You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cxf.apache.org by ow...@apache.org on 2012/01/11 20:17:44 UTC

svn commit: r1230197 - in /cxf/branches/2.5.x-fixes/services/sts/sts-core/src: main/java/org/apache/cxf/sts/claims/ main/java/org/apache/cxf/sts/operation/ test/java/org/apache/cxf/sts/operation/

Author: owulff
Date: Wed Jan 11 19:17:43 2012
New Revision: 1230197

URL: http://svn.apache.org/viewvc?rev=1230197&view=rev
Log:
[CXF-4021] Claims element support in RST for validate binding

Modified:
    cxf/branches/2.5.x-fixes/services/sts/sts-core/src/main/java/org/apache/cxf/sts/claims/ClaimsAttributeStatementProvider.java
    cxf/branches/2.5.x-fixes/services/sts/sts-core/src/main/java/org/apache/cxf/sts/claims/ClaimsManager.java
    cxf/branches/2.5.x-fixes/services/sts/sts-core/src/main/java/org/apache/cxf/sts/operation/AbstractOperation.java
    cxf/branches/2.5.x-fixes/services/sts/sts-core/src/main/java/org/apache/cxf/sts/operation/TokenIssueOperation.java
    cxf/branches/2.5.x-fixes/services/sts/sts-core/src/main/java/org/apache/cxf/sts/operation/TokenValidateOperation.java
    cxf/branches/2.5.x-fixes/services/sts/sts-core/src/test/java/org/apache/cxf/sts/operation/ValidateTokenTransformationUnitTest.java

Modified: cxf/branches/2.5.x-fixes/services/sts/sts-core/src/main/java/org/apache/cxf/sts/claims/ClaimsAttributeStatementProvider.java
URL: http://svn.apache.org/viewvc/cxf/branches/2.5.x-fixes/services/sts/sts-core/src/main/java/org/apache/cxf/sts/claims/ClaimsAttributeStatementProvider.java?rev=1230197&r1=1230196&r2=1230197&view=diff
==============================================================================
--- cxf/branches/2.5.x-fixes/services/sts/sts-core/src/main/java/org/apache/cxf/sts/claims/ClaimsAttributeStatementProvider.java (original)
+++ cxf/branches/2.5.x-fixes/services/sts/sts-core/src/main/java/org/apache/cxf/sts/claims/ClaimsAttributeStatementProvider.java Wed Jan 11 19:17:43 2012
@@ -46,14 +46,17 @@ public class ClaimsAttributeStatementPro
                     providerParameters.getRealm()
                 );
         }
-                
-        List<AttributeBean> attributeList = new ArrayList<AttributeBean>();
-        String tokenType = providerParameters.getTokenRequirements().getTokenType();
+        if (retrievedClaims == null) {
+            return null;
+        }
         
         Iterator<Claim> claimIterator = retrievedClaims.iterator();
         if (!claimIterator.hasNext()) {
             return null;
         }
