You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cxf.apache.org by cs...@apache.org on 2014/07/10 15:15:48 UTC
git commit: CXF-5868 Add subject.doAs and HTTP status mapping
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 <ch...@die-schneider.net>
Authored: Thu Jul 10 15:10:05 2014 +0200
Committer: Christian Schneider <ch...@die-schneider.net>
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)");
}
}
}