You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cxf.apache.org by se...@apache.org on 2012/07/18 14:28:44 UTC

svn commit: r1362908 - in /cxf/trunk: api/src/main/java/org/apache/cxf/common/security/ rt/core/src/main/java/org/apache/cxf/interceptor/security/ rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/security/ rt/transports/http/src/main/java/org/apach...

Author: sergeyb
Date: Wed Jul 18 12:28:44 2012
New Revision: 1362908

URL: http://svn.apache.org/viewvc?rev=1362908&view=rev
Log:
[CXF-4430] Updating SpnegoAuthSupplier to use GSSCredential if it is available on the message, filter - to make it available in the CXF context if the cred delegation is enabled, dropping a mutualAuth property for now - we do not provide any support for getting the response token from the server

Modified:
    cxf/trunk/api/src/main/java/org/apache/cxf/common/security/SimpleSecurityContext.java
    cxf/trunk/rt/core/src/main/java/org/apache/cxf/interceptor/security/JAASLoginInterceptor.java
    cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/security/KerberosAuthenticationFilter.java
    cxf/trunk/rt/transports/http/src/main/java/org/apache/cxf/transport/http/auth/AbstractSpnegoAuthSupplier.java
    cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/security/JAXRSKerberosBookTest.java

Modified: cxf/trunk/api/src/main/java/org/apache/cxf/common/security/SimpleSecurityContext.java
URL: http://svn.apache.org/viewvc/cxf/trunk/api/src/main/java/org/apache/cxf/common/security/SimpleSecurityContext.java?rev=1362908&r1=1362907&r2=1362908&view=diff
==============================================================================
--- cxf/trunk/api/src/main/java/org/apache/cxf/common/security/SimpleSecurityContext.java (original)
+++ cxf/trunk/api/src/main/java/org/apache/cxf/common/security/SimpleSecurityContext.java Wed Jul 18 12:28:44 2012
@@ -25,7 +25,10 @@ import org.apache.cxf.security.SecurityC
 public class SimpleSecurityContext implements SecurityContext {
     private SimplePrincipal principal;
     public SimpleSecurityContext(String name) {
-        this.principal = new SimplePrincipal(name);
+        this(new SimplePrincipal(name));
+    }
+    public SimpleSecurityContext(SimplePrincipal principal) {
+        this.principal = principal;
     }
     
     public Principal getUserPrincipal() {

Modified: cxf/trunk/rt/core/src/main/java/org/apache/cxf/interceptor/security/JAASLoginInterceptor.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/core/src/main/java/org/apache/cxf/interceptor/security/JAASLoginInterceptor.java?rev=1362908&r1=1362907&r2=1362908&view=diff
==============================================================================
--- cxf/trunk/rt/core/src/main/java/org/apache/cxf/interceptor/security/JAASLoginInterceptor.java (original)
+++ cxf/trunk/rt/core/src/main/java/org/apache/cxf/interceptor/security/JAASLoginInterceptor.java Wed Jul 18 12:28:44 2012
@@ -54,6 +54,10 @@ public class JAASLoginInterceptor extend
         super(Phase.UNMARSHAL);
     }
     
+    public JAASLoginInterceptor(String phase) {
+        super(phase);
+    }
+    
     public void setContextName(String name) {
         contextName = name;
     }

Modified: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/security/KerberosAuthenticationFilter.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/security/KerberosAuthenticationFilter.java?rev=1362908&r1=1362907&r2=1362908&view=diff
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/security/KerberosAuthenticationFilter.java (original)
+++ cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/security/KerberosAuthenticationFilter.java Wed Jul 18 12:28:44 2012
@@ -21,6 +21,7 @@ package org.apache.cxf.jaxrs.security;
 import java.security.PrivilegedActionException;
 import java.security.PrivilegedExceptionAction;
 import java.util.List;
+import java.util.logging.Logger;
 
 import javax.security.auth.Subject;
 import javax.security.auth.callback.CallbackHandler;
@@ -31,6 +32,8 @@ import javax.ws.rs.core.Context;
 import javax.ws.rs.core.HttpHeaders;
 import javax.ws.rs.core.Response;
 
+import org.apache.cxf.common.logging.LogUtils;
+import org.apache.cxf.common.security.SimplePrincipal;
 import org.apache.cxf.common.security.SimpleSecurityContext;
 import org.apache.cxf.common.util.Base64Exception;
 import org.apache.cxf.common.util.Base64Utility;
@@ -48,6 +51,8 @@ import org.ietf.jgss.Oid;
 
 public class KerberosAuthenticationFilter implements RequestHandler {
 
+    private static final Logger LOG = LogUtils.getL7dLogger(KerberosAuthenticationFilter.class);
+    
     private static final String NEGOTIATE_SCHEME = "Negotiate";
     private static final String PROPERTY_USE_KERBEROS_OID = "auth.spnego.useKerberosOid";
     private static final String KERBEROS_OID = "1.2.840.113554.1.2.2";
@@ -58,17 +63,18 @@ public class KerberosAuthenticationFilte
     private String loginContextName;
     private String servicePrincipalName;
     private String realm;
-    private boolean keepUserPrincipalRealm = true;
     
     public Response handleRequest(Message m, ClassResourceInfo resourceClass) {
         
         List<String> authHeaders = messageContext.getHttpHeaders()
             .getRequestHeader(HttpHeaders.AUTHORIZATION);
         if (authHeaders.size() != 1) {
+            LOG.fine("No Authorization header is available");
             throw new WebApplicationException(getFaultResponse());
         }
         String[] authPair = authHeaders.get(0).split(" ");
         if (authPair.length != 2 || !NEGOTIATE_SCHEME.equalsIgnoreCase(authPair[0])) {
+            LOG.fine("Negotiate Authorization scheme is expected");
             throw new WebApplicationException(getFaultResponse());
         }
                 
@@ -86,22 +92,31 @@ public class KerberosAuthenticationFilte
                 throw new WebApplicationException(getFaultResponse());
             }
             
-            String userName = srcName.toString();
-            if (!keepUserPrincipalRealm) {
-                int index = userName.lastIndexOf('@');
-                if (index > 0) {
-                    userName = userName.substring(0, index);
-                    //TODO: still provide a complete user name via KerberosPrincipal
-                }
-            }
-            m.put(SecurityContext.class, new SimpleSecurityContext(userName));
+            String complexUserName = srcName.toString();
             
+            String simpleUserName = complexUserName;
+            int index = simpleUserName.lastIndexOf('@');
+            if (index > 0) {
+                simpleUserName = simpleUserName.substring(0, index);
+            }
+            if (!gssContext.getCredDelegState()) {
+                gssContext.dispose();
+                gssContext = null;
+            }
+
+            m.put(SecurityContext.class, 
+                new KerberosSecurityContext(new KerberosPrincipal(simpleUserName,
+                                                                  complexUserName),
+                                            gssContext));
             
         } catch (LoginException e) {
+            LOG.fine("Unsuccessful JAAS login for the service principal");
             throw new WebApplicationException(getFaultResponse());
         } catch (GSSException e) {
+            LOG.fine("GSS API exception: " + e.getMessage());
             throw new WebApplicationException(getFaultResponse());
         } catch (PrivilegedActionException e) {
+            LOG.fine("PrivilegedActionException: " + e.getMessage());
             throw new WebApplicationException(getFaultResponse());
         }
         
@@ -181,11 +196,6 @@ public class KerberosAuthenticationFilte
         this.callbackHandler = callbackHandler;
     }
 
