You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cxf.apache.org by co...@apache.org on 2016/01/27 12:00:19 UTC

cxf git commit: [CXF-6763] - STS requires ClaimHandler even in ClaimMapping only scenarios

Repository: cxf
Updated Branches:
  refs/heads/master 8571a5a79 -> 0966883ab


[CXF-6763] - STS requires ClaimHandler even in ClaimMapping only scenarios


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

Branch: refs/heads/master
Commit: 0966883ab051a53da0b60e285fdf9e494fdb6edc
Parents: 8571a5a
Author: Colm O hEigeartaigh <co...@apache.org>
Authored: Wed Jan 27 11:00:06 2016 +0000
Committer: Colm O hEigeartaigh <co...@apache.org>
Committed: Wed Jan 27 11:00:06 2016 +0000

----------------------------------------------------------------------
 .../apache/cxf/sts/claims/ClaimsManager.java    | 176 ++++++++++---------
 .../cxf/sts/operation/AbstractOperation.java    |  23 ---
 .../cxf/sts/operation/TokenIssueOperation.java  |   7 -
 .../sts/operation/TokenValidateOperation.java   |   5 -
 .../cxf/sts/common/CustomAttributeProvider.java |  25 +--
 .../sts/operation/IssueSamlClaimsUnitTest.java  |  52 ++++++
 6 files changed, 144 insertions(+), 144 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cxf/blob/0966883a/services/sts/sts-core/src/main/java/org/apache/cxf/sts/claims/ClaimsManager.java
