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/09/10 20:30:57 UTC

svn commit: r1383025 - in /cxf/branches/2.6.x-fixes/services/sts/sts-core/src: main/java/org/apache/cxf/sts/claims/ test/java/org/apache/cxf/sts/token/provider/

Author: owulff
Date: Mon Sep 10 18:30:57 2012
New Revision: 1383025

URL: http://svn.apache.org/viewvc?rev=1383025&view=rev
Log:
[CXF-4460] Support static claims globally and per endpoint

Added:
    cxf/branches/2.6.x-fixes/services/sts/sts-core/src/main/java/org/apache/cxf/sts/claims/StaticClaimsHandler.java
    cxf/branches/2.6.x-fixes/services/sts/sts-core/src/main/java/org/apache/cxf/sts/claims/StaticEndpointClaimsHandler.java
Modified:
    cxf/branches/2.6.x-fixes/services/sts/sts-core/src/test/java/org/apache/cxf/sts/token/provider/SAMLClaimsTest.java

Added: cxf/branches/2.6.x-fixes/services/sts/sts-core/src/main/java/org/apache/cxf/sts/claims/StaticClaimsHandler.java
URL: http://svn.apache.org/viewvc/cxf/branches/2.6.x-fixes/services/sts/sts-core/src/main/java/org/apache/cxf/sts/claims/StaticClaimsHandler.java?rev=1383025&view=auto
==============================================================================
--- cxf/branches/2.6.x-fixes/services/sts/sts-core/src/main/java/org/apache/cxf/sts/claims/StaticClaimsHandler.java (added)
+++ cxf/branches/2.6.x-fixes/services/sts/sts-core/src/main/java/org/apache/cxf/sts/claims/StaticClaimsHandler.java Mon Sep 10 18:30:57 2012
@@ -0,0 +1,82 @@
+/**
+ * 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.sts.claims;
+
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import org.apache.cxf.common.logging.LogUtils;
+
+public class StaticClaimsHandler implements ClaimsHandler {
+
+    private static final Logger LOG = LogUtils.getL7dLogger(StaticClaimsHandler.class);
+
+    private Map<String, String> globalClaims;
+        
+    public void setGlobalClaims(Map<String, String> globalClaims) {
+        this.globalClaims = globalClaims;
+    }
+
+    public Map<String, String> getGlobalClaims() {
+        return globalClaims;
+    }
+
+    
+    public List<URI> getSupportedClaimTypes() {
+        List<URI> uriList = new ArrayList<URI>();
+        for (String uri : getGlobalClaims().keySet()) {
+            try {
+                uriList.add(new URI(uri));
+            } catch (URISyntaxException e) {
+                e.printStackTrace();
+            }
+        }
+
+        return uriList;
+    }    
+    
+    public ClaimCollection retrieveClaimValues(
+            RequestClaimCollection claims, ClaimsParameters parameters) {
+        
+        ClaimCollection claimsColl = new ClaimCollection();
+        for (RequestClaim claim : claims) {
+            if (getGlobalClaims().keySet().contains(claim.getClaimType().toString())) {
+                Claim c = new Claim();
+                c.setClaimType(claim.getClaimType());
+                c.setPrincipal(parameters.getPrincipal());
+                c.setValue(getGlobalClaims().get(claim.getClaimType().toString()));
+                claimsColl.add(c);
+            } else {
+                if (LOG.isLoggable(Level.FINER)) {
+                    LOG.finer("Unsupported claim: " + claim.getClaimType());
+                }
+            }
+        }
+        return claimsColl;
+        
+    }
+
+}
+

Added: cxf/branches/2.6.x-fixes/services/sts/sts-core/src/main/java/org/apache/cxf/sts/claims/StaticEndpointClaimsHandler.java
URL: http://svn.apache.org/viewvc/cxf/branches/2.6.x-fixes/services/sts/sts-core/src/main/java/org/apache/cxf/sts/claims/StaticEndpointClaimsHandler.java?rev=1383025&view=auto
==============================================================================
--- cxf/branches/2.6.x-fixes/services/sts/sts-core/src/main/java/org/apache/cxf/sts/claims/StaticEndpointClaimsHandler.java (added)
+++ cxf/branches/2.6.x-fixes/services/sts/sts-core/src/main/java/org/apache/cxf/sts/claims/StaticEndpointClaimsHandler.java Mon Sep 10 18:30:57 2012
@@ -0,0 +1,91 @@
+/**
+ * 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.sts.claims;
+
+import java.net.URI;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import org.apache.cxf.common.logging.LogUtils;
+
+public class StaticEndpointClaimsHandler implements ClaimsHandler {
+
+    private static final Logger LOG = LogUtils.getL7dLogger(StaticEndpointClaimsHandler.class);
+
+    private Map<String, Map<String, String>> endpointClaimsMap;
+    private List<URI> supportedClaims;
+
+    public void setEndpointClaims(Map<String, Map<String, String>> userClaims) {
+        this.endpointClaimsMap = userClaims;
+    }
+
+    public Map<String, Map<String, String>> getEndpointClaims() {
+        return endpointClaimsMap;
+    }
+    
+    public void setSupportedClaims(List<URI> supportedClaims) {
+        this.supportedClaims = supportedClaims;
+    }
+    
+    public List<URI> getSupportedClaimTypes() {
+        return Collections.unmodifiableList(this.supportedClaims);
+    }    
+    
+    public ClaimCollection retrieveClaimValues(
+            RequestClaimCollection claims, ClaimsParameters parameters) {
+        
+        ClaimCollection claimsColl = new ClaimCollection();
+        String appliesTo = parameters.getAppliesToAddress();
+        if (appliesTo == null) {
+            if (LOG.isLoggable(Level.FINER)) {
+                LOG.finer("AppliesTo not provided in RST. " + StaticEndpointClaimsHandler.class.getName() + " ignored");
+            }
+            return claimsColl;
+        }
+        Map<String, String> endpointClaims = this.getEndpointClaims().get(appliesTo);
+        if (endpointClaims == null) {
+            if (LOG.isLoggable(Level.FINER)) {
+                LOG.finer(StaticEndpointClaimsHandler.class.getName()
+                        + " doesn't define claims for endpoint '" + appliesTo + "'");
+            }
+            return claimsColl;
+        }
+        for (RequestClaim claim : claims) {
+            if (endpointClaims.keySet().contains(claim.getClaimType().toString())) {
+                Claim c = new Claim();
+                c.setClaimType(claim.getClaimType());
+                c.setPrincipal(parameters.getPrincipal());
+                c.setValue(endpointClaims.get(claim.getClaimType().toString()));
+                claimsColl.add(c);
+            } else {
+                if (LOG.isLoggable(Level.FINER)) {
+                    LOG.finer("Unsupported claim: " + claim.getClaimType());
+                }
+            }
+        }
+        return claimsColl;
+        
+    }
+
+}
+

Modified: cxf/branches/2.6.x-fixes/services/sts/sts-core/src/test/java/org/apache/cxf/sts/token/provider/SAMLClaimsTest.java
URL: http://svn.apache.org/viewvc/cxf/branches/2.6.x-fixes/services/sts/sts-core/src/test/java/org/apache/cxf/sts/token/provider/SAMLClaimsTest.java?rev=1383025&r1=1383024&r2=1383025&view=diff
==============================================================================
--- cxf/branches/2.6.x-fixes/services/sts/sts-core/src/test/java/org/apache/cxf/sts/token/provider/SAMLClaimsTest.java (original)
+++ cxf/branches/2.6.x-fixes/services/sts/sts-core/src/test/java/org/apache/cxf/sts/token/provider/SAMLClaimsTest.java Mon Sep 10 18:30:57 2012
@@ -18,9 +18,12 @@
  */
 package org.apache.cxf.sts.token.provider;
 
