Repository: cxf Updated Branches: refs/heads/master 22dbf10ed -> 5182ed51f
CXF-5868 Add subject.doAs and HTTP status mapping Project: http://git-wip-us.apache.org/repos/asf/cxf/repo Commit: http://git-wip-us.apache.org/repos/asf/cxf/commit/5182ed51 Tree: http://git-wip-us.apache.org/repos/asf/cxf/tree/5182ed51 Diff: http://git-wip-us.apache.org/repos/asf/cxf/diff/5182ed51 Branch: refs/heads/master Commit: 5182ed51fcc455b52707e3179049fd724418abaf Parents: 22dbf10 Author: Christian Schneider <[email protected]> Authored: Thu Jul 10 15:10:05 2014 +0200 Committer: Christian Schneider <[email protected]> Committed: Thu Jul 10 15:10:05 2014 +0200 ---------------------------------------------------------------------- .../java/org/apache/cxf/interceptor/Fault.java | 23 +++++++- .../security/JAASAuthenticationFeature.java | 58 ++++++++++++++++++++ .../security/JAASLoginInterceptor.java | 40 +++++++------- 3 files changed, 98 insertions(+), 23 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cxf/blob/5182ed51/core/src/main/java/org/apache/cxf/interceptor/Fault.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/cxf/interceptor/Fault.java b/core/src/main/java/org/apache/cxf/interceptor/Fault.java index 55c7fb9..3e44adf 100644 --- a/core/src/main/java/org/apache/cxf/interceptor/Fault.java +++ b/core/src/main/java/org/apache/cxf/interceptor/Fault.java @@ -19,9 +19,11 @@ package org.apache.cxf.interceptor; +import java.net.HttpURLConnection; import java.util.ResourceBundle; import java.util.logging.Logger; +import javax.security.auth.login.LoginException; import javax.xml.namespace.QName; import org.w3c.dom.Element; @@ -29,6 +31,8 @@ import org.w3c.dom.Element; import org.apache.cxf.common.i18n.Message; import org.apache.cxf.common.i18n.UncheckedException; import org.apache.cxf.helpers.DOMUtils; +import org.apache.cxf.interceptor.security.AccessDeniedException; +import org.apache.cxf.interceptor.security.AuthenticationException; /** * A Fault that occurs during invocation processing. @@ -38,9 +42,9 @@ public class Fault extends UncheckedException { public static final QName FAULT_CODE_SERVER = new QName("http://cxf.apache.org/faultcode", "server"); public static final String STACKTRACE_NAMESPACE = "http://cxf.apache.org/fault"; public static final String STACKTRACE = "stackTrace"; - private static final int DEFAULT_HTTP_RESPONSE_CODE = 500; + private static final int DEFAULT_HTTP_RESPONSE_CODE = HttpURLConnection.HTTP_INTERNAL_ERROR; private static final long serialVersionUID = -1583932965031558864L; - + private Element detail; private String messageString; private QName code; @@ -54,6 +58,7 @@ public class Fault extends UncheckedException { super(message, throwable); this.messageString = message.toString(); code = FAULT_CODE_SERVER; + determineStatusCode(throwable); } public Fault(Message message) { @@ -89,12 +94,14 @@ public class Fault extends UncheckedException { messageString = t == null ? null : t.getMessage(); } code = FAULT_CODE_SERVER; + determineStatusCode(t); } public Fault(Message message, Throwable throwable, QName fc) { super(message, throwable); this.messageString = message.toString(); code = fc; + determineStatusCode(throwable); } public Fault(Message message, QName fc) { @@ -111,7 +118,17 @@ public class Fault extends UncheckedException { messageString = t == null ? null : t.getMessage(); } code = fc; - } + determineStatusCode(t); + } + + private void determineStatusCode(Throwable throwable) { + if (throwable instanceof AuthenticationException || throwable instanceof LoginException) { + statusCode = HttpURLConnection.HTTP_UNAUTHORIZED; + } + if (throwable instanceof AccessDeniedException) { + statusCode = HttpURLConnection.HTTP_FORBIDDEN; + } + } public String getMessage() { return messageString; http://git-wip-us.apache.org/repos/asf/cxf/blob/5182ed51/core/src/main/java/org/apache/cxf/interceptor/security/JAASAuthenticationFeature.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/cxf/interceptor/security/JAASAuthenticationFeature.java b/core/src/main/java/org/apache/cxf/interceptor/security/JAASAuthenticationFeature.java new file mode 100644 index 0000000..2a2d985 --- /dev/null +++ b/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/5182ed51/core/src/main/java/org/apache/cxf/interceptor/security/JAASLoginInterceptor.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/cxf/interceptor/security/JAASLoginInterceptor.java b/core/src/main/java/org/apache/cxf/interceptor/security/JAASLoginInterceptor.java index 928bc38..4600812 100644 --- a/core/src/main/java/org/apache/cxf/interceptor/security/JAASLoginInterceptor.java +++ b/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,7 +27,6 @@ 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; @@ -42,8 +41,7 @@ import org.apache.cxf.security.SecurityContext; public class JAASLoginInterceptor extends AbstractPhaseInterceptor<Message> { 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 = ""; @@ -98,7 +96,7 @@ public class JAASLoginInterceptor extends AbstractPhaseInterceptor<Message> { this.reportFault = reportFault; } - public void handleMessage(Message message) throws Fault { + public void handleMessage(final Message message) throws Fault { String name = null; String password = null; @@ -116,20 +114,11 @@ public class JAASLoginInterceptor extends AbstractPhaseInterceptor<Message> { 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); @@ -137,15 +126,26 @@ public class JAASLoginInterceptor extends AbstractPhaseInterceptor<Message> { ctx.login(); Subject subject = ctx.getSubject(); + message.put(SecurityContext.class, createSecurityContext(name, subject)); - message.put(SecurityContext.class, createSecurityContext(name, subject)); + // Run the further chain in the context of this subject. + // This allows other code to retrieve the subject using pure JAAS + Subject.doAs(subject, new PrivilegedAction<Void>() { + + @Override + public Void run() { + message.getInterceptorChain().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)"); } } }
