Author: owulff
Date: Tue Apr 10 14:53:21 2012
New Revision: 1311767
URL: http://svn.apache.org/viewvc?rev=1311767&view=rev
Log:
[CXF-4212] Support RBAC in JAX-WS WebServiceContext based on received SAML token
Modified:
cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/SecurityConstants.java
cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/WSS4JInInterceptor.java
cxf/trunk/rt/ws/security/src/test/java/org/apache/cxf/ws/security/wss4j/saml/AbstractSAMLCallbackHandler.java
cxf/trunk/rt/ws/security/src/test/java/org/apache/cxf/ws/security/wss4j/saml/SAML2CallbackHandler.java
cxf/trunk/rt/ws/security/src/test/java/org/apache/cxf/ws/security/wss4j/saml/SamlTokenTest.java
Modified:
cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/SecurityConstants.java
URL:
http://svn.apache.org/viewvc/cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/SecurityConstants.java?rev=1311767&r1=1311766&r2=1311767&view=diff
==============================================================================
---
cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/SecurityConstants.java
(original)
+++
cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/SecurityConstants.java
Tue Apr 10 14:53:21 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
@@ -199,7 +206,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,
TOKEN_STORE_CACHE_INSTANCE
+ TIMESTAMP_CACHE_INSTANCE, CACHE_CONFIG_FILE,
TOKEN_STORE_CACHE_INSTANCE,
+ SAML_ROLE_ATTRIBUTENAME
}));
ALL_PROPERTIES = Collections.unmodifiableSet(s);
}
Modified:
cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/WSS4JInInterceptor.java
URL:
http://svn.apache.org/viewvc/cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/WSS4JInInterceptor.java?rev=1311767&r1=1311766&r2=1311767&view=diff
==============================================================================
---
cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/WSS4JInInterceptor.java
(original)
+++
cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/WSS4JInInterceptor.java
Tue Apr 10 14:53:21 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;
@@ -78,10 +81,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.
*
@@ -89,6 +96,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";
@@ -454,8 +468,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));
+ }
+ }
}
}
@@ -493,12 +526,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);
}
};
}
@@ -743,6 +783,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/trunk/rt/ws/security/src/test/java/org/apache/cxf/ws/security/wss4j/saml/AbstractSAMLCallbackHandler.java
URL:
http://svn.apache.org/viewvc/cxf/trunk/rt/ws/security/src/test/java/org/apache/cxf/ws/security/wss4j/saml/AbstractSAMLCallbackHandler.java?rev=1311767&r1=1311766&r2=1311767&view=diff
==============================================================================
---
cxf/trunk/rt/ws/security/src/test/java/org/apache/cxf/ws/security/wss4j/saml/AbstractSAMLCallbackHandler.java
(original)
+++
cxf/trunk/rt/ws/security/src/test/java/org/apache/cxf/ws/security/wss4j/saml/AbstractSAMLCallbackHandler.java
Tue Apr 10 14:53:21 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/trunk/rt/ws/security/src/test/java/org/apache/cxf/ws/security/wss4j/saml/SAML2CallbackHandler.java
URL:
http://svn.apache.org/viewvc/cxf/trunk/rt/ws/security/src/test/java/org/apache/cxf/ws/security/wss4j/saml/SAML2CallbackHandler.java?rev=1311767&r1=1311766&r2=1311767&view=diff
==============================================================================
---
cxf/trunk/rt/ws/security/src/test/java/org/apache/cxf/ws/security/wss4j/saml/SAML2CallbackHandler.java
(original)
+++
cxf/trunk/rt/ws/security/src/test/java/org/apache/cxf/ws/security/wss4j/saml/SAML2CallbackHandler.java
Tue Apr 10 14:53:21 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/trunk/rt/ws/security/src/test/java/org/apache/cxf/ws/security/wss4j/saml/SamlTokenTest.java
URL:
http://svn.apache.org/viewvc/cxf/trunk/rt/ws/security/src/test/java/org/apache/cxf/ws/security/wss4j/saml/SamlTokenTest.java?rev=1311767&r1=1311766&r2=1311767&view=diff
==============================================================================
---
cxf/trunk/rt/ws/security/src/test/java/org/apache/cxf/ws/security/wss4j/saml/SamlTokenTest.java
(original)
+++
cxf/trunk/rt/ws/security/src/test/java/org/apache/cxf/ws/security/wss4j/saml/SamlTokenTest.java
Tue Apr 10 14:53:21 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 {