+import java.net.URI;
 import java.util.ArrayList;
 import java.util.Collections;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 import java.util.Properties;
 
 import org.w3c.dom.Element;
@@ -31,10 +34,13 @@ import org.apache.cxf.message.MessageImp
 import org.apache.cxf.sts.STSConstants;
 import org.apache.cxf.sts.StaticSTSProperties;
 import org.apache.cxf.sts.claims.ClaimTypes;
+import org.apache.cxf.sts.claims.ClaimsAttributeStatementProvider;
 import org.apache.cxf.sts.claims.ClaimsHandler;
 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.claims.StaticClaimsHandler;
+import org.apache.cxf.sts.claims.StaticEndpointClaimsHandler;
 import org.apache.cxf.sts.common.CustomAttributeProvider;
 import org.apache.cxf.sts.common.CustomClaimsHandler;
 import org.apache.cxf.sts.common.PasswordCallbackHandler;
@@ -46,14 +52,30 @@ import org.apache.ws.security.WSConstant
 import org.apache.ws.security.WSSecurityException;
 import org.apache.ws.security.components.crypto.Crypto;
 import org.apache.ws.security.components.crypto.CryptoFactory;
+import org.apache.ws.security.saml.ext.AssertionWrapper;
 import org.apache.ws.security.saml.ext.builder.SAML2Constants;
 import org.apache.ws.security.util.DOM2Writer;
 
