cxf-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From owu...@apache.org
Subject svn commit: r1311787 - in /cxf/branches/2.5.x-fixes/rt/ws/security/src: main/java/org/apache/cxf/ws/security/ main/java/org/apache/cxf/ws/security/wss4j/ test/java/org/apache/cxf/ws/security/wss4j/saml/
Date Tue, 10 Apr 2012 15:27:08 GMT
Author: owulff
Date: Tue Apr 10 15:27:07 2012
New Revision: 1311787

URL: http://svn.apache.org/viewvc?rev=1311787&view=rev
Log:
[CXF-4212] Support RBAC in JAX-WS WebServiceContext based on received SAML token

Modified:
    cxf/branches/2.5.x-fixes/rt/ws/security/src/main/java/org/apache/cxf/ws/security/SecurityConstants.java
    cxf/branches/2.5.x-fixes/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/WSS4JInInterceptor.java
    cxf/branches/2.5.x-fixes/rt/ws/security/src/test/java/org/apache/cxf/ws/security/wss4j/saml/AbstractSAMLCallbackHandler.java
    cxf/branches/2.5.x-fixes/rt/ws/security/src/test/java/org/apache/cxf/ws/security/wss4j/saml/SAML2CallbackHandler.java
    cxf/branches/2.5.x-fixes/rt/ws/security/src/test/java/org/apache/cxf/ws/security/wss4j/saml/SamlTokenTest.java