----------------------------------------------------------------------
diff --git a/services/sts/sts-core/src/main/java/org/apache/cxf/sts/claims/ClaimsManager.java b/services/sts/sts-core/src/main/java/org/apache/cxf/sts/claims/ClaimsManager.java
index 505f7e3..6534394 100644
--- a/services/sts/sts-core/src/main/java/org/apache/cxf/sts/claims/ClaimsManager.java
+++ b/services/sts/sts-core/src/main/java/org/apache/cxf/sts/claims/ClaimsManager.java
@@ -145,92 +145,7 @@ public class ClaimsManager {
         if (relationship == null || relationship.getType().equals(Relationship.FED_TYPE_IDENTITY)) {
             // Federate identity. Identity already mapped.
             // Call all configured claims handlers to retrieve the required claims
-            if (claimHandlers == null || claimHandlers.size() == 0) {
-                return null;
-            }
-            Principal originalPrincipal = parameters.getPrincipal();
-            ProcessedClaimCollection returnCollection = new ProcessedClaimCollection();
-            for (ClaimsHandler handler : claimHandlers) {
-                
-                ClaimCollection supportedClaims = 
-                    filterHandlerClaims(claims, handler.getSupportedClaimTypes());
-                if (supportedClaims.isEmpty()) {
-                    continue;
-                }
-                
-                if (handler instanceof RealmSupport) {
-                    RealmSupport handlerRealmSupport = (RealmSupport)handler;
-                    // Check whether the handler supports the current realm
-                    if (handlerRealmSupport.getSupportedRealms() != null
-                            && handlerRealmSupport.getSupportedRealms().size() > 0
-                            && handlerRealmSupport.getSupportedRealms().indexOf(parameters.getRealm()) == -1) {
-                        if (LOG.isLoggable(Level.FINER)) {
-                            LOG.finer("Handler '" + handler.getClass().getName() + "' doesn't support"
-                                    + " realm '" + parameters.getRealm()  + "'");
-                        }
-                        continue;
-                    }
-                    
-                    // If handler realm is configured and different from current realm
-                    // do an identity mapping
-                    if (handlerRealmSupport.getHandlerRealm() != null
-                            && !handlerRealmSupport.getHandlerRealm().equalsIgnoreCase(parameters.getRealm())) {
-                        Principal targetPrincipal = null;
-                        try {
-                            if (LOG.isLoggable(Level.FINE)) {
-                                LOG.fine("Mapping user '" + parameters.getPrincipal().getName()
-                                        + "' [" + parameters.getRealm() + "] to realm '"
-                                        + handlerRealmSupport.getHandlerRealm() + "'");
-                            }
-                            targetPrincipal = doMapping(parameters.getRealm(), parameters.getPrincipal(),
-                                    handlerRealmSupport.getHandlerRealm());
-                        } catch (Exception ex) {
-                            LOG.log(Level.WARNING, "Failed to map user '" + parameters.getPrincipal().getName()
-                                    + "' [" + parameters.getRealm() + "] to realm '"
-                                    + handlerRealmSupport.getHandlerRealm() + "'", ex);
-                            throw new STSException("Failed to map user for claims handler",
-                                    STSException.REQUEST_FAILED);
-                        }
-                        
-                        if (targetPrincipal == null || targetPrincipal.getName() == null) {
-                            LOG.log(Level.WARNING, "Null. Failed to map user '" + parameters.getPrincipal().getName()
-                                    + "' [" + parameters.getRealm() + "] to realm '"
-                                    + handlerRealmSupport.getHandlerRealm() + "'");
-                            continue;
-                        }
-                        if (LOG.isLoggable(Level.INFO)) {
-                            LOG.info("Principal '" + targetPrincipal.getName()
-                                    + "' passed to handler '" + handler.getClass().getName() + "'");
-                        }
-                        parameters.setPrincipal(targetPrincipal);
-                    } else {
-                        if (LOG.isLoggable(Level.FINER)) {
-                            LOG.finer("Handler '" + handler.getClass().getName() + "' doesn't require"
-                                    + " identity mapping '" + parameters.getRealm()  + "'");
-                        }
-                        
-                    }
-                }
-                
-                ProcessedClaimCollection claimCollection = null;
-                try {
-                    claimCollection = handler.retrieveClaimValues(supportedClaims, parameters);
-                } catch (RuntimeException ex) {
-                    LOG.log(Level.INFO, "Failed retrieving claims from ClaimsHandler "
-                            + handler.getClass().getName(), ex);
-                    if (this.isStopProcessingOnException()) {
-                        throw ex;
-                    }
-                } finally {
-                    // set original principal again, otherwise wrong principal passed to next claim handler in the list
-                    // if no mapping required or wrong source principal used for next identity mapping
-                    parameters.setPrincipal(originalPrincipal);
-                }
-                
-                if (claimCollection != null && claimCollection.size() != 0) {
-                    returnCollection.addAll(claimCollection);
-                }
-            }
+            ProcessedClaimCollection returnCollection = handleClaims(claims, parameters);
             validateClaimValues(claims, returnCollection);
             return returnCollection;
             
@@ -263,6 +178,95 @@ public class ClaimsManager {
         }
 
     }
+    
+    private ProcessedClaimCollection handleClaims(ClaimCollection claims, ClaimsParameters parameters) {
+        ProcessedClaimCollection returnCollection = new ProcessedClaimCollection();
+        Principal originalPrincipal = parameters.getPrincipal();
+        
+        for (ClaimsHandler handler : claimHandlers) {
+            
+            ClaimCollection supportedClaims = 
+                filterHandlerClaims(claims, handler.getSupportedClaimTypes());
+            if (supportedClaims.isEmpty()) {
+                continue;
+            }
+            
+            if (handler instanceof RealmSupport) {
+                RealmSupport handlerRealmSupport = (RealmSupport)handler;
+                // Check whether the handler supports the current realm
+                if (handlerRealmSupport.getSupportedRealms() != null
+                        && handlerRealmSupport.getSupportedRealms().size() > 0
+                        && handlerRealmSupport.getSupportedRealms().indexOf(parameters.getRealm()) == -1) {
+                    if (LOG.isLoggable(Level.FINER)) {
+                        LOG.finer("Handler '" + handler.getClass().getName() + "' doesn't support"
+                                + " realm '" + parameters.getRealm()  + "'");
+                    }
+                    continue;
+                }
+                
+                // If handler realm is configured and different from current realm
+                // do an identity mapping
+                if (handlerRealmSupport.getHandlerRealm() != null
+                        && !handlerRealmSupport.getHandlerRealm().equalsIgnoreCase(parameters.getRealm())) {
+                    Principal targetPrincipal = null;
+                    try {
+                        if (LOG.isLoggable(Level.FINE)) {
+                            LOG.fine("Mapping user '" + parameters.getPrincipal().getName()
+                                    + "' [" + parameters.getRealm() + "] to realm '"
+                                    + handlerRealmSupport.getHandlerRealm() + "'");
+                        }
+                        targetPrincipal = doMapping(parameters.getRealm(), parameters.getPrincipal(),
+                                handlerRealmSupport.getHandlerRealm());
+                    } catch (Exception ex) {
+                        LOG.log(Level.WARNING, "Failed to map user '" + parameters.getPrincipal().getName()
+                                + "' [" + parameters.getRealm() + "] to realm '"
+                                + handlerRealmSupport.getHandlerRealm() + "'", ex);
+                        throw new STSException("Failed to map user for claims handler",
+                                STSException.REQUEST_FAILED);
+                    }
+                    
+                    if (targetPrincipal == null || targetPrincipal.getName() == null) {
+                        LOG.log(Level.WARNING, "Null. Failed to map user '" + parameters.getPrincipal().getName()
+                                + "' [" + parameters.getRealm() + "] to realm '"
+                                + handlerRealmSupport.getHandlerRealm() + "'");
+                        continue;
+                    }
+                    if (LOG.isLoggable(Level.INFO)) {
+                        LOG.info("Principal '" + targetPrincipal.getName()
+                                + "' passed to handler '" + handler.getClass().getName() + "'");
+                    }
+                    parameters.setPrincipal(targetPrincipal);
+                } else {
+                    if (LOG.isLoggable(Level.FINER)) {
+                        LOG.finer("Handler '" + handler.getClass().getName() + "' doesn't require"
+                                + " identity mapping '" + parameters.getRealm()  + "'");
+                    }
+                    
+                }
+            }
+            
+            ProcessedClaimCollection claimCollection = null;
+            try {
+                claimCollection = handler.retrieveClaimValues(supportedClaims, parameters);
+            } catch (RuntimeException ex) {
+                LOG.log(Level.INFO, "Failed retrieving claims from ClaimsHandler "
+                        + handler.getClass().getName(), ex);
+                if (this.isStopProcessingOnException()) {
+                    throw ex;
+                }
+            } finally {
+                // set original principal again, otherwise wrong principal passed to next claim handler in the list
+                // if no mapping required or wrong source principal used for next identity mapping
+                parameters.setPrincipal(originalPrincipal);
+            }
+            
+            if (claimCollection != null && claimCollection.size() != 0) {
+                returnCollection.addAll(claimCollection);
+            }
+        }
+        
+        return returnCollection;
+    }
 
     private ClaimCollection filterHandlerClaims(ClaimCollection claims,
                                                          List<URI> handlerClaimTypes) {

http://git-wip-us.apache.org/repos/asf/cxf/blob/0966883a/services/sts/sts-core/src/main/java/org/apache/cxf/sts/operation/AbstractOperation.java
----------------------------------------------------------------------
diff --git a/services/sts/sts-core/src/main/java/org/apache/cxf/sts/operation/AbstractOperation.java b/services/sts/sts-core/src/main/java/org/apache/cxf/sts/operation/AbstractOperation.java
index e47287c..e801906 100644
--- a/services/sts/sts-core/src/main/java/org/apache/cxf/sts/operation/AbstractOperation.java
+++ b/services/sts/sts-core/src/main/java/org/apache/cxf/sts/operation/AbstractOperation.java
@@ -19,7 +19,6 @@
 
 package org.apache.cxf.sts.operation;
 
-import java.net.URI;
 import java.security.Principal;
 import java.util.ArrayList;
 import java.util.Date;
@@ -37,7 +36,6 @@ import org.w3c.dom.Document;
 import org.w3c.dom.Element;
 import org.apache.cxf.common.logging.LogUtils;
 import org.apache.cxf.helpers.DOMUtils;
-import org.apache.cxf.rt.security.claims.Claim;
 import org.apache.cxf.rt.security.claims.ClaimCollection;
 import org.apache.cxf.sts.IdentityMapper;
 import org.apache.cxf.sts.QNameConstants;
@@ -556,27 +554,6 @@ public abstract class AbstractOperation {
         }
     }
     
-    protected void checkClaimsSupport(ClaimCollection requestedClaims) {
-        if (requestedClaims != null) {
-            List<URI> unhandledClaimTypes = new ArrayList<>();
-            for (Claim 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."
-                );
-            }
-        }
-    }
-
     protected void processValidToken(TokenProviderParameters providerParameters,
             ReceivedToken validatedToken, TokenValidatorResponse tokenResponse) {
         // Map the principal (if it exists)

http://git-wip-us.apache.org/repos/asf/cxf/blob/0966883a/services/sts/sts-core/src/main/java/org/apache/cxf/sts/operation/TokenIssueOperation.java
----------------------------------------------------------------------
diff --git a/services/sts/sts-core/src/main/java/org/apache/cxf/sts/operation/TokenIssueOperation.java b/services/sts/sts-core/src/main/java/org/apache/cxf/sts/operation/TokenIssueOperation.java
index a835f2f..dc3ac86 100644
--- a/services/sts/sts-core/src/main/java/org/apache/cxf/sts/operation/TokenIssueOperation.java
+++ b/services/sts/sts-core/src/main/java/org/apache/cxf/sts/operation/TokenIssueOperation.java
@@ -37,7 +37,6 @@ import org.w3c.dom.Element;
 import org.apache.cxf.common.logging.LogUtils;
 import org.apache.cxf.helpers.CastUtils;
 import org.apache.cxf.helpers.DOMUtils;
-import org.apache.cxf.rt.security.claims.ClaimCollection;
 import org.apache.cxf.sts.QNameConstants;
 import org.apache.cxf.sts.event.STSIssueFailureEvent;
 import org.apache.cxf.sts.event.STSIssueSuccessEvent;
@@ -118,12 +117,6 @@ public class TokenIssueOperation extends AbstractOperation implements IssueOpera
             RequestRequirements requestRequirements = parseRequest(request, context);
     
             providerParameters = createTokenProviderParameters(requestRequirements, context);
-    
-            // Check if the requested claims can be handled by the configured claim handlers
-            ClaimCollection requestedClaims = providerParameters.getRequestedPrimaryClaims();
-            checkClaimsSupport(requestedClaims);
-            requestedClaims = providerParameters.getRequestedSecondaryClaims();
-            checkClaimsSupport(requestedClaims);
             providerParameters.setClaimsManager(claimsManager);
             
             String realm = providerParameters.getRealm();

http://git-wip-us.apache.org/repos/asf/cxf/blob/0966883a/services/sts/sts-core/src/main/java/org/apache/cxf/sts/operation/TokenValidateOperation.java
----------------------------------------------------------------------
diff --git a/services/sts/sts-core/src/main/java/org/apache/cxf/sts/operation/TokenValidateOperation.java b/services/sts/sts-core/src/main/java/org/apache/cxf/sts/operation/TokenValidateOperation.java
index 671094e..be8f75e 100644
--- a/services/sts/sts-core/src/main/java/org/apache/cxf/sts/operation/TokenValidateOperation.java
+++ b/services/sts/sts-core/src/main/java/org/apache/cxf/sts/operation/TokenValidateOperation.java
@@ -31,7 +31,6 @@ import org.w3c.dom.Element;
 
 import org.apache.cxf.common.logging.LogUtils;
 import org.apache.cxf.helpers.DOMUtils;
-import org.apache.cxf.rt.security.claims.ClaimCollection;
 import org.apache.cxf.sts.QNameConstants;
 import org.apache.cxf.sts.RealmParser;
 import org.apache.cxf.sts.STSConstants;
@@ -129,10 +128,6 @@ public class TokenValidateOperation extends AbstractOperation implements Validat
                 processValidToken(providerParameters, validateTarget, tokenResponse);
                 
                 // Check if the requested claims can be handled by the configured claim handlers
-                ClaimCollection requestedClaims = providerParameters.getRequestedPrimaryClaims();
-                checkClaimsSupport(requestedClaims);
-                requestedClaims = providerParameters.getRequestedSecondaryClaims();
-                checkClaimsSupport(requestedClaims);
                 providerParameters.setClaimsManager(claimsManager);
                 
                 Map<String, Object> additionalProperties = tokenResponse.getAdditionalProperties();

http://git-wip-us.apache.org/repos/asf/cxf/blob/0966883a/services/sts/sts-core/src/test/java/org/apache/cxf/sts/common/CustomAttributeProvider.java
----------------------------------------------------------------------
diff --git a/services/sts/sts-core/src/test/java/org/apache/cxf/sts/common/CustomAttributeProvider.java b/services/sts/sts-core/src/test/java/org/apache/cxf/sts/common/CustomAttributeProvider.java
index b965b33..e3deba9 100644
--- a/services/sts/sts-core/src/test/java/org/apache/cxf/sts/common/CustomAttributeProvider.java
+++ b/services/sts/sts-core/src/test/java/org/apache/cxf/sts/common/CustomAttributeProvider.java
@@ -24,8 +24,7 @@ import java.util.List;
 
 import org.w3c.dom.Element;
 
-import org.apache.cxf.sts.claims.ClaimsManager;
-import org.apache.cxf.sts.claims.ClaimsParameters;
+import org.apache.cxf.sts.claims.ClaimsUtils;
 import org.apache.cxf.sts.claims.ProcessedClaim;
 import org.apache.cxf.sts.claims.ProcessedClaimCollection;
 import org.apache.cxf.sts.request.ReceivedToken;
@@ -57,27 +56,7 @@ public class CustomAttributeProvider implements AttributeStatementProvider {
         String tokenType = tokenRequirements.getTokenType();
         
         // Handle Claims
-        ClaimsManager claimsManager = providerParameters.getClaimsManager();
-        ProcessedClaimCollection retrievedClaims = new ProcessedClaimCollection();
-        if (claimsManager != null) {
-            ClaimsParameters params = new ClaimsParameters();
-            params.setAdditionalProperties(providerParameters.getAdditionalProperties());
-            params.setAppliesToAddress(providerParameters.getAppliesToAddress());
-            params.setEncryptionProperties(providerParameters.getEncryptionProperties());
-            params.setKeyRequirements(providerParameters.getKeyRequirements());
-            params.setPrincipal(providerParameters.getPrincipal());
-            params.setRealm(providerParameters.getRealm());
-            params.setStsProperties(providerParameters.getStsProperties());
-            params.setTokenRequirements(providerParameters.getTokenRequirements());
-            params.setTokenStore(providerParameters.getTokenStore());
-            params.setWebServiceContext(providerParameters.getWebServiceContext());
-            retrievedClaims = 
-                claimsManager.retrieveClaimValues(
-                    providerParameters.getRequestedPrimaryClaims(),
-                    providerParameters.getRequestedSecondaryClaims(),
-                    params
-                );
-        }
+        ProcessedClaimCollection retrievedClaims = ClaimsUtils.processClaims(providerParameters);
         
         AttributeStatementBean attrBean = new AttributeStatementBean();
         Iterator<ProcessedClaim> claimIterator = retrievedClaims.iterator();

http://git-wip-us.apache.org/repos/asf/cxf/blob/0966883a/services/sts/sts-core/src/test/java/org/apache/cxf/sts/operation/IssueSamlClaimsUnitTest.java
----------------------------------------------------------------------
diff --git a/services/sts/sts-core/src/test/java/org/apache/cxf/sts/operation/IssueSamlClaimsUnitTest.java b/services/sts/sts-core/src/test/java/org/apache/cxf/sts/operation/IssueSamlClaimsUnitTest.java
index 6eb6db6..d519348 100644
--- a/services/sts/sts-core/src/test/java/org/apache/cxf/sts/operation/IssueSamlClaimsUnitTest.java
+++ b/services/sts/sts-core/src/test/java/org/apache/cxf/sts/operation/IssueSamlClaimsUnitTest.java
@@ -33,6 +33,7 @@ import javax.xml.namespace.QName;
 
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
+import org.w3c.dom.Node;
 import org.apache.cxf.helpers.DOMUtils;
 import org.apache.cxf.jaxws.context.WebServiceContextImpl;
 import org.apache.cxf.jaxws.context.WrappedMessageContext;
@@ -273,6 +274,57 @@ public class IssueSamlClaimsUnitTest extends org.junit.Assert {
         assertTrue(tokenString.contains("AttributeStatement"));
         assertTrue(tokenString.contains("bob@custom"));
     }
+    
+    @org.junit.Test
+    public void testIssueTokenUnknownClaim() throws Exception {
+        TokenIssueOperation issueOperation = new TokenIssueOperation();
+        
+        // Add Token Provider
+        addTokenProvider(issueOperation);
+        
+        // Add Service
+        addService(issueOperation);
+        
+        // Add STSProperties object
+        addSTSProperties(issueOperation);
+        
+        // Set the ClaimsManager
+        ClaimsManager claimsManager = new ClaimsManager();
+        ClaimsHandler claimsHandler = new CustomClaimsHandler();
+        claimsManager.setClaimHandlers(Collections.singletonList(claimsHandler));
+        issueOperation.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);
+        
+        // Add a custom claim (unknown to the CustomClaimsHandler)
+        Element secondaryParameters = createSecondaryParameters();
+        Node claims = 
+            secondaryParameters.getElementsByTagNameNS(STSConstants.WST_NS_05_12, "Claims").item(0);
+        Element claimType = claims.getOwnerDocument().createElementNS(STSConstants.IDT_NS_05_05, "ClaimType");
+        claimType.setAttributeNS(
+            null, "Uri", ClaimTypes.COUNTRY.toString()
+        );
+        claimType.setAttributeNS(WSConstants.XMLNS_NS, "xmlns", STSConstants.IDT_NS_05_05);
+        claims.appendChild(claimType);
+        
+        request.getAny().add(secondaryParameters);
+        request.getAny().add(createAppliesToElement("http://dummy-service.com/dummy"));
+        
+        WebServiceContextImpl webServiceContext = setupMessageContext();
+        
+        try {
+            issueToken(issueOperation, request, webServiceContext);
+            fail("Failure expected on an unknown non-optional claims type");
+        } catch (Exception ex) {
+            // expected
+        }
+    }
 
     /**
      * @param issueOperation