+import org.opensaml.saml2.core.Attribute;
+import org.opensaml.xml.XMLObject;
+
 /**
  * A unit test for creating a SAML Tokens with various Attributes populated by a ClaimsHandler.
  */
 public class SAMLClaimsTest extends org.junit.Assert {
     
+    public static final URI CLAIM_STATIC_COMPANY = 
+        URI.create("http://apache.org/claims/test/company");
+    
+    public static final URI CLAIM_APPLICATION = 
+        URI.create("http://apache.org/claims/test/applicationId");
+    
+    private static final String CLAIM_STATIC_COMPANY_VALUE = "myc@mpany";
+    
+    private static final String CLAIM_APPLICATION_VALUE = "my@pplic@tion";
+    
+    private static final String APPLICATION_APPLIES_TO = "http://dummy-service.com/dummy";
+    
     /**
      * Test the creation of a SAML2 Assertion with various Attributes set by a ClaimsHandler.
      */
@@ -61,7 +83,15 @@ public class SAMLClaimsTest extends org.
     public void testSaml2Claims() throws Exception {
         TokenProvider samlTokenProvider = new SAMLTokenProvider();
         TokenProviderParameters providerParameters = 
-            createProviderParameters(WSConstants.WSS_SAML2_TOKEN_TYPE, STSConstants.BEARER_KEY_KEYTYPE);
+            createProviderParameters(WSConstants.WSS_SAML2_TOKEN_TYPE, STSConstants.BEARER_KEY_KEYTYPE, null);
+        
+        ClaimsManager claimsManager = new ClaimsManager();
+        ClaimsHandler claimsHandler = new CustomClaimsHandler();
+        claimsManager.setClaimHandlers(Collections.singletonList(claimsHandler));
+        providerParameters.setClaimsManager(claimsManager);
+        
+        RequestClaimCollection claims = createClaims();
+        providerParameters.setRequestedClaims(claims);
         
         List<AttributeStatementProvider> customProviderList = new ArrayList<AttributeStatementProvider>();
         customProviderList.add(new CustomAttributeProvider());
@@ -83,8 +113,160 @@ public class SAMLClaimsTest extends org.
         assertTrue(tokenString.contains(ClaimTypes.LASTNAME.toString()));
     }
     
+    /**
+     * Test the creation of a SAML2 Assertion with StaticClaimsHandler
+     */
+    @org.junit.Test
+    public void testSaml2StaticClaims() throws Exception {
+        TokenProvider samlTokenProvider = new SAMLTokenProvider();
+        TokenProviderParameters providerParameters = 
+            createProviderParameters(WSConstants.WSS_SAML2_TOKEN_TYPE, STSConstants.BEARER_KEY_KEYTYPE, null);
+        
+        ClaimsManager claimsManager = new ClaimsManager();
+        StaticClaimsHandler claimsHandler = new StaticClaimsHandler();
+        Map<String, String> staticClaimsMap = new HashMap<String, String>();
+        staticClaimsMap.put(CLAIM_STATIC_COMPANY.toString(), CLAIM_STATIC_COMPANY_VALUE);
+        claimsHandler.setGlobalClaims(staticClaimsMap);
+        claimsManager.setClaimHandlers(Collections.singletonList((ClaimsHandler)claimsHandler));
+        providerParameters.setClaimsManager(claimsManager);
+        
+        RequestClaimCollection claims = new RequestClaimCollection();
+        RequestClaim claim = new RequestClaim();
+        claim.setClaimType(CLAIM_STATIC_COMPANY);
+        claims.add(claim);
+        providerParameters.setRequestedClaims(claims);
+        
+        List<AttributeStatementProvider> customProviderList = new ArrayList<AttributeStatementProvider>();
+        customProviderList.add(new ClaimsAttributeStatementProvider());
+        ((SAMLTokenProvider)samlTokenProvider).setAttributeStatementProviders(customProviderList);
+        
+        assertTrue(samlTokenProvider.canHandleToken(WSConstants.WSS_SAML2_TOKEN_TYPE));
+        TokenProviderResponse providerResponse = samlTokenProvider.createToken(providerParameters);
+        assertTrue(providerResponse != null);
+        assertTrue(providerResponse.getToken() != null && providerResponse.getTokenId() != null);
+        
+        Element token = providerResponse.getToken();
+        String tokenString = DOM2Writer.nodeToString(token);
+        assertTrue(tokenString.contains(providerResponse.getTokenId()));
+        assertTrue(tokenString.contains("AttributeStatement"));
+        assertTrue(tokenString.contains("alice"));
+        assertTrue(tokenString.contains(SAML2Constants.CONF_BEARER));
+        
+        AssertionWrapper assertion = new AssertionWrapper(token);
+        List<Attribute> attributes = assertion.getSaml2().getAttributeStatements().get(0).getAttributes();
+        assertEquals(attributes.size(), 1);
+        assertEquals(attributes.get(0).getName(), CLAIM_STATIC_COMPANY.toString());
+        XMLObject valueObj = attributes.get(0).getAttributeValues().get(0);
+        assertEquals(valueObj.getDOM().getTextContent(), CLAIM_STATIC_COMPANY_VALUE);      
+    }
+    
+    /**
+     * Test the creation of a SAML2 Assertion with StaticEndpointClaimsHandler
+     */
+    @org.junit.Test
+    public void testSaml2StaticEndpointClaims() throws Exception {
+        TokenProvider samlTokenProvider = new SAMLTokenProvider();
+        TokenProviderParameters providerParameters = 
+            createProviderParameters(WSConstants.WSS_SAML2_TOKEN_TYPE, STSConstants.BEARER_KEY_KEYTYPE, null);
+        
+        ClaimsManager claimsManager = new ClaimsManager();
+        StaticEndpointClaimsHandler claimsHandler = new StaticEndpointClaimsHandler();
+        
+        // Create claims map for specific application
+        Map<String, String> endpointClaimsMap = new HashMap<String, String>();
+        endpointClaimsMap.put(CLAIM_APPLICATION.toString(), CLAIM_APPLICATION_VALUE);
+        
+        Map<String, Map<String, String>> staticClaims = new HashMap<String, Map<String, String>>();
+        staticClaims.put(APPLICATION_APPLIES_TO, endpointClaimsMap);
+        claimsHandler.setEndpointClaims(staticClaims);
+        
+        List<URI> supportedClaims = new ArrayList<URI>();
+        supportedClaims.add(CLAIM_APPLICATION);
+        claimsHandler.setSupportedClaims(supportedClaims);
+        
+        claimsManager.setClaimHandlers(Collections.singletonList((ClaimsHandler)claimsHandler));
+        providerParameters.setClaimsManager(claimsManager);
+        
+        RequestClaimCollection claims = new RequestClaimCollection();
+        RequestClaim claim = new RequestClaim();
+        claim.setClaimType(CLAIM_APPLICATION);
+        claims.add(claim);
+        providerParameters.setRequestedClaims(claims);
+        
+        List<AttributeStatementProvider> customProviderList = new ArrayList<AttributeStatementProvider>();
+        customProviderList.add(new ClaimsAttributeStatementProvider());
+        ((SAMLTokenProvider)samlTokenProvider).setAttributeStatementProviders(customProviderList);
+        
+        assertTrue(samlTokenProvider.canHandleToken(WSConstants.WSS_SAML2_TOKEN_TYPE));
+        TokenProviderResponse providerResponse = samlTokenProvider.createToken(providerParameters);
+        assertTrue(providerResponse != null);
+        assertTrue(providerResponse.getToken() != null && providerResponse.getTokenId() != null);
+        
+        Element token = providerResponse.getToken();
+        String tokenString = DOM2Writer.nodeToString(token);
+        assertTrue(tokenString.contains(providerResponse.getTokenId()));
+        assertTrue(tokenString.contains("AttributeStatement"));
+        assertTrue(tokenString.contains("alice"));
+        assertTrue(tokenString.contains(SAML2Constants.CONF_BEARER));
+        
+        AssertionWrapper assertion = new AssertionWrapper(token);
+        List<Attribute> attributes = assertion.getSaml2().getAttributeStatements().get(0).getAttributes();
+        assertEquals(attributes.size(), 1);
+        assertEquals(attributes.get(0).getName(), CLAIM_APPLICATION.toString());
+        XMLObject valueObj = attributes.get(0).getAttributeValues().get(0);
+        assertEquals(valueObj.getDOM().getTextContent(), CLAIM_APPLICATION_VALUE);      
+    }
+    
+    /**
+     * Test the creation of a SAML2 Assertion with StaticEndpointClaimsHandler
+     * but unknown AppliesTo value
+     */
+    @org.junit.Test
+    public void testSaml2StaticEndpointClaimsUnknownAppliesTo() throws Exception {
+        TokenProvider samlTokenProvider = new SAMLTokenProvider();
+        TokenProviderParameters providerParameters = 
+            createProviderParameters(WSConstants.WSS_SAML2_TOKEN_TYPE, 
+                    STSConstants.BEARER_KEY_KEYTYPE, APPLICATION_APPLIES_TO + "UNKNOWN");
+        
+        ClaimsManager claimsManager = new ClaimsManager();
+        StaticEndpointClaimsHandler claimsHandler = new StaticEndpointClaimsHandler();
+        
+        // Create claims map for specific application
+        Map<String, String> endpointClaimsMap = new HashMap<String, String>();
+        endpointClaimsMap.put(CLAIM_APPLICATION.toString(), CLAIM_APPLICATION_VALUE);
+        
+        Map<String, Map<String, String>> staticClaims = new HashMap<String, Map<String, String>>();
+        staticClaims.put(APPLICATION_APPLIES_TO, endpointClaimsMap);
+        claimsHandler.setEndpointClaims(staticClaims);
+        
+        List<URI> supportedClaims = new ArrayList<URI>();
+        supportedClaims.add(CLAIM_APPLICATION);
+        claimsHandler.setSupportedClaims(supportedClaims);
+        
+        claimsManager.setClaimHandlers(Collections.singletonList((ClaimsHandler)claimsHandler));
+        providerParameters.setClaimsManager(claimsManager);
+        
+        RequestClaimCollection claims = new RequestClaimCollection();
+        RequestClaim claim = new RequestClaim();
+        claim.setClaimType(CLAIM_APPLICATION);
+        claims.add(claim);
+        providerParameters.setRequestedClaims(claims);
+        
+        List<AttributeStatementProvider> customProviderList = new ArrayList<AttributeStatementProvider>();
+        customProviderList.add(new ClaimsAttributeStatementProvider());
+        ((SAMLTokenProvider)samlTokenProvider).setAttributeStatementProviders(customProviderList);
+        assertTrue(samlTokenProvider.canHandleToken(WSConstants.WSS_SAML2_TOKEN_TYPE));
+        
+        try {
+            samlTokenProvider.createToken(providerParameters);
+            fail("Failure expected as the claim for the application can't be found due to unknown AppliesTo");
+        } catch (Exception ex) {
+            // expected on the wrong attribute provider
+        }        
+    }
+    
     private TokenProviderParameters createProviderParameters(
-        String tokenType, String keyType
+        String tokenType, String keyType, String appliesTo
     ) throws WSSecurityException {
         TokenProviderParameters parameters = new TokenProviderParameters();
         
@@ -103,7 +285,11 @@ public class SAMLClaimsTest extends org.
         WebServiceContextImpl webServiceContext = new WebServiceContextImpl(msgCtx);
         parameters.setWebServiceContext(webServiceContext);
         
-        parameters.setAppliesToAddress("http://dummy-service.com/dummy");
+        if (appliesTo != null) {
+            parameters.setAppliesToAddress(appliesTo);
+        } else {
+            parameters.setAppliesToAddress(APPLICATION_APPLIES_TO);
+        }
         
         // Add STSProperties object
         StaticSTSProperties stsProperties = new StaticSTSProperties();
@@ -118,13 +304,7 @@ public class SAMLClaimsTest extends org.
         
         parameters.setEncryptionProperties(new EncryptionProperties());
         
-        ClaimsManager claimsManager = new ClaimsManager();
-        ClaimsHandler claimsHandler = new CustomClaimsHandler();
-        claimsManager.setClaimHandlers(Collections.singletonList(claimsHandler));
-        parameters.setClaimsManager(claimsManager);
-        
-        RequestClaimCollection claims = createClaims();
-        parameters.setRequestedClaims(claims);
+
         
         return parameters;
     }