Modified: cxf/branches/2.5.x-fixes/rt/ws/security/src/main/java/org/apache/cxf/ws/security/SecurityConstants.java
URL: http://svn.apache.org/viewvc/cxf/branches/2.5.x-fixes/rt/ws/security/src/main/java/org/apache/cxf/ws/security/SecurityConstants.java?rev=1311787&r1=1311786&r2=1311787&view=diff
==============================================================================
--- cxf/branches/2.5.x-fixes/rt/ws/security/src/main/java/org/apache/cxf/ws/security/SecurityConstants.java
(original)
+++ cxf/branches/2.5.x-fixes/rt/ws/security/src/main/java/org/apache/cxf/ws/security/SecurityConstants.java
Tue Apr 10 15:27:07 2012
@@ -91,6 +91,13 @@ public final class SecurityConstants {
      * constructed. The default is false.
      */
     public static final String SELF_SIGN_SAML_ASSERTION = "ws-security.self-sign-saml-assertion";
+
+    /**
+     * This configuration tag specifies the attribute URI of the SAML attributestatement
+     * where the role information is stored.
+     * The default is "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/role".
+     */
+    public static final String SAML_ROLE_ATTRIBUTENAME = "ws-security.saml-role-attributename";
     
     /**
      * WCF's trust server sometimes will encrypt the token in the response IN ADDITION TO
@@ -188,7 +195,8 @@ public final class SecurityConstants {
             KERBEROS_CLIENT, SCT_TOKEN_VALIDATOR, CACHE_ISSUED_TOKEN_IN_ENDPOINT,
             KERBEROS_JAAS_CONTEXT_NAME, KERBEROS_SPN, SPNEGO_CLIENT_ACTION,
             ENABLE_NONCE_CACHE, NONCE_CACHE_INSTANCE, ENABLE_TIMESTAMP_CACHE,
-            TIMESTAMP_CACHE_INSTANCE, CACHE_CONFIG_FILE
+            TIMESTAMP_CACHE_INSTANCE, CACHE_CONFIG_FILE,
+            SAML_ROLE_ATTRIBUTENAME
         }));
         ALL_PROPERTIES = Collections.unmodifiableSet(s);
     }

Modified: cxf/branches/2.5.x-fixes/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/WSS4JInInterceptor.java
URL: http://svn.apache.org/viewvc/cxf/branches/2.5.x-fixes/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/WSS4JInInterceptor.java?rev=1311787&r1=1311786&r2=1311787&view=diff
==============================================================================
--- cxf/branches/2.5.x-fixes/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/WSS4JInInterceptor.java
(original)
+++ cxf/branches/2.5.x-fixes/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/WSS4JInInterceptor.java
Tue Apr 10 15:27:07 2012
@@ -22,12 +22,15 @@ import java.io.IOException;
 import java.security.Principal;
 import java.util.ArrayList;
 import java.util.Collection;
+import java.util.Collections;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.logging.Level;
 import java.util.logging.Logger;
 
+
+
 import javax.security.auth.callback.Callback;
 import javax.security.auth.callback.CallbackHandler;
 import javax.security.auth.callback.UnsupportedCallbackException;
@@ -77,10 +80,14 @@ import org.apache.ws.security.handler.WS
 import org.apache.ws.security.handler.WSHandlerResult;
 import org.apache.ws.security.message.token.SecurityTokenReference;
 import org.apache.ws.security.processor.Processor;
+import org.apache.ws.security.saml.ext.AssertionWrapper;
 import org.apache.ws.security.util.WSSecurityUtil;
 import org.apache.ws.security.validate.NoOpValidator;
 import org.apache.ws.security.validate.Validator;
 
+import org.opensaml.common.SAMLVersion;
+import org.opensaml.xml.XMLObject;
+
 /**
  * Performs WS-Security inbound actions.
  * 
@@ -88,6 +95,13 @@ import org.apache.ws.security.validate.V
  */
 public class WSS4JInInterceptor extends AbstractWSS4JInterceptor {
 
+    /**
+     * This configuration tag specifies the default attribute name where the roles are present
+     * The default is "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/role".
+     */
+    public static final String SAML_ROLE_ATTRIBUTENAME_DEFAULT =
+        "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/role";
+    
     public static final String TIMESTAMP_RESULT = "wss4j.timestamp.result";
     public static final String SIGNATURE_RESULT = "wss4j.signature.result";
     public static final String PRINCIPAL_RESULT = "wss4j.principal.result";
@@ -444,8 +458,27 @@ public class WSS4JInInterceptor extends 
                 if (!utWithCallbacks) {
                     WSS4JTokenConverter.convertToken(msg, p);
                 }
-                msg.put(SecurityContext.class, createSecurityContext(p));
-            }            
+                AssertionWrapper receivedAssertion = null;
+                
+                List<String> roles = null;
+                if (o.get(WSSecurityEngineResult.TAG_SAML_ASSERTION) != null) {
+                    String roleAttributeName = (String)msg.getContextualProperty(
+                            SecurityConstants.SAML_ROLE_ATTRIBUTENAME);
+                    if (roleAttributeName == null || roleAttributeName.length() == 0) {
+                        roleAttributeName = SAML_ROLE_ATTRIBUTENAME_DEFAULT;
+                    }
+                    receivedAssertion = 
+                        (AssertionWrapper) o.get(WSSecurityEngineResult.TAG_SAML_ASSERTION);
+                    if (receivedAssertion.getSamlVersion().equals(SAMLVersion.VERSION_20))
{
+                        roles = this.parseRolesInAssertion(receivedAssertion.getSaml2(),
roleAttributeName);
+                    } else {
+                        roles = this.parseRolesInAssertion(receivedAssertion.getSaml1(),
roleAttributeName);
+                    }
+                    msg.put(SecurityContext.class, createSecurityContext(p, roles));
+                } else {
+                    msg.put(SecurityContext.class, createSecurityContext(p));
+                }
+            }
         }
     }
 
@@ -483,12 +516,19 @@ public class WSS4JInInterceptor extends 
     }
     
     protected SecurityContext createSecurityContext(final Principal p) {
+        return createSecurityContext(p, null);
+    }
+    
+    protected SecurityContext createSecurityContext(final Principal p, final List<String>
roles) {
         return new SecurityContext() {
             public Principal getUserPrincipal() {
                 return p;
             }
             public boolean isUserInRole(String role) {
-                return false;
+                if (roles == null) {
+                    return false;
+                }
+                return roles.contains(role);
             }
         };
     }
@@ -723,6 +763,80 @@ public class WSS4JInInterceptor extends 
         return fault;
     }
     
