cxf-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From cohei...@apache.org
Subject git commit: Support pass-through Kerberos use-case
Date Mon, 08 Sep 2014 14:49:20 GMT
Repository: cxf-fediz
Updated Branches:
  refs/heads/master bb7d7488b -> fd46b5bf3


Support pass-through Kerberos use-case


Project: http://git-wip-us.apache.org/repos/asf/cxf-fediz/repo
Commit: http://git-wip-us.apache.org/repos/asf/cxf-fediz/commit/fd46b5bf
Tree: http://git-wip-us.apache.org/repos/asf/cxf-fediz/tree/fd46b5bf
Diff: http://git-wip-us.apache.org/repos/asf/cxf-fediz/diff/fd46b5bf

Branch: refs/heads/master
Commit: fd46b5bf3711723feaf09434b4463817f7821933
Parents: bb7d748
Author: Colm O hEigeartaigh <coheigea@apache.org>
Authored: Mon Sep 8 15:49:00 2014 +0100
Committer: Colm O hEigeartaigh <coheigea@apache.org>
Committed: Mon Sep 8 15:49:00 2014 +0100

----------------------------------------------------------------------
 .../service/idp/STSAuthenticationProvider.java  | 124 +++++++++++++------
 .../idp/kerberos/PassThroughKerberosClient.java |  71 +++++++++++
 .../src/main/resources/restContextKerberos.xml  |   6 +-
 .../webapp/WEB-INF/security-config-kerberos.xml |   7 +-
 4 files changed, 163 insertions(+), 45 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cxf-fediz/blob/fd46b5bf/services/idp/src/main/java/org/apache/cxf/fediz/service/idp/STSAuthenticationProvider.java
----------------------------------------------------------------------
diff --git a/services/idp/src/main/java/org/apache/cxf/fediz/service/idp/STSAuthenticationProvider.java
b/services/idp/src/main/java/org/apache/cxf/fediz/service/idp/STSAuthenticationProvider.java
index bf96aff..af76d64 100644
--- a/services/idp/src/main/java/org/apache/cxf/fediz/service/idp/STSAuthenticationProvider.java
+++ b/services/idp/src/main/java/org/apache/cxf/fediz/service/idp/STSAuthenticationProvider.java
@@ -39,11 +39,13 @@ import org.apache.cxf.fediz.core.Claim;
 import org.apache.cxf.fediz.core.ClaimTypes;
 import org.apache.cxf.fediz.service.idp.kerberos.KerberosServiceRequestToken;
 import org.apache.cxf.fediz.service.idp.kerberos.KerberosTokenValidator;
+import org.apache.cxf.fediz.service.idp.kerberos.PassThroughKerberosClient;
 //import org.apache.cxf.transport.http.HTTPConduit;
 //import org.apache.cxf.transports.http.configuration.HTTPClientPolicy;
 import org.apache.cxf.ws.security.SecurityConstants;
 import org.apache.cxf.ws.security.tokenstore.SecurityToken;
 import org.apache.wss4j.common.kerberos.KerberosServiceContext;
+import org.apache.wss4j.common.principal.SAMLTokenPrincipalImpl;
 import org.apache.wss4j.common.saml.SamlAssertionWrapper;
 import org.apache.wss4j.dom.WSConstants;
 import org.ietf.jgss.GSSContext;