-    
-    public void setKeepUserPrincipalRealm(boolean keep) {
-        this.keepUserPrincipalRealm = keep;
-    }
-
     private final class ValidateServiceTicketAction implements PrivilegedExceptionAction<byte[]> {
         private final GSSContext context;
         private final byte[] token;
@@ -199,4 +209,29 @@ public class KerberosAuthenticationFilte
             return context.acceptSecContext(token, 0, token.length);
         }
     }
+    
+    public static class KerberosPrincipal extends SimplePrincipal {
+        private String complexName;
+        public KerberosPrincipal(String simpleName, String complexName) {
+            super(simpleName);
+            this.complexName = complexName;
+        }
+        
+        public String getKerberosName() {
+            return complexName;
+        }
+    }
+    
+    public static class KerberosSecurityContext extends SimpleSecurityContext {
+        private GSSContext context;
+        public KerberosSecurityContext(KerberosPrincipal principal,
+                                       GSSContext context) {
+            super(principal);
+            this.context = context;
+        }
+        
+        public GSSContext getGSSContext() {
+            return context;
+        }
+    }
 }

Modified: cxf/trunk/rt/transports/http/src/main/java/org/apache/cxf/transport/http/auth/AbstractSpnegoAuthSupplier.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/transports/http/src/main/java/org/apache/cxf/transport/http/auth/AbstractSpnegoAuthSupplier.java?rev=1362908&r1=1362907&r2=1362908&view=diff
==============================================================================
--- cxf/trunk/rt/transports/http/src/main/java/org/apache/cxf/transport/http/auth/AbstractSpnegoAuthSupplier.java (original)
+++ cxf/trunk/rt/transports/http/src/main/java/org/apache/cxf/transport/http/auth/AbstractSpnegoAuthSupplier.java Wed Jul 18 12:28:44 2012
@@ -34,10 +34,12 @@ import javax.security.auth.login.LoginEx
 
 import org.apache.cxf.common.logging.LogUtils;
 import org.apache.cxf.common.util.Base64Utility;