+    protected List<String> parseRolesInAssertion(org.opensaml.saml1.core.Assertion
assertion,
+            String roleAttributeName) {
+        List<org.opensaml.saml1.core.AttributeStatement> attributeStatements = 
+            assertion.getAttributeStatements();
+        if (attributeStatements == null || attributeStatements.isEmpty()) {
+            return null;
+        }
+        List<String> roles = new ArrayList<String>();
+        
+        for (org.opensaml.saml1.core.AttributeStatement statement : attributeStatements)
{
+            
+            List<org.opensaml.saml1.core.Attribute> attributes = statement.getAttributes();
+            for (org.opensaml.saml1.core.Attribute attribute : attributes) {
+                
+                if (attribute.getAttributeName().equals(roleAttributeName)) {
+                    for (XMLObject attributeValue : attribute.getAttributeValues()) {
+                        Element attributeValueElement = attributeValue.getDOM();
+                        String value = attributeValueElement.getTextContent();
+                        roles.add(value);                    
+                    }
+                    if (attribute.getAttributeValues().size() > 1) {
+//                        Don't search for other attributes with the same name if       
                 
+//                        <saml:Attribute xmlns:saml="urn:oasis:names:tc:SAML:1.0:assertion"
+//                             AttributeNamespace="http://schemas.xmlsoap.org/claims" AttributeName="roles">
+//                        <saml:AttributeValue>Value1</saml:AttributeValue>
+//                        <saml:AttributeValue>Value2</saml:AttributeValue>
+//                        </saml:Attribute>
+                        break;
+                    }
+                }
+                
+            }
+        }
+        return Collections.unmodifiableList(roles);
+    }
+    
+
+    protected List<String> parseRolesInAssertion(org.opensaml.saml2.core.Assertion
assertion,
+            String roleAttributeName) {
+        List<org.opensaml.saml2.core.AttributeStatement> attributeStatements = 
+            assertion.getAttributeStatements();
+        if (attributeStatements == null || attributeStatements.isEmpty()) {
+            return null;
+        }
+        List<String> roles = new ArrayList<String>();
+        
+        for (org.opensaml.saml2.core.AttributeStatement statement : attributeStatements)
{
+            
+            List<org.opensaml.saml2.core.Attribute> attributes = statement.getAttributes();
+            for (org.opensaml.saml2.core.Attribute attribute : attributes) {
+                
+                if (attribute.getName().equals(roleAttributeName)) {
+                    for (XMLObject attributeValue : attribute.getAttributeValues()) {
+                        Element attributeValueElement = attributeValue.getDOM();
+                        String value = attributeValueElement.getTextContent();
+                        roles.add(value);                    
+                    }
+                    if (attribute.getAttributeValues().size() > 1) {
+//                        Don't search for other attributes with the same name if       
                 
+//                        <saml:Attribute xmlns:saml="urn:oasis:names:tc:SAML:1.0:assertion"
+//                             AttributeNamespace="http://schemas.xmlsoap.org/claims" AttributeName="roles">
+//                        <saml:AttributeValue>Value1</saml:AttributeValue>
+//                        <saml:AttributeValue>Value2</saml:AttributeValue>
+//                        </saml:Attribute>
+                        break;
+                    }
+                }
+                
+            }
+        }
+        return Collections.unmodifiableList(roles);
+    }
+    
+    
     static class CXFRequestData extends RequestData {
         public CXFRequestData() {
         }

Modified: cxf/branches/2.5.x-fixes/rt/ws/security/src/test/java/org/apache/cxf/ws/security/wss4j/saml/AbstractSAMLCallbackHandler.java
URL: http://svn.apache.org/viewvc/cxf/branches/2.5.x-fixes/rt/ws/security/src/test/java/org/apache/cxf/ws/security/wss4j/saml/AbstractSAMLCallbackHandler.java?rev=1311787&r1=1311786&r2=1311787&view=diff
==============================================================================
--- cxf/branches/2.5.x-fixes/rt/ws/security/src/test/java/org/apache/cxf/ws/security/wss4j/saml/AbstractSAMLCallbackHandler.java
(original)
+++ cxf/branches/2.5.x-fixes/rt/ws/security/src/test/java/org/apache/cxf/ws/security/wss4j/saml/AbstractSAMLCallbackHandler.java
Tue Apr 10 15:27:07 2012
@@ -20,6 +20,7 @@
 package org.apache.cxf.ws.security.wss4j.saml;
 
 import java.security.cert.X509Certificate;
+import java.util.Arrays;
 import java.util.Collections;
 
 import javax.security.auth.callback.CallbackHandler;
@@ -58,6 +59,7 @@ public abstract class AbstractSAMLCallba
     protected Statement statement = Statement.AUTHN;
     protected CERT_IDENTIFIER certIdentifier = CERT_IDENTIFIER.X509_CERT;
     protected byte[] ephemeralKey;
+    protected boolean multiValue = true;
     
     public void setConfirmationMethod(String confMethod) {
         confirmationMethod = confMethod;
@@ -92,16 +94,53 @@ public abstract class AbstractSAMLCallba
             callback.setAuthenticationStatementData(Collections.singletonList(authBean));
         } else if (statement == Statement.ATTR) {
             AttributeStatementBean attrBean = new AttributeStatementBean();
-            AttributeBean attributeBean = new AttributeBean();
-            if (subjectBean != null) {
-                attrBean.setSubject(subjectBean);
-                attributeBean.setSimpleName("role");
-                attributeBean.setQualifiedName("http://custom-ns");
+            
+            if (multiValue) {
+//              <saml:Attribute xmlns:saml="urn:oasis:names:tc:SAML:1.0:assertion"
+//                AttributeNamespace="http://schemas.xmlsoap.org/claims" AttributeName="roles">
+//                <saml:AttributeValue>Value1</saml:AttributeValue>
+//                <saml:AttributeValue>Value2</saml:AttributeValue>
+//              </saml:Attribute>
+                AttributeBean attributeBean = new AttributeBean();
+                if (subjectBean != null) {
+                    attrBean.setSubject(subjectBean);
+                    attributeBean.setSimpleName("role");
+                    attributeBean.setQualifiedName("http://custom-ns");
+                } else {
+                    attributeBean.setQualifiedName("role");
+                }
+                attributeBean.setAttributeValues(Arrays.asList("user", "admin"));
+                attrBean.setSamlAttributes(Collections.singletonList(attributeBean));
             } else {
-                attributeBean.setQualifiedName("role");
+//              <saml:Attribute xmlns:saml="urn:oasis:names:tc:SAML:1.0:assertion"
+//                AttributeNamespace="http://schemas.xmlsoap.org/claims" AttributeName="roles">
+//                <saml:AttributeValue>Value1</saml:AttributeValue>
+//              </saml:Attribute>
+//              <saml:Attribute xmlns:saml="urn:oasis:names:tc:SAML:1.0:assertion"
+//                AttributeNamespace="http://schemas.xmlsoap.org/claims" AttributeName="roles">
+//                <saml:AttributeValue>Value2</saml:AttributeValue>
+//              </saml:Attribute>
+                AttributeBean attributeBean = new AttributeBean();
+                if (subjectBean != null) {
+                    attrBean.setSubject(subjectBean);
+                    attributeBean.setSimpleName("role");
+                    attributeBean.setQualifiedName("http://custom-ns");
+                } else {
+                    attributeBean.setQualifiedName("role");
+                }
+                attributeBean.setAttributeValues(Collections.singletonList("user"));
+                
+                AttributeBean attributeBean2 = new AttributeBean();
+                if (subjectBean != null) {
+                    attributeBean2.setSimpleName("role");
+                    attributeBean2.setQualifiedName("http://custom-ns");
+                } else {
+                    attributeBean2.setQualifiedName("role");
+                }
+                attributeBean2.setAttributeValues(Collections.singletonList("admin"));
+                attrBean.setSamlAttributes(Arrays.asList(attributeBean, attributeBean2));
             }
-            attributeBean.setAttributeValues(Collections.singletonList("user"));
-            attrBean.setSamlAttributes(Collections.singletonList(attributeBean));
+            
             callback.setAttributeStatementData(Collections.singletonList(attrBean));
         } else {
             AuthDecisionStatementBean authzBean = new AuthDecisionStatementBean();

Modified: cxf/branches/2.5.x-fixes/rt/ws/security/src/test/java/org/apache/cxf/ws/security/wss4j/saml/SAML2CallbackHandler.java
URL: http://svn.apache.org/viewvc/cxf/branches/2.5.x-fixes/rt/ws/security/src/test/java/org/apache/cxf/ws/security/wss4j/saml/SAML2CallbackHandler.java?rev=1311787&r1=1311786&r2=1311787&view=diff
==============================================================================
--- cxf/branches/2.5.x-fixes/rt/ws/security/src/test/java/org/apache/cxf/ws/security/wss4j/saml/SAML2CallbackHandler.java
(original)
+++ cxf/branches/2.5.x-fixes/rt/ws/security/src/test/java/org/apache/cxf/ws/security/wss4j/saml/SAML2CallbackHandler.java
Tue Apr 10 15:27:07 2012
@@ -52,6 +52,11 @@ public class SAML2CallbackHandler extend
         confirmationMethod = SAML2Constants.CONF_SENDER_VOUCHES;
     }
     
+    public SAML2CallbackHandler(boolean multivalue) throws Exception {
+        this();
+        this.multiValue = multivalue;
+    }
+    
     public void handle(Callback[] callbacks)
         throws IOException, UnsupportedCallbackException {
         for (int i = 0; i < callbacks.length; i++) {

Modified: cxf/branches/2.5.x-fixes/rt/ws/security/src/test/java/org/apache/cxf/ws/security/wss4j/saml/SamlTokenTest.java
URL: http://svn.apache.org/viewvc/cxf/branches/2.5.x-fixes/rt/ws/security/src/test/java/org/apache/cxf/ws/security/wss4j/saml/SamlTokenTest.java?rev=1311787&r1=1311786&r2=1311787&view=diff
==============================================================================
--- cxf/branches/2.5.x-fixes/rt/ws/security/src/test/java/org/apache/cxf/ws/security/wss4j/saml/SamlTokenTest.java
(original)
+++ cxf/branches/2.5.x-fixes/rt/ws/security/src/test/java/org/apache/cxf/ws/security/wss4j/saml/SamlTokenTest.java
Tue Apr 10 15:27:07 2012
@@ -44,12 +44,16 @@ import org.apache.cxf.helpers.XMLUtils;
 import org.apache.cxf.interceptor.Fault;
 import org.apache.cxf.message.Exchange;
 import org.apache.cxf.message.ExchangeImpl;
+import org.apache.cxf.message.Message;
 import org.apache.cxf.message.MessageImpl;
 import org.apache.cxf.phase.PhaseInterceptor;
+import org.apache.cxf.security.SecurityContext;
 import org.apache.cxf.staxutils.StaxUtils;
+import org.apache.cxf.ws.security.SecurityConstants;
 import org.apache.cxf.ws.security.wss4j.AbstractSecurityTest;
 import org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor;
 import org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor;
+import org.apache.cxf.ws.security.wss4j.saml.AbstractSAMLCallbackHandler.Statement;
 
 import org.apache.ws.security.WSConstants;
 import org.apache.ws.security.WSSecurityEngine;
@@ -96,8 +100,9 @@ public class SamlTokenTest extends Abstr
         xpaths.add("//wsse:Security");
         xpaths.add("//wsse:Security/saml1:Assertion");
 
-        List<WSHandlerResult> handlerResults = 
-            makeInvocation(outProperties, xpaths, inProperties);
+        Message message = makeInvocation(outProperties, xpaths, inProperties);
+        final List<WSHandlerResult> handlerResults = 
+            CastUtils.cast((List<?>)message.get(WSHandlerConstants.RECV_RESULTS));
         
         WSSecurityEngineResult actionResult =
             WSSecurityUtil.fetchActionResult(handlerResults.get(0).getResults(), WSConstants.ST_UNSIGNED);
@@ -133,8 +138,9 @@ public class SamlTokenTest extends Abstr
         xpaths.add("//wsse:Security");
         xpaths.add("//wsse:Security/saml2:Assertion");
 
-        List<WSHandlerResult> handlerResults = 
-            makeInvocation(outProperties, xpaths, inProperties);
+        Message message = makeInvocation(outProperties, xpaths, inProperties);
+        final List<WSHandlerResult> handlerResults = 
+            CastUtils.cast((List<?>)message.get(WSHandlerConstants.RECV_RESULTS));
         
         WSSecurityEngineResult actionResult =
             WSSecurityUtil.fetchActionResult(handlerResults.get(0).getResults(), WSConstants.ST_UNSIGNED);
@@ -176,8 +182,9 @@ public class SamlTokenTest extends Abstr
         xpaths.add("//wsse:Security");
         xpaths.add("//wsse:Security/saml1:Assertion");
 
-        List<WSHandlerResult> handlerResults = 
-            makeInvocation(outProperties, xpaths, inProperties);
+        Message message = makeInvocation(outProperties, xpaths, inProperties);
+        final List<WSHandlerResult> handlerResults = 
+            CastUtils.cast((List<?>)message.get(WSHandlerConstants.RECV_RESULTS));
         
         WSSecurityEngineResult actionResult =
             WSSecurityUtil.fetchActionResult(handlerResults.get(0).getResults(), WSConstants.ST_UNSIGNED);
@@ -224,8 +231,9 @@ public class SamlTokenTest extends Abstr
         xpaths.add("//wsse:Security");
         xpaths.add("//wsse:Security/saml2:Assertion");
 
-        List<WSHandlerResult> handlerResults = 
-            makeInvocation(outProperties, xpaths, inProperties);
+        Message message = makeInvocation(outProperties, xpaths, inProperties);
+        final List<WSHandlerResult> handlerResults = 
+            CastUtils.cast((List<?>)message.get(WSHandlerConstants.RECV_RESULTS));
         
         WSSecurityEngineResult actionResult =
             WSSecurityUtil.fetchActionResult(handlerResults.get(0).getResults(), WSConstants.ST_UNSIGNED);
@@ -283,8 +291,9 @@ public class SamlTokenTest extends Abstr
         }
         validator.setRequireSenderVouches(false);
 
-        List<WSHandlerResult> handlerResults = 
-            makeInvocation(outProperties, xpaths, inProperties);
+        Message message = makeInvocation(outProperties, xpaths, inProperties);
+        final List<WSHandlerResult> handlerResults = 
+            CastUtils.cast((List<?>)message.get(WSHandlerConstants.RECV_RESULTS));
         
         WSSecurityEngineResult actionResult =
             WSSecurityUtil.fetchActionResult(handlerResults.get(0).getResults(), WSConstants.ST_SIGNED);
@@ -349,8 +358,9 @@ public class SamlTokenTest extends Abstr
         }
         validator.setRequireSAML1Assertion(false);
 
-        List<WSHandlerResult> handlerResults = 
-            makeInvocation(outProperties, xpaths, inProperties);
+        Message message = makeInvocation(outProperties, xpaths, inProperties);
+        final List<WSHandlerResult> handlerResults = 
+            CastUtils.cast((List<?>)message.get(WSHandlerConstants.RECV_RESULTS));
         
         WSSecurityEngineResult actionResult =
             WSSecurityUtil.fetchActionResult(handlerResults.get(0).getResults(), WSConstants.ST_SIGNED);
@@ -364,7 +374,147 @@ public class SamlTokenTest extends Abstr
         assertTrue(actionResult != null);
     }
     
-    private List<WSHandlerResult> makeInvocation(
+    /**
+     * This test creates a SAML2 Assertion and sends it in the security header to the provider.
+     * An single attribute is created for the roles but multiple attribute value elements.
+     */
+    @Test
+    public void testSaml2TokenWithRoles() throws Exception {
+        Map<String, Object> outProperties = new HashMap<String, Object>();
+        outProperties.put(WSHandlerConstants.ACTION, WSHandlerConstants.SAML_TOKEN_UNSIGNED);
+        outProperties.put(WSHandlerConstants.SAML_PROP_FILE, "saml_sv.properties");
+        
+        SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
+        callbackHandler.setStatement(Statement.ATTR);
+        outProperties.put(
+            WSHandlerConstants.SAML_CALLBACK_REF, callbackHandler
+        );
+        
+        Map<String, Object> inProperties = new HashMap<String, Object>();
+        inProperties.put(WSHandlerConstants.ACTION, WSHandlerConstants.SAML_TOKEN_UNSIGNED);
+        final Map<QName, Object> customMap = new HashMap<QName, Object>();
+        CustomSamlValidator validator = new CustomSamlValidator();
+        validator.setRequireSAML1Assertion(false);
+        customMap.put(WSSecurityEngine.SAML_TOKEN, validator);
+        customMap.put(WSSecurityEngine.SAML2_TOKEN, validator);
+        inProperties.put(WSS4JInInterceptor.VALIDATOR_MAP, customMap);
+        
+        
+        List<String> xpaths = new ArrayList<String>();
+        xpaths.add("//wsse:Security");
+        xpaths.add("//wsse:Security/saml2:Assertion");
+
+        Message message = makeInvocation(outProperties, xpaths, inProperties);
+        final List<WSHandlerResult> handlerResults = 
+            CastUtils.cast((List<?>)message.get(WSHandlerConstants.RECV_RESULTS));
+        
+        SecurityContext sc = message.get(SecurityContext.class);
+        assertNotNull(sc);
+        assertTrue(sc.isUserInRole("user"));
+        assertTrue(sc.isUserInRole("admin"));
+        
+        WSSecurityEngineResult actionResult =
+            WSSecurityUtil.fetchActionResult(handlerResults.get(0).getResults(), WSConstants.ST_UNSIGNED);
+        AssertionWrapper receivedAssertion = 
+            (AssertionWrapper) actionResult.get(WSSecurityEngineResult.TAG_SAML_ASSERTION);
+        assertTrue(receivedAssertion != null && receivedAssertion.getSaml2() != null);
+        assert !receivedAssertion.isSigned();
+    }
+    
+    /**
+     * This test creates a SAML2 Assertion and sends it in the security header to the provider.
+     * An attribute is created per role. There are several attributes with the same name.
+     */
+    @Test
+    public void testSaml2TokenWithRolesSingleValue() throws Exception {
+        Map<String, Object> outProperties = new HashMap<String, Object>();
+        outProperties.put(WSHandlerConstants.ACTION, WSHandlerConstants.SAML_TOKEN_UNSIGNED);
+        outProperties.put(WSHandlerConstants.SAML_PROP_FILE, "saml_sv.properties");
+        
+        SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler(false);
+        callbackHandler.setStatement(Statement.ATTR);
+        outProperties.put(
+            WSHandlerConstants.SAML_CALLBACK_REF, callbackHandler
+        );
+        
+        Map<String, Object> inProperties = new HashMap<String, Object>();
+        inProperties.put(WSHandlerConstants.ACTION, WSHandlerConstants.SAML_TOKEN_UNSIGNED);
+        final Map<QName, Object> customMap = new HashMap<QName, Object>();
+        CustomSamlValidator validator = new CustomSamlValidator();
+        validator.setRequireSAML1Assertion(false);
+        customMap.put(WSSecurityEngine.SAML_TOKEN, validator);
+        customMap.put(WSSecurityEngine.SAML2_TOKEN, validator);
+        inProperties.put(WSS4JInInterceptor.VALIDATOR_MAP, customMap);
+        
+        
+        List<String> xpaths = new ArrayList<String>();
+        xpaths.add("//wsse:Security");
+        xpaths.add("//wsse:Security/saml2:Assertion");
+
+        Message message = makeInvocation(outProperties, xpaths, inProperties);
+        final List<WSHandlerResult> handlerResults = 
+            CastUtils.cast((List<?>)message.get(WSHandlerConstants.RECV_RESULTS));
+        
+        SecurityContext sc = message.get(SecurityContext.class);
+        assertNotNull(sc);
+        assertTrue(sc.isUserInRole("user"));
+        assertTrue(sc.isUserInRole("admin"));
+        
+        WSSecurityEngineResult actionResult =
+            WSSecurityUtil.fetchActionResult(handlerResults.get(0).getResults(), WSConstants.ST_UNSIGNED);
+        AssertionWrapper receivedAssertion = 
+            (AssertionWrapper) actionResult.get(WSSecurityEngineResult.TAG_SAML_ASSERTION);
+        assertTrue(receivedAssertion != null && receivedAssertion.getSaml2() != null);
+        assert !receivedAssertion.isSigned();
+    }
+    
+    /**
+     * This test creates a SAML1 Assertion and sends it in the security header to the provider.
+     */
+    @Test
+    //@Ignore
+    public void testSaml1TokenWithRoles() throws Exception {
+        Map<String, Object> outProperties = new HashMap<String, Object>();
+        outProperties.put(WSHandlerConstants.ACTION, WSHandlerConstants.SAML_TOKEN_UNSIGNED);
+        outProperties.put(WSHandlerConstants.SAML_PROP_FILE, "saml_sv.properties");
+        
+        SAML1CallbackHandler callbackHandler = new SAML1CallbackHandler();
+        callbackHandler.setStatement(Statement.ATTR);
+        outProperties.put(
+            WSHandlerConstants.SAML_CALLBACK_REF, callbackHandler
+        );
+        
+        Map<String, Object> inProperties = new HashMap<String, Object>();
+        inProperties.put(WSHandlerConstants.ACTION, WSHandlerConstants.SAML_TOKEN_UNSIGNED);
+        final Map<QName, Object> customMap = new HashMap<QName, Object>();
+        CustomSamlValidator validator = new CustomSamlValidator();
+        customMap.put(WSSecurityEngine.SAML_TOKEN, validator);
+        customMap.put(WSSecurityEngine.SAML2_TOKEN, validator);
+        inProperties.put(WSS4JInInterceptor.VALIDATOR_MAP, customMap);
+        
+        
+        List<String> xpaths = new ArrayList<String>();
+        xpaths.add("//wsse:Security");
+        xpaths.add("//wsse:Security/saml1:Assertion");
+
+        Message message = makeInvocation(outProperties, xpaths, inProperties);
+        final List<WSHandlerResult> handlerResults = 
+            CastUtils.cast((List<?>)message.get(WSHandlerConstants.RECV_RESULTS));
+        
+        SecurityContext sc = message.get(SecurityContext.class);
+        assertNotNull(sc);
+        assertTrue(sc.isUserInRole("user"));
+        assertTrue(sc.isUserInRole("admin"));
+        
+        WSSecurityEngineResult actionResult =
+            WSSecurityUtil.fetchActionResult(handlerResults.get(0).getResults(), WSConstants.ST_UNSIGNED);
+        AssertionWrapper receivedAssertion = 
+            (AssertionWrapper) actionResult.get(WSSecurityEngineResult.TAG_SAML_ASSERTION);
+        assertTrue(receivedAssertion != null && receivedAssertion.getSaml1() != null);
+        assert !receivedAssertion.isSigned();
+    }
+    
+    private SoapMessage makeInvocation(
         Map<String, Object> outProperties,
         List<String> xpaths,
         Map<String, Object> inProperties
@@ -414,14 +564,13 @@ public class SamlTokenTest extends Abstr
         WSS4JInInterceptor inHandler = new WSS4JInInterceptor(inProperties);
 
         SoapMessage inmsg = new SoapMessage(new MessageImpl());
+        inmsg.put(SecurityConstants.SAML_ROLE_ATTRIBUTENAME, "role");
         ex.setInMessage(inmsg);
         inmsg.setContent(SOAPMessage.class, saajMsg);
 
         inHandler.handleMessage(inmsg);
 
-        final List<WSHandlerResult> handlerResults = 
-            CastUtils.cast((List<?>)inmsg.get(WSHandlerConstants.RECV_RESULTS));
-        return handlerResults;
+        return inmsg;
     }
     
     private byte[] getMessageBytes(Document doc) throws Exception {



Mime
View raw message