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)");
             }
         }
     }