@@ -105,6 +107,8 @@ public class STSAuthenticationProvider implements AuthenticationProvider
{
     
     private boolean kerberosUsernameServiceNameForm;
     
+    private boolean requireDelegation;
+    
     
     @Override
     public Authentication authenticate(Authentication authentication) throws AuthenticationException
{
@@ -124,47 +128,22 @@ public class STSAuthenticationProvider implements AuthenticationProvider
{
         
         Principal kerberosPrincipal = null;
         if (authentication instanceof KerberosServiceRequestToken) {
-
-            if (kerberosTokenValidator == null) {
-                LOG.error("KerberosTokenValidator must be configured to support kerberos");
-                return null;
-            }
-            KerberosServiceContext kerberosContext;
-            try {
-                kerberosContext = 
-                    kerberosTokenValidator.validate((KerberosServiceRequestToken)authentication);
-                if (kerberosContext != null) {
-                    GSSCredential delegatedCredential = kerberosContext.getDelegationCredential();
-                    if (delegatedCredential != null) {
-                        sts.getProperties().put(SecurityConstants.DELEGATED_CREDENTIAL, 
-                                                delegatedCredential);
-                        sts.getProperties().put(SecurityConstants.KERBEROS_USE_CREDENTIAL_DELEGATION,
"true");
-                    }
-                    kerberosPrincipal = kerberosContext.getPrincipal();
+            // 
+            // If delegation is required then validate the received token + store the
+            // Delegated Credential so that we can retrieve a new kerberos token for the
+            // STS with it. If delegation is not required, then we just get the received
+            // token + pass it to the STS
+            //
+            if (requireDelegation) {
+                kerberosPrincipal = 
+                    validateKerberosToken((KerberosServiceRequestToken)authentication, sts);
+                if (kerberosPrincipal == null) {
+                    return null;
                 }
-            } catch (LoginException ex) {
-                LOG.info("Failed to authenticate user '" + authentication.getName() + "'",
ex);
-                return null;
-            } catch (PrivilegedActionException ex) {
-                LOG.info("Failed to authenticate user '" + authentication.getName() + "'",
ex);
-                return null;
-            }
-            
-            if (kerberosTokenValidator.getContextName() != null) {
-                sts.getProperties().put(SecurityConstants.KERBEROS_JAAS_CONTEXT_NAME, 
-                                    kerberosTokenValidator.getContextName());
-            }
-            if (kerberosTokenValidator.getServiceName() != null) {
-                sts.getProperties().put(SecurityConstants.KERBEROS_SPN,
-                                    kerberosTokenValidator.getServiceName());
-            }
-            if (kerberosCallbackHandler != null) {
-                sts.getProperties().put(SecurityConstants.CALLBACK_HANDLER, 
-                                    kerberosCallbackHandler);
-            }
-            if (kerberosUsernameServiceNameForm) {
-                sts.getProperties().put(SecurityConstants.KERBEROS_IS_USERNAME_IN_SERVICENAME_FORM,

-                                        "true");
+            } else {
+                PassThroughKerberosClient kerberosClient = new PassThroughKerberosClient();
+                kerberosClient.setToken(((KerberosServiceRequestToken)authentication).getToken());
+                sts.getProperties().put(SecurityConstants.KERBEROS_CLIENT, kerberosClient);
             }
         } else {
             sts.getProperties().put(SecurityConstants.USERNAME, authentication.getName());
@@ -192,6 +171,7 @@ public class STSAuthenticationProvider implements AuthenticationProvider
{
             //Not needed because AuthenticatedVoter has been added for SecurityFlowExecutionListener
             if (roleURI != null) {
                 SamlAssertionWrapper assertion = new SamlAssertionWrapper(token.getToken());
+                
                 List<Claim> claims = parseClaimsInAssertion(assertion.getSaml2());
                 for (Claim c : claims) {
                     if (roleURI.equals(c.getClaimType())) {
@@ -215,6 +195,12 @@ public class STSAuthenticationProvider implements AuthenticationProvider
{
             authorities.add(new SimpleGrantedAuthority("ROLE_IDP_LOGIN"));
             
             if (authentication instanceof KerberosServiceRequestToken) {
+                if (kerberosPrincipal == null && token.getToken() != null
+                    && "Assertion".equals(token.getToken().getLocalName())) {
+                    // For the pass-through Kerberos case, we don't know the Principal name...
+                    kerberosPrincipal = 
+                        new SAMLTokenPrincipalImpl(new SamlAssertionWrapper(token.getToken()));
+                }
                 KerberosServiceRequestToken ksrt = 
                     new KerberosServiceRequestToken(kerberosPrincipal, authorities, 
                                                     ((KerberosServiceRequestToken)authentication).getToken());
@@ -248,6 +234,56 @@ public class STSAuthenticationProvider implements AuthenticationProvider
{
         
     }
     
+    private Principal validateKerberosToken(
+        KerberosServiceRequestToken token,
+        IdpSTSClient sts
+    ) {
+        if (kerberosTokenValidator == null) {
+            LOG.error("KerberosTokenValidator must be configured to support kerberos "
+                + "credential delegation");
+            return null;
+        }
+        KerberosServiceContext kerberosContext;
+        Principal kerberosPrincipal = null;
+        try {
+            kerberosContext = kerberosTokenValidator.validate(token);
+            if (kerberosContext == null || kerberosContext.getDelegationCredential() == null)
{
+                LOG.info("Kerberos Validation failure");
+                return null;
+            }
+            GSSCredential delegatedCredential = kerberosContext.getDelegationCredential();
+            sts.getProperties().put(SecurityConstants.DELEGATED_CREDENTIAL, 
+                                    delegatedCredential);
+            sts.getProperties().put(SecurityConstants.KERBEROS_USE_CREDENTIAL_DELEGATION,
"true");
+            kerberosPrincipal = kerberosContext.getPrincipal();
+        } catch (LoginException ex) {
+            LOG.info("Failed to authenticate user", ex);
+            return null;
+        } catch (PrivilegedActionException ex) {
+            LOG.info("Failed to authenticate user", ex);
+            return null;
+        }
+
+        if (kerberosTokenValidator.getContextName() != null) {
+            sts.getProperties().put(SecurityConstants.KERBEROS_JAAS_CONTEXT_NAME, 
+                                    kerberosTokenValidator.getContextName());
+        }
+        if (kerberosTokenValidator.getServiceName() != null) {
+            sts.getProperties().put(SecurityConstants.KERBEROS_SPN,
+                                    kerberosTokenValidator.getServiceName());
+        }
+        if (kerberosCallbackHandler != null) {
+            sts.getProperties().put(SecurityConstants.CALLBACK_HANDLER, 
+                                    kerberosCallbackHandler);
+        }
+        if (kerberosUsernameServiceNameForm) {
+            sts.getProperties().put(SecurityConstants.KERBEROS_IS_USERNAME_IN_SERVICENAME_FORM,

+                                    "true");
+        }
+        
+        return kerberosPrincipal;
+    }
+    
     protected GSSContext createGSSContext() throws GSSException {
         Oid oid = new Oid("1.2.840.113554.1.2.2");
 
@@ -459,6 +495,14 @@ public class STSAuthenticationProvider implements AuthenticationProvider
{
         this.kerberosUsernameServiceNameForm = kerberosUsernameServiceNameForm;
     }
 
+    public boolean isRequireDelegation() {
+        return requireDelegation;
+    }
+
+    public void setRequireDelegation(boolean requireDelegation) {
+        this.requireDelegation = requireDelegation;
+    }
+
 //May be uncommented for debugging    
 //    private void setTimeout(Client client, Long timeout) {
 //        HTTPConduit conduit = (HTTPConduit) client.getConduit();

http://git-wip-us.apache.org/repos/asf/cxf-fediz/blob/fd46b5bf/services/idp/src/main/java/org/apache/cxf/fediz/service/idp/kerberos/PassThroughKerberosClient.java
----------------------------------------------------------------------
diff --git a/services/idp/src/main/java/org/apache/cxf/fediz/service/idp/kerberos/PassThroughKerberosClient.java
b/services/idp/src/main/java/org/apache/cxf/fediz/service/idp/kerberos/PassThroughKerberosClient.java
new file mode 100644
index 0000000..66d995b
--- /dev/null
+++ b/services/idp/src/main/java/org/apache/cxf/fediz/service/idp/kerberos/PassThroughKerberosClient.java
@@ -0,0 +1,71 @@
+/**
+ * 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.fediz.service.idp.kerberos;
+
+import org.apache.cxf.helpers.DOMUtils;
+import org.apache.cxf.ws.security.kerberos.KerberosClient;
+import org.apache.cxf.ws.security.tokenstore.SecurityToken;
+import org.apache.wss4j.dom.WSConstants;
+import org.apache.wss4j.dom.WSSConfig;
+import org.apache.wss4j.dom.message.token.KerberosSecurity;
+import org.apache.wss4j.dom.util.WSSecurityUtil;
+import org.apache.xml.security.utils.Base64;
+
+/**
+ * Override the default CXF KerberosClient just to create a BinarySecurityToken from a 
+ * give Kerberos token. This is used to pass a received Kerberos token through to the 
+ * STS, without retrieving a new token.
+ */
+public class PassThroughKerberosClient extends KerberosClient {
+    
+    private byte[] token;
+
+    public PassThroughKerberosClient() {
+        super();
+    }
+
+    @Override
+    public SecurityToken requestSecurityToken() throws Exception {
+        KerberosSecurity bst = new KerberosSecurity(DOMUtils.createDocument());
+        bst.setValueType(WSConstants.WSS_GSS_KRB_V5_AP_REQ);
+        bst.setToken(token);
+        bst.addWSUNamespace();
+        bst.setID(WSSConfig.getNewInstance().getIdAllocator().createSecureId("BST-", bst));
+        
+        SecurityToken securityToken = new SecurityToken(bst.getID());
+        securityToken.setToken(bst.getElement());
+        securityToken.setWsuId(bst.getID());
+        securityToken.setData(bst.getToken());
+        String sha1 = Base64.encode(WSSecurityUtil.generateDigest(bst.getToken()));
+        securityToken.setSHA1(sha1);
+        securityToken.setTokenType(bst.getValueType());
+
+        return securityToken;
+    }
+
+    public byte[] getToken() {
+        return token;
+    }
+
+    public void setToken(byte[] token) {
+        this.token = token;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cxf-fediz/blob/fd46b5bf/services/idp/src/main/resources/restContextKerberos.xml
----------------------------------------------------------------------
diff --git a/services/idp/src/main/resources/restContextKerberos.xml b/services/idp/src/main/resources/restContextKerberos.xml
index 95e7907..4fa2060 100644
--- a/services/idp/src/main/resources/restContextKerberos.xml
+++ b/services/idp/src/main/resources/restContextKerberos.xml
@@ -146,11 +146,12 @@
     <bean id="entitlementsEnricher" class="org.apache.cxf.fediz.service.idp.service.security.GrantedAuthorityEntitlements"
/>
 
     <bean id="stsPortFilter" class="org.apache.cxf.fediz.service.idp.STSPortFilter" />
-    
+    <!--
     <bean id="kerberosTokenValidator" class="org.apache.cxf.fediz.service.idp.kerberos.KerberosTokenValidator">
         <property name="contextName" value="bob"/>
         <property name="serviceName" value="bob@service.ws.apache.org"/>
     </bean>
+    -->
     
     <bean id="stsAuthProvider" class="org.apache.cxf.fediz.service.idp.STSAuthenticationProvider">
         <!--<property name="wsdlLocation" value="https://localhost:0/fediz-idp-sts/${realm.STS_URI}/STSServiceTransportUT?wsdl"/>
@@ -160,7 +161,8 @@
         <property name="wsdlService" value="SecurityTokenService"/>
         <property name="appliesTo" value="urn:fediz:idp"/>
         <property name="tokenType" value="http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV2.0"/>
-        <property name="kerberosTokenValidator" ref="kerberosTokenValidator"/>
+        <!--<property name="kerberosTokenValidator" ref="kerberosTokenValidator"/>
+        <property name="requireDelegation" value="true"/>-->
     </bean>
     
 </beans>

http://git-wip-us.apache.org/repos/asf/cxf-fediz/blob/fd46b5bf/services/idp/src/main/webapp/WEB-INF/security-config-kerberos.xml
----------------------------------------------------------------------
diff --git a/services/idp/src/main/webapp/WEB-INF/security-config-kerberos.xml b/services/idp/src/main/webapp/WEB-INF/security-config-kerberos.xml
index 32242c1..0d17349 100644
--- a/services/idp/src/main/webapp/WEB-INF/security-config-kerberos.xml
+++ b/services/idp/src/main/webapp/WEB-INF/security-config-kerberos.xml
@@ -61,10 +61,10 @@
 	
     <bean id="stsPortFilter" class="org.apache.cxf.fediz.service.idp.STSPortFilter" />
     
-    <bean id="kerberosTokenValidator" class="org.apache.cxf.fediz.service.idp.kerberos.KerberosTokenValidator">
+    <!--<bean id="kerberosTokenValidator" class="org.apache.cxf.fediz.service.idp.kerberos.KerberosTokenValidator">
         <property name="contextName" value="bob"/>
         <property name="serviceName" value="bob@service.ws.apache.org"/>
-    </bean>
+    </bean>-->
 	
     <bean id="stsAuthProvider" class="org.apache.cxf.fediz.service.idp.STSAuthenticationProvider">
         <!--<property name="wsdlLocation" value="https://localhost:0/fediz-idp-sts/${realm.STS_URI}/STSServiceTransportUT?wsdl"/>
@@ -74,7 +74,8 @@
         <property name="wsdlService" value="SecurityTokenService"/>
         <property name="appliesTo" value="urn:fediz:idp"/>
         <property name="tokenType" value="http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV2.0"/>
-        <property name="kerberosTokenValidator" ref="kerberosTokenValidator"/>
+        <!--<property name="kerberosTokenValidator" ref="kerberosTokenValidator"/>
+        <property name="requireDelegation" value="true"/>-->
     </bean>
 
 </beans>


Mime
View raw message