Return-Path: X-Original-To: apmail-cxf-commits-archive@www.apache.org Delivered-To: apmail-cxf-commits-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 4BD41112D3 for ; Sat, 12 Jul 2014 08:35:12 +0000 (UTC) Received: (qmail 34232 invoked by uid 500); 12 Jul 2014 08:35:12 -0000 Delivered-To: apmail-cxf-commits-archive@cxf.apache.org Received: (qmail 34168 invoked by uid 500); 12 Jul 2014 08:35:12 -0000 Mailing-List: contact commits-help@cxf.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@cxf.apache.org Delivered-To: mailing list commits@cxf.apache.org Received: (qmail 34159 invoked by uid 99); 12 Jul 2014 08:35:12 -0000 Received: from tyr.zones.apache.org (HELO tyr.zones.apache.org) (140.211.11.114) by apache.org (qpsmtpd/0.29) with ESMTP; Sat, 12 Jul 2014 08:35:12 +0000 Received: by tyr.zones.apache.org (Postfix, from userid 65534) id D0A818B79E9; Sat, 12 Jul 2014 08:35:11 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: cschneider@apache.org To: commits@cxf.apache.org Message-Id: <45afadaacccb47238d378768e87058c4@git.apache.org> X-Mailer: ASF-Git Admin Mailer Subject: git commit: CXF-5868 Add subject.doAs Date: Sat, 12 Jul 2014 08:35:11 +0000 (UTC) Repository: cxf Updated Branches: refs/heads/2.7.x-fixes 76efa97cc -> ca5058af1 CXF-5868 Add subject.doAs Project: http://git-wip-us.apache.org/repos/asf/cxf/repo Commit: http://git-wip-us.apache.org/repos/asf/cxf/commit/ca5058af Tree: http://git-wip-us.apache.org/repos/asf/cxf/tree/ca5058af Diff: http://git-wip-us.apache.org/repos/asf/cxf/diff/ca5058af Branch: refs/heads/2.7.x-fixes Commit: ca5058af10c2cb3f35dbb47dce87d0509706da78 Parents: 76efa97 Author: Christian Schneider Authored: Sat Jul 12 10:34:29 2014 +0200 Committer: Christian Schneider Committed: Sat Jul 12 10:34:29 2014 +0200 ---------------------------------------------------------------------- .../security/JAASAuthenticationFeature.java | 58 ++++++++++++++++ .../security/JAASLoginInterceptor.java | 70 +++++++++----------- .../security/JAASAuthenticationFilter.java | 15 +++-- 3 files changed, 100 insertions(+), 43 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cxf/blob/ca5058af/rt/core/src/main/java/org/apache/cxf/interceptor/security/JAASAuthenticationFeature.java ---------------------------------------------------------------------- diff --git a/rt/core/src/main/java/org/apache/cxf/interceptor/security/JAASAuthenticationFeature.java b/rt/core/src/main/java/org/apache/cxf/interceptor/security/JAASAuthenticationFeature.java new file mode 100644 index 0000000..2a2d985 --- /dev/null +++ b/rt/core/src/main/java/org/apache/cxf/interceptor/security/JAASAuthenticationFeature.java @@ -0,0 +1,58 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.cxf.interceptor.security; + +import org.apache.cxf.Bus; +import org.apache.cxf.feature.AbstractFeature; +import org.apache.cxf.interceptor.InterceptorProvider; + +/** + * Feature to do JAAS authentication with defaults for karaf integration + */ +public class JAASAuthenticationFeature extends AbstractFeature { + public static final String ID = "jaas"; + + private String contextName = "karaf"; + private boolean reportFault; + + @Override + public String getID() { + return ID; + } + + @Override + protected void initializeProvider(InterceptorProvider provider, Bus bus) { + JAASLoginInterceptor jaasLoginInterceptor = new JAASLoginInterceptor(); + jaasLoginInterceptor.setRoleClassifierType(JAASLoginInterceptor.ROLE_CLASSIFIER_CLASS_NAME); + jaasLoginInterceptor.setRoleClassifier("org.apache.karaf.jaas.boot.principal.RolePrincipal"); + jaasLoginInterceptor.setContextName(contextName); + jaasLoginInterceptor.setReportFault(reportFault); + provider.getInInterceptors().add(jaasLoginInterceptor); + super.initializeProvider(provider, bus); + } + + public void setContextName(String contextName) { + this.contextName = contextName; + } + + public void setReportFault(boolean reportFault) { + this.reportFault = reportFault; + } + +} http://git-wip-us.apache.org/repos/asf/cxf/blob/ca5058af/rt/core/src/main/java/org/apache/cxf/interceptor/security/JAASLoginInterceptor.java ---------------------------------------------------------------------- diff --git a/rt/core/src/main/java/org/apache/cxf/interceptor/security/JAASLoginInterceptor.java b/rt/core/src/main/java/org/apache/cxf/interceptor/security/JAASLoginInterceptor.java index 07b10d5..24c7bf2 100644 --- a/rt/core/src/main/java/org/apache/cxf/interceptor/security/JAASLoginInterceptor.java +++ b/rt/core/src/main/java/org/apache/cxf/interceptor/security/JAASLoginInterceptor.java @@ -18,7 +18,7 @@ */ package org.apache.cxf.interceptor.security; -import java.util.ResourceBundle; +import java.security.PrivilegedAction; import java.util.logging.Logger; import javax.security.auth.Subject; @@ -27,24 +27,22 @@ import javax.security.auth.login.Configuration; import javax.security.auth.login.LoginContext; import javax.security.auth.login.LoginException; -import org.apache.cxf.common.i18n.BundleUtils; import org.apache.cxf.common.logging.LogUtils; import org.apache.cxf.common.security.SecurityToken; import org.apache.cxf.common.security.TokenType; import org.apache.cxf.common.security.UsernameToken; import org.apache.cxf.configuration.security.AuthorizationPolicy; import org.apache.cxf.interceptor.Fault; +import org.apache.cxf.interceptor.InterceptorChain; import org.apache.cxf.message.Message; import org.apache.cxf.phase.AbstractPhaseInterceptor; import org.apache.cxf.phase.Phase; -import org.apache.cxf.phase.PhaseInterceptorChain; import org.apache.cxf.security.SecurityContext; public class JAASLoginInterceptor extends AbstractPhaseInterceptor { public static final String ROLE_CLASSIFIER_PREFIX = "prefix"; public static final String ROLE_CLASSIFIER_CLASS_NAME = "classname"; - - private static final ResourceBundle BUNDLE = BundleUtils.getBundle(JAASLoginInterceptor.class); + private static final Logger LOG = LogUtils.getL7dLogger(JAASLoginInterceptor.class); private String contextName = ""; @@ -52,6 +50,7 @@ public class JAASLoginInterceptor extends AbstractPhaseInterceptor { private String roleClassifier; private String roleClassifierType = ROLE_CLASSIFIER_PREFIX; private boolean reportFault; + private boolean useDoAs = true; public JAASLoginInterceptor() { @@ -99,7 +98,11 @@ public class JAASLoginInterceptor extends AbstractPhaseInterceptor { this.reportFault = reportFault; } - public void handleMessage(Message message) throws Fault { + public void setUseDoAs(boolean useDoAs) { + this.useDoAs = useDoAs; + } + + public void handleMessage(final Message message) throws Fault { String name = null; String password = null; @@ -117,38 +120,43 @@ public class JAASLoginInterceptor extends AbstractPhaseInterceptor { password = ut.getPassword(); } } - + if (name == null || password == null) { - org.apache.cxf.common.i18n.Message errorMsg = - new org.apache.cxf.common.i18n.Message("NO_USER_PASSWORD", - BUNDLE, - name, password); - LOG.warning(errorMsg.toString()); - if (reportFault) { - throw new SecurityException(errorMsg.toString()); - } else { - throw new SecurityException(); - } + throw new AuthenticationException("Authentication required but no user or password was supplied"); } - + try { - - CallbackHandler handler = getCallbackHandler(name, password); LoginContext ctx = new LoginContext(getContextName(), null, handler, loginConfig); ctx.login(); Subject subject = ctx.getSubject(); + message.put(SecurityContext.class, createSecurityContext(name, subject)); - message.put(SecurityContext.class, createSecurityContext(subject)); + // Run the further chain in the context of this subject. + // This allows other code to retrieve the subject using pure JAAS + if (useDoAs) { + Subject.doAs(subject, new PrivilegedAction() { + + @Override + public Void run() { + InterceptorChain chain = message.getInterceptorChain(); + if (chain != null) { + chain.doIntercept(message); + } + return null; + } + }); + } + } catch (LoginException ex) { - String errorMessage = "Unauthorized : " + ex.getMessage(); + String errorMessage = "Authentication failed for user " + name + " : " + ex.getMessage(); LOG.fine(errorMessage); if (reportFault) { throw new AuthenticationException(errorMessage); } else { - throw new AuthenticationException(); + throw new AuthenticationException("Authentication failed (details can be found in server log)"); } } } @@ -157,25 +165,11 @@ public class JAASLoginInterceptor extends AbstractPhaseInterceptor { return new NamePasswordCallbackHandler(name, password); } - protected SecurityContext createSecurityContext(Subject subject) { + protected SecurityContext createSecurityContext(String name, Subject subject) { if (getRoleClassifier() != null) { return new RolePrefixSecurityContextImpl(subject, getRoleClassifier(), getRoleClassifierType()); } else { - // Get username - this is a bit unwieldy but necessary to preserve the message signature - Message message = PhaseInterceptorChain.getCurrentMessage(); - AuthorizationPolicy policy = message.get(AuthorizationPolicy.class); - String name = null; - if (policy != null) { - name = policy.getUserName(); - } else { - // try the UsernameToken - SecurityToken token = message.get(SecurityToken.class); - if (token != null && token.getTokenType() == TokenType.UsernameToken) { - UsernameToken ut = (UsernameToken)token; - name = ut.getName(); - } - } return new DefaultSecurityContext(name, subject); } } http://git-wip-us.apache.org/repos/asf/cxf/blob/ca5058af/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/security/JAASAuthenticationFilter.java ---------------------------------------------------------------------- diff --git a/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/security/JAASAuthenticationFilter.java b/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/security/JAASAuthenticationFilter.java index 9ff4aa6..aadb27a 100644 --- a/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/security/JAASAuthenticationFilter.java +++ b/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/security/JAASAuthenticationFilter.java @@ -51,11 +51,16 @@ public class JAASAuthenticationFilter implements RequestHandler { private String realmName; private boolean ignoreBasePath = true; - private JAASLoginInterceptor interceptor = new JAASLoginInterceptor() { - protected CallbackHandler getCallbackHandler(String name, String password) { - return JAASAuthenticationFilter.this.getCallbackHandler(name, password); - } - }; + private JAASLoginInterceptor interceptor; + + public JAASAuthenticationFilter() { + interceptor = new JAASLoginInterceptor() { + protected CallbackHandler getCallbackHandler(String name, String password) { + return JAASAuthenticationFilter.this.getCallbackHandler(name, password); + } + }; + interceptor.setUseDoAs(false); + } public void setIgnoreBasePath(boolean ignore) { this.ignoreBasePath = ignore;