+                
+        List<AttributeBean> attributeList = new ArrayList<AttributeBean>();
+        String tokenType = providerParameters.getTokenRequirements().getTokenType();
         
         AttributeStatementBean attrBean = new AttributeStatementBean();
         while (claimIterator.hasNext()) {

Modified: cxf/branches/2.5.x-fixes/services/sts/sts-core/src/main/java/org/apache/cxf/sts/claims/ClaimsManager.java
URL: http://svn.apache.org/viewvc/cxf/branches/2.5.x-fixes/services/sts/sts-core/src/main/java/org/apache/cxf/sts/claims/ClaimsManager.java?rev=1230197&r1=1230196&r2=1230197&view=diff
==============================================================================
--- cxf/branches/2.5.x-fixes/services/sts/sts-core/src/main/java/org/apache/cxf/sts/claims/ClaimsManager.java (original)
+++ cxf/branches/2.5.x-fixes/services/sts/sts-core/src/main/java/org/apache/cxf/sts/claims/ClaimsManager.java Wed Jan 11 19:17:43 2012
@@ -55,7 +55,7 @@ public class ClaimsManager {
 
     public ClaimCollection retrieveClaimValues(
             Principal principal, RequestClaimCollection claims, WebServiceContext context, String realm) {
-        if (claimHandlers != null && claimHandlers.size() > 0) {
+        if (claimHandlers != null && claimHandlers.size() > 0 && claims != null && claims.size() > 0) {
             ClaimCollection returnCollection = new ClaimCollection();
             for (ClaimsHandler handler : claimHandlers) {
                 ClaimCollection claimCollection = handler.retrieveClaimValues(

Modified: cxf/branches/2.5.x-fixes/services/sts/sts-core/src/main/java/org/apache/cxf/sts/operation/AbstractOperation.java
URL: http://svn.apache.org/viewvc/cxf/branches/2.5.x-fixes/services/sts/sts-core/src/main/java/org/apache/cxf/sts/operation/AbstractOperation.java?rev=1230197&r1=1230196&r2=1230197&view=diff
==============================================================================
--- cxf/branches/2.5.x-fixes/services/sts/sts-core/src/main/java/org/apache/cxf/sts/operation/AbstractOperation.java (original)
+++ cxf/branches/2.5.x-fixes/services/sts/sts-core/src/main/java/org/apache/cxf/sts/operation/AbstractOperation.java Wed Jan 11 19:17:43 2012
@@ -19,6 +19,7 @@
 
 package org.apache.cxf.sts.operation;
 
+import java.net.URI;
 import java.security.cert.X509Certificate;
 import java.util.ArrayList;
 import java.util.Collections;
@@ -42,6 +43,8 @@ import org.apache.cxf.sts.RealmParser;
 import org.apache.cxf.sts.STSConstants;
 import org.apache.cxf.sts.STSPropertiesMBean;
 import org.apache.cxf.sts.cache.STSTokenStore;
+import org.apache.cxf.sts.claims.ClaimsManager;
+import org.apache.cxf.sts.claims.RequestClaim;
 import org.apache.cxf.sts.claims.RequestClaimCollection;
 import org.apache.cxf.sts.request.KeyRequirements;
 import org.apache.cxf.sts.request.ReceivedToken;
@@ -95,6 +98,7 @@ public abstract class AbstractOperation 
     protected List<TokenValidator> tokenValidators = new ArrayList<TokenValidator>();
     protected boolean returnReferences = true;
     protected STSTokenStore tokenStore;
+    protected ClaimsManager claimsManager;
     
     public boolean isReturnReferences() {
         return returnReferences;
@@ -138,7 +142,15 @@ public abstract class AbstractOperation 
 
     public List<TokenValidator> getTokenValidators() {
         return tokenValidators;
-    }  
+    }
+    
+    public ClaimsManager getClaimsManager() {
+        return claimsManager;
+    }
+
+    public void setClaimsManager(ClaimsManager claimsManager) {
+        this.claimsManager = claimsManager;
+    }
     
     /**
      * Check the arguments from the STSProvider and parse the request.
@@ -548,5 +560,25 @@ public abstract class AbstractOperation 
         return tokenResponse;
     }
     
+    protected void checkClaimsSupport(RequestClaimCollection requestedClaims) {
+        if (requestedClaims != null) {
+            List<URI> unhandledClaimTypes = new ArrayList<URI>();
+            for (RequestClaim requestedClaim : requestedClaims) {
+                if (!claimsManager.getSupportedClaimTypes().contains(requestedClaim.getClaimType()) 
+                        && !requestedClaim.isOptional()) {
+                    unhandledClaimTypes.add(requestedClaim.getClaimType());
+                }
+            }
+
+            if (unhandledClaimTypes.size() > 0) {
+                LOG.log(Level.WARNING, "The requested claim " + unhandledClaimTypes.toString() 
+                        + " cannot be fulfilled by the STS.");
+                throw new STSException(
+                        "The requested claim " + unhandledClaimTypes.toString() 
+                        + " cannot be fulfilled by the STS."
+                );
+            }
+        }
+    }
     
 }

Modified: cxf/branches/2.5.x-fixes/services/sts/sts-core/src/main/java/org/apache/cxf/sts/operation/TokenIssueOperation.java
URL: http://svn.apache.org/viewvc/cxf/branches/2.5.x-fixes/services/sts/sts-core/src/main/java/org/apache/cxf/sts/operation/TokenIssueOperation.java?rev=1230197&r1=1230196&r2=1230197&view=diff
==============================================================================
--- cxf/branches/2.5.x-fixes/services/sts/sts-core/src/main/java/org/apache/cxf/sts/operation/TokenIssueOperation.java (original)
+++ cxf/branches/2.5.x-fixes/services/sts/sts-core/src/main/java/org/apache/cxf/sts/operation/TokenIssueOperation.java Wed Jan 11 19:17:43 2012
@@ -19,10 +19,7 @@
 
 package org.apache.cxf.sts.operation;
 
-import java.net.URI;
 import java.security.Principal;
-import java.util.ArrayList;
-import java.util.List;
 import java.util.Map;
 import java.util.logging.Level;
 import java.util.logging.Logger;
@@ -33,8 +30,6 @@ import javax.xml.ws.WebServiceContext;
 import org.apache.cxf.common.logging.LogUtils;
 import org.apache.cxf.sts.IdentityMapper;
 import org.apache.cxf.sts.QNameConstants;
-import org.apache.cxf.sts.claims.ClaimsManager;
-import org.apache.cxf.sts.claims.RequestClaim;
 import org.apache.cxf.sts.claims.RequestClaimCollection;
 import org.apache.cxf.sts.request.KeyRequirements;
 import org.apache.cxf.sts.request.ReceivedToken;
@@ -68,16 +63,6 @@ public class TokenIssueOperation extends
 
     private static final Logger LOG = LogUtils.getL7dLogger(TokenIssueOperation.class);
 
-    private ClaimsManager claimsManager; 
-
-    public ClaimsManager getClaimsManager() {
-        return claimsManager;
-    }
-
-    public void setClaimsManager(ClaimsManager claimsManager) {
-        this.claimsManager = claimsManager;
-    }
-
 
     public RequestSecurityTokenResponseCollectionType issue(
             RequestSecurityTokenType request,
@@ -100,26 +85,9 @@ public class TokenIssueOperation extends
 
         // Check if the requested claims can be handled by the configured claim handlers
         RequestClaimCollection requestedClaims = providerParameters.getRequestedClaims();
-        if (requestedClaims != null) {
-            List<URI> unhandledClaimTypes = new ArrayList<URI>();
-            for (RequestClaim requestedClaim : requestedClaims) {
-                if (!claimsManager.getSupportedClaimTypes().contains(requestedClaim.getClaimType()) 
-                        && !requestedClaim.isOptional()) {
-                    unhandledClaimTypes.add(requestedClaim.getClaimType());
-                }
-            }
-
-            if (unhandledClaimTypes.size() > 0) {
-                LOG.log(Level.WARNING, "The requested claim " + unhandledClaimTypes.toString() 
-                        + " cannot be fulfilled by the STS.");
-                throw new STSException(
-                        "The requested claim " + unhandledClaimTypes.toString() 
-                        + " cannot be fulfilled by the STS."
-                );
-            }
-        }
-
+        checkClaimsSupport(requestedClaims);
         providerParameters.setClaimsManager(claimsManager);
+        
         String realm = providerParameters.getRealm();
 
         TokenRequirements tokenRequirements = requestParser.getTokenRequirements();

Modified: cxf/branches/2.5.x-fixes/services/sts/sts-core/src/main/java/org/apache/cxf/sts/operation/TokenValidateOperation.java
URL: http://svn.apache.org/viewvc/cxf/branches/2.5.x-fixes/services/sts/sts-core/src/main/java/org/apache/cxf/sts/operation/TokenValidateOperation.java?rev=1230197&r1=1230196&r2=1230197&view=diff
==============================================================================
--- cxf/branches/2.5.x-fixes/services/sts/sts-core/src/main/java/org/apache/cxf/sts/operation/TokenValidateOperation.java (original)
+++ cxf/branches/2.5.x-fixes/services/sts/sts-core/src/main/java/org/apache/cxf/sts/operation/TokenValidateOperation.java Wed Jan 11 19:17:43 2012
@@ -32,6 +32,7 @@ import org.apache.cxf.sts.IdentityMapper
 import org.apache.cxf.sts.QNameConstants;
 import org.apache.cxf.sts.RealmParser;
 import org.apache.cxf.sts.STSConstants;
+import org.apache.cxf.sts.claims.RequestClaimCollection;
 import org.apache.cxf.sts.request.ReceivedToken;
 import org.apache.cxf.sts.request.RequestParser;
 import org.apache.cxf.sts.request.TokenRequirements;
@@ -118,6 +119,11 @@ public class TokenValidateOperation exte
                 }
             }
             
+            // Check if the requested claims can be handled by the configured claim handlers
+            RequestClaimCollection requestedClaims = providerParameters.getRequestedClaims();
+            checkClaimsSupport(requestedClaims);
+            providerParameters.setClaimsManager(claimsManager);
+            
             Map<String, Object> additionalProperties = tokenResponse.getAdditionalProperties();
             if (additionalProperties != null) {
                 providerParameters.setAdditionalProperties(additionalProperties);

Modified: cxf/branches/2.5.x-fixes/services/sts/sts-core/src/test/java/org/apache/cxf/sts/operation/ValidateTokenTransformationUnitTest.java
URL: http://svn.apache.org/viewvc/cxf/branches/2.5.x-fixes/services/sts/sts-core/src/test/java/org/apache/cxf/sts/operation/ValidateTokenTransformationUnitTest.java?rev=1230197&r1=1230196&r2=1230197&view=diff
==============================================================================
--- cxf/branches/2.5.x-fixes/services/sts/sts-core/src/test/java/org/apache/cxf/sts/operation/ValidateTokenTransformationUnitTest.java (original)
+++ cxf/branches/2.5.x-fixes/services/sts/sts-core/src/test/java/org/apache/cxf/sts/operation/ValidateTokenTransformationUnitTest.java Wed Jan 11 19:17:43 2012
@@ -20,6 +20,7 @@ package org.apache.cxf.sts.operation;
 
 import java.security.Principal;
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -28,8 +29,10 @@ import java.util.Properties;
 import javax.xml.bind.JAXBElement;
 import javax.xml.namespace.QName;
 
+import org.w3c.dom.Document;
 import org.w3c.dom.Element;
 
+import org.apache.cxf.helpers.DOMUtils;
 import org.apache.cxf.jaxws.context.WebServiceContextImpl;
 import org.apache.cxf.jaxws.context.WrappedMessageContext;
 import org.apache.cxf.message.MessageImpl;
@@ -38,13 +41,20 @@ import org.apache.cxf.sts.QNameConstants
 import org.apache.cxf.sts.STSConstants;
 import org.apache.cxf.sts.STSPropertiesMBean;
 import org.apache.cxf.sts.StaticSTSProperties;
+import org.apache.cxf.sts.claims.ClaimTypes;
+import org.apache.cxf.sts.claims.ClaimsHandler;
+import org.apache.cxf.sts.claims.ClaimsManager; 
+import org.apache.cxf.sts.common.CustomAttributeProvider;
+import org.apache.cxf.sts.common.CustomClaimsHandler;
 import org.apache.cxf.sts.common.PasswordCallbackHandler;
+import org.apache.cxf.sts.token.provider.AttributeStatementProvider;
 import org.apache.cxf.sts.token.provider.SAMLTokenProvider;
 import org.apache.cxf.sts.token.provider.TokenProvider;
 import org.apache.cxf.sts.token.realm.SAMLRealm;
 import org.apache.cxf.sts.token.validator.TokenValidator;
 import org.apache.cxf.sts.token.validator.UsernameTokenValidator;
 import org.apache.cxf.ws.security.sts.provider.STSException;
+import org.apache.cxf.ws.security.sts.provider.model.ClaimsType;
 import org.apache.cxf.ws.security.sts.provider.model.RequestSecurityTokenResponseType;
 import org.apache.cxf.ws.security.sts.provider.model.RequestSecurityTokenType;
 import org.apache.cxf.ws.security.sts.provider.model.RequestedSecurityTokenType;
@@ -243,6 +253,120 @@ public class ValidateTokenTransformation
         assertTrue(tokenString.contains("ALICE"));
         assertTrue(tokenString.contains(SAML2Constants.CONF_BEARER));
     }
+
+    /**
+     * Test to successfully validate a UsernameToken and transform it into a SAML Assertion.
+     * Required claims are a child of RST element
+     */
+    @org.junit.Test
+    public void testUsernameTokenTransformationClaims() throws Exception {
+        runUsernameTokenTransformationClaims(false);
+    }
+    
+    /**
+     * Test to successfully validate a UsernameToken and transform it into a SAML Assertion.
+     * Required claims are a child of SecondaryParameters element
+     */
+    @org.junit.Test
+    public void testUsernameTokenTransformationClaimsSecondaryParameters() throws Exception {
+        runUsernameTokenTransformationClaims(true);
+    }
+    
+    /**
+     * Test to successfully validate a UsernameToken and transform it into a SAML Assertion with claims.
+     */
+    private void runUsernameTokenTransformationClaims(boolean useSecondaryParameters) throws Exception {
+        TokenValidateOperation validateOperation = new TokenValidateOperation();
+        
+        // Add Token Validator
+        List<TokenValidator> validatorList = new ArrayList<TokenValidator>();
+        validatorList.add(new UsernameTokenValidator());
+        validateOperation.setTokenValidators(validatorList);
+
+        // Add Token Provider
+        List<TokenProvider> providerList = new ArrayList<TokenProvider>();
+       
+        List<AttributeStatementProvider> customProviderList = 
+            new ArrayList<AttributeStatementProvider>();
+        customProviderList.add(new CustomAttributeProvider());
+        SAMLTokenProvider samlTokenProvider = new SAMLTokenProvider();
+        samlTokenProvider.setAttributeStatementProviders(customProviderList);
+        providerList.add(samlTokenProvider);
+        validateOperation.setTokenProviders(providerList);
+        
+        // Add STSProperties object
+        STSPropertiesMBean stsProperties = new StaticSTSProperties();
+        Crypto crypto = CryptoFactory.getInstance(getEncryptionProperties());
+        stsProperties.setEncryptionCrypto(crypto);
+        stsProperties.setSignatureCrypto(crypto);
+        stsProperties.setEncryptionUsername("myservicekey");
+        stsProperties.setSignatureUsername("mystskey");
+        stsProperties.setCallbackHandler(new PasswordCallbackHandler());
+        stsProperties.setIssuer("STS");
+        validateOperation.setStsProperties(stsProperties);
+        
+        // Set the ClaimsManager
+        ClaimsManager claimsManager = new ClaimsManager();
+        ClaimsHandler claimsHandler = new CustomClaimsHandler();
+        claimsManager.setClaimHandlers(Collections.singletonList(claimsHandler));
+        validateOperation.setClaimsManager(claimsManager);
+        
+        // Mock up a request
+        RequestSecurityTokenType request = new RequestSecurityTokenType();
+        JAXBElement<String> tokenType = 
+            new JAXBElement<String>(
+                QNameConstants.TOKEN_TYPE, String.class, WSConstants.WSS_SAML2_TOKEN_TYPE
+            );
+        request.getAny().add(tokenType);
+        Object claims = 
+            useSecondaryParameters ? createClaimsElementInSecondaryParameters() : createClaimsElement();
+            
+        request.getAny().add(claims);
+        
+        // Create a UsernameToken
+        JAXBElement<UsernameTokenType> usernameTokenType = createUsernameToken("alice", "clarinet");
+        ValidateTargetType validateTarget = new ValidateTargetType();
+        validateTarget.setAny(usernameTokenType);
+        
+        JAXBElement<ValidateTargetType> validateTargetType = 
+            new JAXBElement<ValidateTargetType>(
+                QNameConstants.VALIDATE_TARGET, ValidateTargetType.class, validateTarget
+            );
+        request.getAny().add(validateTargetType);
+        
+        // Mock up message context
+        MessageImpl msg = new MessageImpl();
+        WrappedMessageContext msgCtx = new WrappedMessageContext(msg);
+        msgCtx.put(
+            SecurityContext.class.getName(), 
+            createSecurityContext(new CustomTokenPrincipal("alice"))
+        );
+        WebServiceContextImpl webServiceContext = new WebServiceContextImpl(msgCtx);
+        
+        // Validate a token
+        RequestSecurityTokenResponseType response = 
+            validateOperation.validate(request, webServiceContext);
+        assertTrue(validateResponse(response));
+        
+        // Test the generated token.
+        Element assertion = null;
+        for (Object tokenObject : response.getAny()) {
+            if (tokenObject instanceof JAXBElement<?>
+                && REQUESTED_SECURITY_TOKEN.equals(((JAXBElement<?>)tokenObject).getName())) {
+                RequestedSecurityTokenType rstType = 
+                    (RequestedSecurityTokenType)((JAXBElement<?>)tokenObject).getValue();
+                assertion = (Element)rstType.getAny();
+                break;
+            }
+        }
+        
+        assertNotNull(assertion);
+        String tokenString = DOM2Writer.nodeToString(assertion);
+        assertTrue(tokenString.contains("AttributeStatement"));
+        assertTrue(tokenString.contains("alice"));
+        assertTrue(tokenString.contains(SAML2Constants.CONF_BEARER));
+        assertTrue(tokenString.contains(ClaimTypes.FIRSTNAME.toString()));
+    }
     
     /*
      * Create a security context object
@@ -325,4 +449,53 @@ public class ValidateTokenTransformation
         return tokenType;
     }
     
+    /*
+     * Mock up a DOM Element containing some claims
+     */
+    private JAXBElement<ClaimsType> createClaimsElement() {
+        Document doc = DOMUtils.createDocument();
+        
+        Element claimType = createClaimsType(doc);        
+       
+        ClaimsType claims = new ClaimsType();
+        claims.setDialect(STSConstants.IDT_NS_05_05);
+        claims.getAny().add(claimType);
+        
+        JAXBElement<ClaimsType> claimsType =
+            new JAXBElement<ClaimsType>(
+                    QNameConstants.CLAIMS, ClaimsType.class, claims
+            );
+        
+        return claimsType;
+    }
+    
+    /*
+     * Mock up a SecondaryParameters DOM Element containing some claims
+     */
+    private Element createClaimsElementInSecondaryParameters() {
+        Document doc = DOMUtils.createDocument();
+        Element secondary = doc.createElementNS(STSConstants.WST_NS_05_12, "SecondaryParameters");
+        secondary.setAttributeNS(WSConstants.XMLNS_NS, "xmlns", STSConstants.WST_NS_05_12);
+        
+        Element claims = doc.createElementNS(STSConstants.WST_NS_05_12, "Claims");
+        claims.setAttributeNS(null, "Dialect", STSConstants.IDT_NS_05_05);
+        
+        Element claimType = createClaimsType(doc);
+        
+        claims.appendChild(claimType);
+        secondary.appendChild(claims);
+
+        return secondary;
+    }
+    
+    private Element createClaimsType(Document doc) {
+        Element claimType = doc.createElementNS(STSConstants.IDT_NS_05_05, "ClaimType");
+        claimType.setAttributeNS(
+            null, "Uri", "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname"
+        );
+        claimType.setAttributeNS(WSConstants.XMLNS_NS, "xmlns", STSConstants.IDT_NS_05_05);
+        
+        return claimType;
+    }
+    
 }