+import org.apache.cxf.common.util.StringUtils;
 import org.apache.cxf.configuration.security.AuthorizationPolicy;
 import org.apache.cxf.message.Message;
 import org.apache.cxf.message.MessageUtils;
 import org.ietf.jgss.GSSContext;
+import org.ietf.jgss.GSSCredential;
 import org.ietf.jgss.GSSException;
 import org.ietf.jgss.GSSManager;
 import org.ietf.jgss.GSSName;
@@ -51,7 +53,6 @@ public abstract class AbstractSpnegoAuth
      * instead of the default spnego OID
      */
     private static final String PROPERTY_USE_KERBEROS_OID = "auth.spnego.useKerberosOid";
-    private static final String PROPERTY_REQUIRE_MUTUAL_AUTH = "auth.spnego.requireMutualAuth";
     private static final String PROPERTY_REQUIRE_CRED_DELEGATION = "auth.spnego.requireCredDelegation";
     
     private static final String KERBEROS_OID = "1.2.840.113554.1.2.2";
@@ -59,10 +60,8 @@ public abstract class AbstractSpnegoAuth
 
     private String servicePrincipalName;
     private String realm;
-    private boolean mutualAuth;
     private boolean credDelegation;
     
-    
     public String getAuthorization(AuthorizationPolicy authPolicy,
                                    URL currentURL,
                                    Message message) {
@@ -99,7 +98,7 @@ public abstract class AbstractSpnegoAuth
         LoginException {
         final byte[] token = new byte[0];
 
-        if (authPolicy.getUserName() == null || authPolicy.getUserName().trim().length() == 0) {
+        if (authPolicy == null || StringUtils.isEmpty(authPolicy.getUserName())) {
             return context.initSecContext(token, 0, token.length);
         }
 
@@ -136,17 +135,18 @@ public abstract class AbstractSpnegoAuth
         GSSManager manager = GSSManager.getInstance();
         GSSName serverName = manager.createName(spn, null);
 
+        GSSCredential delegatedCred = (GSSCredential)message.get(GSSCredential.class.getName());
+        
         GSSContext context = manager
-                .createContext(serverName.canonicalize(oid), oid, null, GSSContext.DEFAULT_LIFETIME);
-        context.requestMutualAuth(isMutualAuthRequired(message));
+                .createContext(serverName.canonicalize(oid), oid, delegatedCred, GSSContext.DEFAULT_LIFETIME);
+        
         context.requestCredDeleg(isCredDelegationRequired(message));
 
-        return getToken(authPolicy, context);
-    }
-    
-    protected boolean isMutualAuthRequired(Message message) { 
-        Object prop = message.getContextualProperty(PROPERTY_REQUIRE_MUTUAL_AUTH);
-        return prop == null ? mutualAuth : MessageUtils.isTrue(prop);
+        // If the delegated cred is not null then we only need the context to
+        // immediately return a ticket based on this credential without attempting
+        // to log on again 
+        return getToken(delegatedCred == null ? authPolicy : null, 
+                        context);
     }
     
     protected boolean isCredDelegationRequired(Message message) { 
@@ -205,4 +205,8 @@ public abstract class AbstractSpnegoAuth
         return handler;
     }
 
+    public void setCredDelegation(boolean delegation) {
+        this.credDelegation = delegation;
+    }
+
 }

Modified: cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/security/JAXRSKerberosBookTest.java
URL: http://svn.apache.org/viewvc/cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/security/JAXRSKerberosBookTest.java?rev=1362908&r1=1362907&r2=1362908&view=diff
==============================================================================
--- cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/security/JAXRSKerberosBookTest.java (original)
+++ cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/security/JAXRSKerberosBookTest.java Wed Jul 18 12:28:44 2012
@@ -82,6 +82,7 @@ public class JAXRSKerberosBookTest exten
         policy.setPassword("alice");
         
         kbInterceptor.setPolicy(policy);
+        kbInterceptor.setCredDelegation(true);
         
         WebClient.getConfig(wc).getOutInterceptors().add(new LoggingOutInterceptor());
         WebClient.getConfig(wc).getOutInterceptors().add(kbInterceptor);