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 2013/09/05 12:38:30 UTC
svn commit: r1520272 - in /cxf/trunk/services/sts:
sts-core/src/main/java/org/apache/cxf/sts/operation/
sts-core/src/main/java/org/apache/cxf/sts/request/
sts-core/src/test/java/org/apache/cxf/sts/operation/
systests/advanced/src/test/resources/org/apa...
Author: coheigea
Date: Thu Sep 5 10:38:30 2013
New Revision: 1520272
URL: http://svn.apache.org/r1520272
Log:
[CXF-5251] - Implement more stringent requirements on allowing OnBehalfOf/ActAs in the STS
Added:
cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/request/DefaultDelegationHandler.java
cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/request/DelegationHandler.java
cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/request/HOKDelegationHandler.java
cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/request/UsernameTokenDelegationHandler.java
cxf/trunk/services/sts/systests/basic/src/test/java/org/apache/cxf/systest/sts/common/HOKDelegationHandler.java
Modified:
cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/operation/AbstractOperation.java
cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/operation/TokenIssueOperation.java
cxf/trunk/services/sts/sts-core/src/test/java/org/apache/cxf/sts/operation/IssueOnbehalfofUnitTest.java
cxf/trunk/services/sts/systests/advanced/src/test/resources/org/apache/cxf/systest/sts/deployment/cxf-sts.xml
cxf/trunk/services/sts/systests/basic/src/test/java/org/apache/cxf/systest/sts/issueunit/IssueUnitTest.java
cxf/trunk/services/sts/systests/basic/src/test/resources/org/apache/cxf/systest/sts/deployment/cxf-transport.xml
cxf/trunk/services/sts/systests/basic/src/test/resources/org/apache/cxf/systest/sts/deployment/cxf-x509.xml
Modified: cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/operation/AbstractOperation.java
URL: http://svn.apache.org/viewvc/cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/operation/AbstractOperation.java?rev=1520272&r1=1520271&r2=1520272&view=diff
==============================================================================
--- cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/operation/AbstractOperation.java (original)
+++ cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/operation/AbstractOperation.java Thu Sep 5 10:38:30 2013
@@ -36,7 +36,6 @@ import javax.xml.ws.handler.MessageConte
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.sts.IdentityMapper;
@@ -49,6 +48,8 @@ import org.apache.cxf.sts.claims.Request
import org.apache.cxf.sts.claims.RequestClaimCollection;
import org.apache.cxf.sts.event.AbstractSTSEvent;
import org.apache.cxf.sts.event.STSEventListener;
+import org.apache.cxf.sts.request.DefaultDelegationHandler;
+import org.apache.cxf.sts.request.DelegationHandler;
import org.apache.cxf.sts.request.KeyRequirements;
import org.apache.cxf.sts.request.ReceivedToken;
import org.apache.cxf.sts.request.ReceivedToken.STATE;
@@ -102,7 +103,16 @@ public abstract class AbstractOperation
protected TokenStore tokenStore;
protected ClaimsManager claimsManager = new ClaimsManager();
protected STSEventListener eventPublisher;
+ protected DelegationHandler delegationHandler = new DefaultDelegationHandler();
+ public DelegationHandler getDelegationHandler() {
+ return delegationHandler;
+ }
+
+ public void setDelegationHandler(DelegationHandler delegationHandler) {
+ this.delegationHandler = delegationHandler;
+ }
+
public boolean isReturnReferences() {
return returnReferences;
}
@@ -609,7 +619,6 @@ public abstract class AbstractOperation
Relationship.class.getName(), relationship);
}
}
-
if (relationship == null || relationship.getType().equals(Relationship.FED_TYPE_IDENTITY)) {
// federate identity
IdentityMapper identityMapper = null;
Modified: cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/operation/TokenIssueOperation.java
URL: http://svn.apache.org/viewvc/cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/operation/TokenIssueOperation.java?rev=1520272&r1=1520271&r2=1520272&view=diff
==============================================================================
--- cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/operation/TokenIssueOperation.java (original)
+++ cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/operation/TokenIssueOperation.java Thu Sep 5 10:38:30 2013
@@ -143,6 +143,15 @@ public class TokenIssueOperation extends
providerParameters.setPrincipal(wssecToken.getPrincipal());
}
}
+
+ if (delegationHandler != null) {
+ String appliesToAddress = extractAddressFromAppliesTo(tokenRequirements.getAppliesTo());
+ if (!delegationHandler.isDelegationAllowed(context, tokenRequirements, appliesToAddress)) {
+ LOG.fine("Token Delegation (OnBehalfOf/ActAs) is not allowed for this particular token");
+ throw new STSException("Token Delegation (OnBehalfOf/ActAs) is not allowed",
+ STSException.REQUEST_FAILED);
+ }
+ }
// Validate OnBehalfOf token if present
if (providerParameters.getTokenRequirements().getOnBehalfOf() != null) {
Added: cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/request/DefaultDelegationHandler.java
URL: http://svn.apache.org/viewvc/cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/request/DefaultDelegationHandler.java?rev=1520272&view=auto
==============================================================================
--- cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/request/DefaultDelegationHandler.java (added)
+++ cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/request/DefaultDelegationHandler.java Thu Sep 5 10:38:30 2013
@@ -0,0 +1,151 @@
+/**
+ * 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.request;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import javax.xml.ws.WebServiceContext;
+
+import org.w3c.dom.Element;
+import org.apache.cxf.common.logging.LogUtils;
+import org.apache.wss4j.common.ext.WSSecurityException;
+import org.apache.wss4j.common.saml.SamlAssertionWrapper;
+import org.apache.wss4j.common.saml.builder.SAML1Constants;
+import org.apache.wss4j.common.saml.builder.SAML2Constants;
+import org.apache.wss4j.dom.WSConstants;
+import org.opensaml.saml1.core.AudienceRestrictionCondition;
+
+
+/**
+ * The Default DelegationHandler implementation. It disallows ActAs or OnBehalfOf for
+ * all cases apart from the case of a Bearer SAML Token. In addition, the AppliesTo
+ * address (if supplied) must match an AudienceRestriction address (if in token)
+ */
+public class DefaultDelegationHandler implements DelegationHandler {
+
+ private static final Logger LOG =
+ LogUtils.getL7dLogger(DefaultDelegationHandler.class);
+
+ /**
+ * Returns true if delegation is allowed.
+ * @param context WebServiceContext
+ * @param tokenRequirements The parameters extracted from the request
+ * @param appliesToAddress The AppliesTo address (if any)
+ * @param onBehalfOf whether the token was received OnBehalfOf or ActAs
+ * @return true if delegation is allowed.
+ */
+ public boolean isDelegationAllowed(
+ WebServiceContext context,
+ TokenRequirements tokenRequirements,
+ String appliesToAddress
+ ) {
+ if (tokenRequirements.getOnBehalfOf() != null
+ && !isDelegationAllowed(context, tokenRequirements.getOnBehalfOf(), appliesToAddress)) {
+ return false;
+ }
+
+ if (tokenRequirements.getActAs() != null
+ && !isDelegationAllowed(context, tokenRequirements.getActAs(), appliesToAddress)) {
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * Is Delegation allowed for a particular token
+ */
+ protected boolean isDelegationAllowed(
+ WebServiceContext context,
+ ReceivedToken receivedToken,
+ String appliesToAddress
+ ) {
+ // It must be a SAML Token
+ if (!isSAMLToken(receivedToken)) {
+ LOG.fine("Received token is not a SAML Token");
+ return false;
+ }
+
+ Element validateTargetElement = (Element)receivedToken.getToken();
+ try {
+ SamlAssertionWrapper assertion = new SamlAssertionWrapper(validateTargetElement);
+
+ for (String confirmationMethod : assertion.getConfirmationMethods()) {
+ if (!(SAML1Constants.CONF_BEARER.equals(confirmationMethod)
+ || SAML2Constants.CONF_BEARER.equals(confirmationMethod))) {
+ LOG.fine("An unsupported Confirmation Method was used: " + confirmationMethod);
+ return false;
+ }
+ }
+
+ if (appliesToAddress != null) {
+ List<String> addresses = getAudienceRestrictions(assertion);
+ if (!(addresses.isEmpty() || addresses.contains(appliesToAddress))) {
+ LOG.fine("The AppliesTo address " + appliesToAddress + " is not contained"
+ + " in the Audience Restriction addresses in the assertion");
+ return false;
+ }
+ }
+ } catch (WSSecurityException ex) {
+ LOG.log(Level.WARNING, "Error in ascertaining whether delegation is allowed", ex);
+ return false;
+ }
+
+ return true;
+ }
+
+ protected boolean isSAMLToken(ReceivedToken target) {
+ Object token = target.getToken();
+ if (token instanceof Element) {
+ Element tokenElement = (Element)token;
+ String namespace = tokenElement.getNamespaceURI();
+ String localname = tokenElement.getLocalName();
+ if ((WSConstants.SAML_NS.equals(namespace) || WSConstants.SAML2_NS.equals(namespace))
+ && "Assertion".equals(localname)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ protected List<String> getAudienceRestrictions(SamlAssertionWrapper assertion) {
+ List<String> addresses = new ArrayList<String>();
+ if (assertion.getSaml1() != null) {
+ for (AudienceRestrictionCondition restriction
+ : assertion.getSaml1().getConditions().getAudienceRestrictionConditions()) {
+ for (org.opensaml.saml1.core.Audience audience : restriction.getAudiences()) {
+ addresses.add(audience.getUri());
+ }
+ }
+ } else if (assertion.getSaml2() != null) {
+ for (org.opensaml.saml2.core.AudienceRestriction restriction
+ : assertion.getSaml2().getConditions().getAudienceRestrictions()) {
+ for (org.opensaml.saml2.core.Audience audience : restriction.getAudiences()) {
+ addresses.add(audience.getAudienceURI());
+ }
+ }
+ }
+
+ return addresses;
+ }
+
+}
\ No newline at end of file
Added: cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/request/DelegationHandler.java
URL: http://svn.apache.org/viewvc/cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/request/DelegationHandler.java?rev=1520272&view=auto
==============================================================================
--- cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/request/DelegationHandler.java (added)
+++ cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/request/DelegationHandler.java Thu Sep 5 10:38:30 2013
@@ -0,0 +1,44 @@
+/**
+ * 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.request;
+
+import javax.xml.ws.WebServiceContext;
+
+
+/**
+ * This interface controls whether the STS allows an authenticated user to get a token
+ * OnBehalfOf or ActAs another token. The tokens should be taken from the TokenRequirements
+ * object passed as a parameter.
+ */
+public interface DelegationHandler {
+
+ /**
+ * Returns true if delegation is allowed.
+ * @param context WebServiceContext
+ * @param tokenRequirements The parameters extracted from the request
+ * @param appliesToAddress The AppliesTo address (if any)
+ * @return true if delegation is allowed.
+ */
+ boolean isDelegationAllowed(
+ WebServiceContext context,
+ TokenRequirements tokenRequirements,
+ String appliesToAddress
+ );
+
+}
\ No newline at end of file
Added: cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/request/HOKDelegationHandler.java
URL: http://svn.apache.org/viewvc/cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/request/HOKDelegationHandler.java?rev=1520272&view=auto
==============================================================================
--- cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/request/HOKDelegationHandler.java (added)
+++ cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/request/HOKDelegationHandler.java Thu Sep 5 10:38:30 2013
@@ -0,0 +1,85 @@
+/**
+ * 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.request;
+
+import java.util.List;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import javax.xml.ws.WebServiceContext;
+
+import org.w3c.dom.Element;
+
+import org.apache.cxf.common.logging.LogUtils;
+import org.apache.wss4j.common.ext.WSSecurityException;
+import org.apache.wss4j.common.saml.SamlAssertionWrapper;
+import org.apache.wss4j.common.saml.builder.SAML1Constants;
+import org.apache.wss4j.common.saml.builder.SAML2Constants;
+
+/**
+ * This DelegationHandler implementation extends the Default implementation to allow SAML
+ * Tokens with HolderOfKey Subject Confirmation.
+ */
+public class HOKDelegationHandler extends DefaultDelegationHandler {
+
+ private static final Logger LOG =
+ LogUtils.getL7dLogger(HOKDelegationHandler.class);
+
+ /**
+ * Is Delegation allowed for a particular token
+ */
+ @Override
+ protected boolean isDelegationAllowed(
+ WebServiceContext context,
+ ReceivedToken receivedToken,
+ String appliesToAddress
+ ) {
+ // It must be a SAML Token
+ if (!isSAMLToken(receivedToken)) {
+ return false;
+ }
+
+ Element validateTargetElement = (Element)receivedToken.getToken();
+ try {
+ SamlAssertionWrapper assertion = new SamlAssertionWrapper(validateTargetElement);
+
+ for (String confirmationMethod : assertion.getConfirmationMethods()) {
+ if (!(SAML1Constants.CONF_BEARER.equals(confirmationMethod)
+ || SAML1Constants.CONF_HOLDER_KEY.equals(confirmationMethod)
+ || SAML2Constants.CONF_BEARER.equals(confirmationMethod)
+ || SAML2Constants.CONF_HOLDER_KEY.equals(confirmationMethod))) {
+ return false;
+ }
+ }
+
+ if (appliesToAddress != null) {
+ List<String> addresses = getAudienceRestrictions(assertion);
+ if (!(addresses.isEmpty() || addresses.contains(appliesToAddress))) {
+ return false;
+ }
+ }
+ } catch (WSSecurityException ex) {
+ LOG.log(Level.WARNING, "Error in ascertaining whether delegation is allowed", ex);
+ return false;
+ }
+
+ return true;
+ }
+
+}
\ No newline at end of file
Added: cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/request/UsernameTokenDelegationHandler.java
URL: http://svn.apache.org/viewvc/cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/request/UsernameTokenDelegationHandler.java?rev=1520272&view=auto
==============================================================================
--- cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/request/UsernameTokenDelegationHandler.java (added)
+++ cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/request/UsernameTokenDelegationHandler.java Thu Sep 5 10:38:30 2013
@@ -0,0 +1,79 @@
+/**
+ * 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.request;
+
+import java.util.List;
+
+import javax.xml.ws.WebServiceContext;
+
+import org.w3c.dom.Element;
+
+import org.apache.wss4j.common.ext.WSSecurityException;
+import org.apache.wss4j.common.saml.SamlAssertionWrapper;
+import org.apache.wss4j.common.saml.builder.SAML1Constants;
+import org.apache.wss4j.common.saml.builder.SAML2Constants;
+
+/**
+ * This DelegationHandler implementation extends the Default implementation to allow UsernameTokens
+ * for OnBehalfOf/ActAs
+ */
+public class UsernameTokenDelegationHandler extends DefaultDelegationHandler {
+
+ /**
+ * Is Delegation allowed for a particular token
+ */
+ protected boolean isDelegationAllowed(
+ WebServiceContext context,
+ ReceivedToken receivedToken,
+ String appliesToAddress
+ ) {
+ if (receivedToken.isUsernameToken()) {
+ return true;
+ }
+
+ // It must be a SAML Token
+ if (!isSAMLToken(receivedToken)) {
+ return false;
+ }
+
+ Element validateTargetElement = (Element)receivedToken.getToken();
+ try {
+ SamlAssertionWrapper assertion = new SamlAssertionWrapper(validateTargetElement);
+
+ for (String confirmationMethod : assertion.getConfirmationMethods()) {
+ if (!(SAML1Constants.CONF_BEARER.equals(confirmationMethod)
+ || SAML2Constants.CONF_BEARER.equals(confirmationMethod))) {
+ return false;
+ }
+ }
+
+ if (appliesToAddress != null) {
+ List<String> addresses = getAudienceRestrictions(assertion);
+ if (!(addresses.isEmpty() || addresses.contains(appliesToAddress))) {
+ return false;
+ }
+ }
+ } catch (WSSecurityException ex) {
+ return false;
+ }
+
+ return true;
+ }
+
+}
\ No newline at end of file
Modified: cxf/trunk/services/sts/sts-core/src/test/java/org/apache/cxf/sts/operation/IssueOnbehalfofUnitTest.java
URL: http://svn.apache.org/viewvc/cxf/trunk/services/sts/sts-core/src/test/java/org/apache/cxf/sts/operation/IssueOnbehalfofUnitTest.java?rev=1520272&r1=1520271&r2=1520272&view=diff
==============================================================================
--- cxf/trunk/services/sts/sts-core/src/test/java/org/apache/cxf/sts/operation/IssueOnbehalfofUnitTest.java (original)
+++ cxf/trunk/services/sts/sts-core/src/test/java/org/apache/cxf/sts/operation/IssueOnbehalfofUnitTest.java Thu Sep 5 10:38:30 2013
@@ -19,6 +19,7 @@
package org.apache.cxf.sts.operation;
import java.security.Principal;
+import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
@@ -32,7 +33,6 @@ import javax.xml.namespace.QName;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
-
import org.apache.cxf.helpers.DOMUtils;
import org.apache.cxf.jaxws.context.WebServiceContextImpl;
import org.apache.cxf.jaxws.context.WrappedMessageContext;
@@ -48,8 +48,11 @@ import org.apache.cxf.sts.claims.ClaimsH
import org.apache.cxf.sts.claims.ClaimsManager;
import org.apache.cxf.sts.common.CustomUserClaimsHandler;
import org.apache.cxf.sts.common.PasswordCallbackHandler;
+import org.apache.cxf.sts.request.HOKDelegationHandler;
import org.apache.cxf.sts.request.KeyRequirements;
+import org.apache.cxf.sts.request.ReceivedKey;
import org.apache.cxf.sts.request.TokenRequirements;
+import org.apache.cxf.sts.request.UsernameTokenDelegationHandler;
import org.apache.cxf.sts.service.EncryptionProperties;
import org.apache.cxf.sts.service.ServiceMBean;
import org.apache.cxf.sts.service.StaticService;
@@ -75,6 +78,7 @@ import org.apache.cxf.ws.security.sts.pr
import org.apache.cxf.ws.security.sts.provider.model.secext.UsernameTokenType;
import org.apache.wss4j.common.crypto.Crypto;
import org.apache.wss4j.common.crypto.CryptoFactory;
+import org.apache.wss4j.common.crypto.CryptoType;
import org.apache.wss4j.common.ext.WSSecurityException;
import org.apache.wss4j.common.principal.CustomTokenPrincipal;
import org.apache.wss4j.common.saml.SamlAssertionWrapper;
@@ -160,6 +164,550 @@ public class IssueOnbehalfofUnitTest ext
assertTrue(!securityTokenResponse.isEmpty());
}
+ /**
+ * Test to successfully issue a SAML 2 token on-behalf-of a SAML 1 token
+ */
+ @org.junit.Test
+ public void testIssueSaml2TokenOnBehalfOfSaml1() throws Exception {
+ TokenIssueOperation issueOperation = new TokenIssueOperation();
+
+ // Add Token Provider
+ List<TokenProvider> providerList = new ArrayList<TokenProvider>();
+ providerList.add(new SAMLTokenProvider());
+ issueOperation.setTokenProviders(providerList);
+
+ // Add Token Validator
+ List<TokenValidator> validatorList = new ArrayList<TokenValidator>();
+ validatorList.add(new SAMLTokenValidator());
+ issueOperation.setTokenValidators(validatorList);
+
+ // Add Service
+ ServiceMBean service = new StaticService();
+ service.setEndpoints(Collections.singletonList("http://dummy-service.com/dummy"));
+ issueOperation.setServices(Collections.singletonList(service));
+
+ // Add STSProperties object
+ STSPropertiesMBean stsProperties = new StaticSTSProperties();
+ Crypto crypto = CryptoFactory.getInstance(getEncryptionProperties());
+ stsProperties.setEncryptionCrypto(crypto);
+ stsProperties.setSignatureCrypto(crypto);
+ stsProperties.setEncryptionUsername("myservicekey");
+ stsProperties.setSignatureUsername("mystskey");
+ stsProperties.setCallbackHandler(new PasswordCallbackHandler());
+ stsProperties.setIssuer("STS");
+ issueOperation.setStsProperties(stsProperties);
+
+ // 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);
+
+ // Get a SAML Token via the SAMLTokenProvider
+ CallbackHandler callbackHandler = new PasswordCallbackHandler();
+ Element samlToken =
+ createSAMLAssertion(WSConstants.WSS_SAML_TOKEN_TYPE, crypto, "mystskey", callbackHandler);
+ Document doc = samlToken.getOwnerDocument();
+ samlToken = (Element)doc.appendChild(samlToken);
+ OnBehalfOfType onbehalfof = new OnBehalfOfType();
+ onbehalfof.setAny(samlToken);
+
+ JAXBElement<OnBehalfOfType> onbehalfofType =
+ new JAXBElement<OnBehalfOfType>(
+ QNameConstants.ON_BEHALF_OF, OnBehalfOfType.class, onbehalfof
+ );
+ request.getAny().add(onbehalfofType);
+
+ // Mock up message context
+ MessageImpl msg = new MessageImpl();
+ WrappedMessageContext msgCtx = new WrappedMessageContext(msg);
+ WebServiceContextImpl webServiceContext = new WebServiceContextImpl(msgCtx);
+
+ // Issue a token
+ RequestSecurityTokenResponseCollectionType response =
+ issueOperation.issue(request, webServiceContext);
+ List<RequestSecurityTokenResponseType> securityTokenResponse =
+ response.getRequestSecurityTokenResponse();
+ assertTrue(!securityTokenResponse.isEmpty());
+ }
+
+ /**
+ * Test to successfully issue a SAML 2 token on-behalf-of a SAML 2 Symmetric HOK token
+ */
+ @org.junit.Test
+ public void testIssueSaml2TokenOnBehalfOfSaml2SymmetricHOK() throws Exception {
+ TokenIssueOperation issueOperation = new TokenIssueOperation();
+
+ // Add Token Provider
+ List<TokenProvider> providerList = new ArrayList<TokenProvider>();
+ providerList.add(new SAMLTokenProvider());
+ issueOperation.setTokenProviders(providerList);
+
+ // Add Token Validator
+ List<TokenValidator> validatorList = new ArrayList<TokenValidator>();
+ validatorList.add(new SAMLTokenValidator());
+ issueOperation.setTokenValidators(validatorList);
+
+ // Add Service
+ ServiceMBean service = new StaticService();
+ service.setEndpoints(Collections.singletonList("http://dummy-service.com/dummy"));
+ issueOperation.setServices(Collections.singletonList(service));
+
+ // Add STSProperties object
+ STSPropertiesMBean stsProperties = new StaticSTSProperties();
+ Crypto crypto = CryptoFactory.getInstance(getEncryptionProperties());
+ stsProperties.setEncryptionCrypto(crypto);
+ stsProperties.setSignatureCrypto(crypto);
+ stsProperties.setEncryptionUsername("myservicekey");
+ stsProperties.setSignatureUsername("mystskey");
+ stsProperties.setCallbackHandler(new PasswordCallbackHandler());
+ stsProperties.setIssuer("STS");
+ issueOperation.setStsProperties(stsProperties);
+
+ // 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);
+
+ // Get a SAML Token via the SAMLTokenProvider
+ CallbackHandler callbackHandler = new PasswordCallbackHandler();
+ Element samlToken =
+ createSAMLAssertion(WSConstants.WSS_SAML2_TOKEN_TYPE, crypto, "mystskey",
+ callbackHandler, null, STSConstants.SYMMETRIC_KEY_TYPE);
+ Document doc = samlToken.getOwnerDocument();
+ samlToken = (Element)doc.appendChild(samlToken);
+ OnBehalfOfType onbehalfof = new OnBehalfOfType();
+ onbehalfof.setAny(samlToken);
+
+ JAXBElement<OnBehalfOfType> onbehalfofType =
+ new JAXBElement<OnBehalfOfType>(
+ QNameConstants.ON_BEHALF_OF, OnBehalfOfType.class, onbehalfof
+ );
+ request.getAny().add(onbehalfofType);
+
+ // Mock up message context
+ MessageImpl msg = new MessageImpl();
+ WrappedMessageContext msgCtx = new WrappedMessageContext(msg);
+ WebServiceContextImpl webServiceContext = new WebServiceContextImpl(msgCtx);
+
+ // Issue a token
+
+ // This should fail as the default DelegationHandler does not allow HolderOfKey
+ try {
+ issueOperation.issue(request, webServiceContext);
+ fail("Failure expected as HolderOfKey is not allowed by default");
+ } catch (STSException ex) {
+ // expected
+ }
+
+ issueOperation.setDelegationHandler(new HOKDelegationHandler());
+
+ RequestSecurityTokenResponseCollectionType response =
+ issueOperation.issue(request, webServiceContext);
+ List<RequestSecurityTokenResponseType> securityTokenResponse =
+ response.getRequestSecurityTokenResponse();
+ assertTrue(!securityTokenResponse.isEmpty());
+ }
+
+ /**
+ * Test to successfully issue a SAML 2 token on-behalf-of a SAML 1 Symmetric HOK token
+ */
+ @org.junit.Test
+ public void testIssueSaml2TokenOnBehalfOfSaml1SymmetricHOK() throws Exception {
+ TokenIssueOperation issueOperation = new TokenIssueOperation();
+
+ // Add Token Provider
+ List<TokenProvider> providerList = new ArrayList<TokenProvider>();
+ providerList.add(new SAMLTokenProvider());
+ issueOperation.setTokenProviders(providerList);
+
+ // Add Token Validator
+ List<TokenValidator> validatorList = new ArrayList<TokenValidator>();
+ validatorList.add(new SAMLTokenValidator());
+ issueOperation.setTokenValidators(validatorList);
+
+ // Add Service
+ ServiceMBean service = new StaticService();
+ service.setEndpoints(Collections.singletonList("http://dummy-service.com/dummy"));
+ issueOperation.setServices(Collections.singletonList(service));
+
+ // Add STSProperties object
+ STSPropertiesMBean stsProperties = new StaticSTSProperties();
+ Crypto crypto = CryptoFactory.getInstance(getEncryptionProperties());
+ stsProperties.setEncryptionCrypto(crypto);
+ stsProperties.setSignatureCrypto(crypto);
+ stsProperties.setEncryptionUsername("myservicekey");
+ stsProperties.setSignatureUsername("mystskey");
+ stsProperties.setCallbackHandler(new PasswordCallbackHandler());
+ stsProperties.setIssuer("STS");
+ issueOperation.setStsProperties(stsProperties);
+
+ // 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);
+
+ // Get a SAML Token via the SAMLTokenProvider
+ CallbackHandler callbackHandler = new PasswordCallbackHandler();
+ Element samlToken =
+ createSAMLAssertion(WSConstants.WSS_SAML_TOKEN_TYPE, crypto, "mystskey",
+ callbackHandler, null, STSConstants.SYMMETRIC_KEY_TYPE);
+ Document doc = samlToken.getOwnerDocument();
+ samlToken = (Element)doc.appendChild(samlToken);
+ OnBehalfOfType onbehalfof = new OnBehalfOfType();
+ onbehalfof.setAny(samlToken);
+
+ JAXBElement<OnBehalfOfType> onbehalfofType =
+ new JAXBElement<OnBehalfOfType>(
+ QNameConstants.ON_BEHALF_OF, OnBehalfOfType.class, onbehalfof
+ );
+ request.getAny().add(onbehalfofType);
+
+ // Mock up message context
+ MessageImpl msg = new MessageImpl();
+ WrappedMessageContext msgCtx = new WrappedMessageContext(msg);
+ WebServiceContextImpl webServiceContext = new WebServiceContextImpl(msgCtx);
+
+ // Issue a token
+
+ // This should fail as the default DelegationHandler does not allow HolderOfKey
+ try {
+ issueOperation.issue(request, webServiceContext);
+ fail("Failure expected as HolderOfKey is not allowed by default");
+ } catch (STSException ex) {
+ // expected
+ }
+
+ issueOperation.setDelegationHandler(new HOKDelegationHandler());
+
+ RequestSecurityTokenResponseCollectionType response =
+ issueOperation.issue(request, webServiceContext);
+ List<RequestSecurityTokenResponseType> securityTokenResponse =
+ response.getRequestSecurityTokenResponse();
+ assertTrue(!securityTokenResponse.isEmpty());
+ }
+
+ /**
+ * Test to successfully issue a SAML 2 token on-behalf-of a SAML 2 PublicKey HOK token
+ */
+ @org.junit.Test
+ public void testIssueSaml2TokenOnBehalfOfSaml2PublicKeyHOK() throws Exception {
+ TokenIssueOperation issueOperation = new TokenIssueOperation();
+
+ // Add Token Provider
+ List<TokenProvider> providerList = new ArrayList<TokenProvider>();
+ providerList.add(new SAMLTokenProvider());
+ issueOperation.setTokenProviders(providerList);
+
+ // Add Token Validator
+ List<TokenValidator> validatorList = new ArrayList<TokenValidator>();
+ validatorList.add(new SAMLTokenValidator());
+ issueOperation.setTokenValidators(validatorList);
+
+ // Add Service
+ ServiceMBean service = new StaticService();
+ service.setEndpoints(Collections.singletonList("http://dummy-service.com/dummy"));
+ issueOperation.setServices(Collections.singletonList(service));
+
+ // Add STSProperties object
+ STSPropertiesMBean stsProperties = new StaticSTSProperties();
+ Crypto crypto = CryptoFactory.getInstance(getEncryptionProperties());
+ stsProperties.setEncryptionCrypto(crypto);
+ stsProperties.setSignatureCrypto(crypto);
+ stsProperties.setEncryptionUsername("myservicekey");
+ stsProperties.setSignatureUsername("mystskey");
+ stsProperties.setCallbackHandler(new PasswordCallbackHandler());
+ stsProperties.setIssuer("STS");
+ issueOperation.setStsProperties(stsProperties);
+
+ // 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);
+
+ // Get a SAML Token via the SAMLTokenProvider
+ CallbackHandler callbackHandler = new PasswordCallbackHandler();
+ Element samlToken =
+ createSAMLAssertion(WSConstants.WSS_SAML2_TOKEN_TYPE, crypto, "mystskey",
+ callbackHandler, null, STSConstants.PUBLIC_KEY_KEYTYPE);
+ Document doc = samlToken.getOwnerDocument();
+ samlToken = (Element)doc.appendChild(samlToken);
+ OnBehalfOfType onbehalfof = new OnBehalfOfType();
+ onbehalfof.setAny(samlToken);
+
+ JAXBElement<OnBehalfOfType> onbehalfofType =
+ new JAXBElement<OnBehalfOfType>(
+ QNameConstants.ON_BEHALF_OF, OnBehalfOfType.class, onbehalfof
+ );
+ request.getAny().add(onbehalfofType);
+
+ // Mock up message context
+ MessageImpl msg = new MessageImpl();
+ WrappedMessageContext msgCtx = new WrappedMessageContext(msg);
+ WebServiceContextImpl webServiceContext = new WebServiceContextImpl(msgCtx);
+
+ // Issue a token
+
+ // This should fail as the default DelegationHandler does not allow HolderOfKey
+ try {
+ issueOperation.issue(request, webServiceContext);
+ fail("Failure expected as HolderOfKey is not allowed by default");
+ } catch (STSException ex) {
+ // expected
+ }
+
+ issueOperation.setDelegationHandler(new HOKDelegationHandler());
+
+ RequestSecurityTokenResponseCollectionType response =
+ issueOperation.issue(request, webServiceContext);
+ List<RequestSecurityTokenResponseType> securityTokenResponse =
+ response.getRequestSecurityTokenResponse();
+ assertTrue(!securityTokenResponse.isEmpty());
+ }
+
+ /**
+ * Test to successfully issue a SAML 2 token on-behalf-of a SAML 1 PublicKey HOK token
+ */
+ @org.junit.Test
+ public void testIssueSaml2TokenOnBehalfOfSaml1PublicKeyHOK() throws Exception {
+ TokenIssueOperation issueOperation = new TokenIssueOperation();
+
+ // Add Token Provider
+ List<TokenProvider> providerList = new ArrayList<TokenProvider>();
+ providerList.add(new SAMLTokenProvider());
+ issueOperation.setTokenProviders(providerList);
+
+ // Add Token Validator
+ List<TokenValidator> validatorList = new ArrayList<TokenValidator>();
+ validatorList.add(new SAMLTokenValidator());
+ issueOperation.setTokenValidators(validatorList);
+
+ // Add Service
+ ServiceMBean service = new StaticService();
+ service.setEndpoints(Collections.singletonList("http://dummy-service.com/dummy"));
+ issueOperation.setServices(Collections.singletonList(service));
+
+ // Add STSProperties object
+ STSPropertiesMBean stsProperties = new StaticSTSProperties();
+ Crypto crypto = CryptoFactory.getInstance(getEncryptionProperties());
+ stsProperties.setEncryptionCrypto(crypto);
+ stsProperties.setSignatureCrypto(crypto);
+ stsProperties.setEncryptionUsername("myservicekey");
+ stsProperties.setSignatureUsername("mystskey");
+ stsProperties.setCallbackHandler(new PasswordCallbackHandler());
+ stsProperties.setIssuer("STS");
+ issueOperation.setStsProperties(stsProperties);
+
+ // 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);
+
+ // Get a SAML Token via the SAMLTokenProvider
+ CallbackHandler callbackHandler = new PasswordCallbackHandler();
+ Element samlToken =
+ createSAMLAssertion(WSConstants.WSS_SAML_TOKEN_TYPE, crypto, "mystskey",
+ callbackHandler, null, STSConstants.PUBLIC_KEY_KEYTYPE);
+ Document doc = samlToken.getOwnerDocument();
+ samlToken = (Element)doc.appendChild(samlToken);
+ OnBehalfOfType onbehalfof = new OnBehalfOfType();
+ onbehalfof.setAny(samlToken);
+
+ JAXBElement<OnBehalfOfType> onbehalfofType =
+ new JAXBElement<OnBehalfOfType>(
+ QNameConstants.ON_BEHALF_OF, OnBehalfOfType.class, onbehalfof
+ );
+ request.getAny().add(onbehalfofType);
+
+ // Mock up message context
+ MessageImpl msg = new MessageImpl();
+ WrappedMessageContext msgCtx = new WrappedMessageContext(msg);
+ WebServiceContextImpl webServiceContext = new WebServiceContextImpl(msgCtx);
+
+ // Issue a token
+
+ // This should fail as the default DelegationHandler does not allow HolderOfKey
+ try {
+ issueOperation.issue(request, webServiceContext);
+ fail("Failure expected as HolderOfKey is not allowed by default");
+ } catch (STSException ex) {
+ // expected
+ }
+
+ issueOperation.setDelegationHandler(new HOKDelegationHandler());
+
+ RequestSecurityTokenResponseCollectionType response =
+ issueOperation.issue(request, webServiceContext);
+ List<RequestSecurityTokenResponseType> securityTokenResponse =
+ response.getRequestSecurityTokenResponse();
+ assertTrue(!securityTokenResponse.isEmpty());
+ }
+
+ /**
+ * Test to unsuccessfully issue a SAML 2 token on-behalf-of a SAML 2 token. The
+ * problem is that the Audience Restriction URLs in the original token do not
+ * match the AppliesTo address.
+ */
+ @org.junit.Test
+ public void testSaml2AudienceRestriction() throws Exception {
+ TokenIssueOperation issueOperation = new TokenIssueOperation();
+
+ // Add Token Provider
+ List<TokenProvider> providerList = new ArrayList<TokenProvider>();
+ providerList.add(new SAMLTokenProvider());
+ issueOperation.setTokenProviders(providerList);
+
+ // Add Token Validator
+ List<TokenValidator> validatorList = new ArrayList<TokenValidator>();
+ validatorList.add(new SAMLTokenValidator());
+ issueOperation.setTokenValidators(validatorList);
+
+ // Add Service
+ ServiceMBean service = new StaticService();
+ service.setEndpoints(Collections.singletonList("http://dummy-service.com/dummy"));
+ issueOperation.setServices(Collections.singletonList(service));
+
+ // Add STSProperties object
+ STSPropertiesMBean stsProperties = new StaticSTSProperties();
+ Crypto crypto = CryptoFactory.getInstance(getEncryptionProperties());
+ stsProperties.setEncryptionCrypto(crypto);
+ stsProperties.setSignatureCrypto(crypto);
+ stsProperties.setEncryptionUsername("myservicekey");
+ stsProperties.setSignatureUsername("mystskey");
+ stsProperties.setCallbackHandler(new PasswordCallbackHandler());
+ stsProperties.setIssuer("STS");
+ issueOperation.setStsProperties(stsProperties);
+
+ // 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);
+
+ // Get a SAML Token via the SAMLTokenProvider
+ CallbackHandler callbackHandler = new PasswordCallbackHandler();
+ Element samlToken =
+ createSAMLAssertion(WSConstants.WSS_SAML2_TOKEN_TYPE, crypto, "mystskey", callbackHandler);
+ Document doc = samlToken.getOwnerDocument();
+ samlToken = (Element)doc.appendChild(samlToken);
+ OnBehalfOfType onbehalfof = new OnBehalfOfType();
+ onbehalfof.setAny(samlToken);
+
+ JAXBElement<OnBehalfOfType> onbehalfofType =
+ new JAXBElement<OnBehalfOfType>(
+ QNameConstants.ON_BEHALF_OF, OnBehalfOfType.class, onbehalfof
+ );
+ request.getAny().add(onbehalfofType);
+
+ // Mock up message context
+ MessageImpl msg = new MessageImpl();
+ WrappedMessageContext msgCtx = new WrappedMessageContext(msg);
+ WebServiceContextImpl webServiceContext = new WebServiceContextImpl(msgCtx);
+
+ // Issue a token - this should work
+ issueOperation.issue(request, webServiceContext);
+
+ request.getAny().add(createAppliesToElement("http://dummy-service.com/dummy2"));
+ // This should fail
+ try {
+ issueOperation.issue(request, webServiceContext);
+ fail("Failure expected due to AudienceRestriction");
+ } catch (STSException ex) {
+ // expected
+ }
+ }
+
+ /**
+ * Test to unsuccessfully issue a SAML 2 token on-behalf-of a SAML 1 token. The
+ * problem is that the Audience Restriction URLs in the original token do not
+ * match the AppliesTo address.
+ */
+ @org.junit.Test
+ public void testSaml1AudienceRestriction() throws Exception {
+ TokenIssueOperation issueOperation = new TokenIssueOperation();
+
+ // Add Token Provider
+ List<TokenProvider> providerList = new ArrayList<TokenProvider>();
+ providerList.add(new SAMLTokenProvider());
+ issueOperation.setTokenProviders(providerList);
+
+ // Add Token Validator
+ List<TokenValidator> validatorList = new ArrayList<TokenValidator>();
+ validatorList.add(new SAMLTokenValidator());
+ issueOperation.setTokenValidators(validatorList);
+
+ // Add Service
+ ServiceMBean service = new StaticService();
+ service.setEndpoints(Collections.singletonList("http://dummy-service.com/dummy"));
+ issueOperation.setServices(Collections.singletonList(service));
+
+ // Add STSProperties object
+ STSPropertiesMBean stsProperties = new StaticSTSProperties();
+ Crypto crypto = CryptoFactory.getInstance(getEncryptionProperties());
+ stsProperties.setEncryptionCrypto(crypto);
+ stsProperties.setSignatureCrypto(crypto);
+ stsProperties.setEncryptionUsername("myservicekey");
+ stsProperties.setSignatureUsername("mystskey");
+ stsProperties.setCallbackHandler(new PasswordCallbackHandler());
+ stsProperties.setIssuer("STS");
+ issueOperation.setStsProperties(stsProperties);
+
+ // 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);
+
+ // Get a SAML Token via the SAMLTokenProvider
+ CallbackHandler callbackHandler = new PasswordCallbackHandler();
+ Element samlToken =
+ createSAMLAssertion(WSConstants.WSS_SAML_TOKEN_TYPE, crypto, "mystskey", callbackHandler);
+ Document doc = samlToken.getOwnerDocument();
+ samlToken = (Element)doc.appendChild(samlToken);
+ OnBehalfOfType onbehalfof = new OnBehalfOfType();
+ onbehalfof.setAny(samlToken);
+
+ JAXBElement<OnBehalfOfType> onbehalfofType =
+ new JAXBElement<OnBehalfOfType>(
+ QNameConstants.ON_BEHALF_OF, OnBehalfOfType.class, onbehalfof
+ );
+ request.getAny().add(onbehalfofType);
+
+ // Mock up message context
+ MessageImpl msg = new MessageImpl();
+ WrappedMessageContext msgCtx = new WrappedMessageContext(msg);
+ WebServiceContextImpl webServiceContext = new WebServiceContextImpl(msgCtx);
+
+ // Issue a token - this should work
+ issueOperation.issue(request, webServiceContext);
+
+ request.getAny().add(createAppliesToElement("http://dummy-service.com/dummy2"));
+ // This should fail
+ try {
+ issueOperation.issue(request, webServiceContext);
+ fail("Failure expected due to AudienceRestriction");
+ } catch (STSException ex) {
+ // expected
+ }
+ }
/**
* Test to successfully issue a SAML 2 token on-behalf-of a UsernameToken
@@ -221,6 +769,17 @@ public class IssueOnbehalfofUnitTest ext
WebServiceContextImpl webServiceContext = new WebServiceContextImpl(msgCtx);
// Issue a token
+
+ // This should fail as the default DelegationHandler does not allow UsernameTokens
+ try {
+ issueOperation.issue(request, webServiceContext);
+ fail("Failure expected as UsernameTokens are not accepted for OnBehalfOf by default");
+ } catch (STSException ex) {
+ // expected
+ }
+
+ issueOperation.setDelegationHandler(new UsernameTokenDelegationHandler());
+
RequestSecurityTokenResponseCollectionType response =
issueOperation.issue(request, webServiceContext);
List<RequestSecurityTokenResponseType> securityTokenResponse =
@@ -286,6 +845,8 @@ public class IssueOnbehalfofUnitTest ext
MessageImpl msg = new MessageImpl();
WrappedMessageContext msgCtx = new WrappedMessageContext(msg);
WebServiceContextImpl webServiceContext = new WebServiceContextImpl(msgCtx);
+
+ issueOperation.setDelegationHandler(new UsernameTokenDelegationHandler());
// Issue a token - this will fail as the UsernameToken validation fails
try {
@@ -350,7 +911,7 @@ public class IssueOnbehalfofUnitTest ext
CallbackHandler callbackHandler = new PasswordCallbackHandler();
Element samlToken =
createSAMLAssertion(WSConstants.WSS_SAML2_TOKEN_TYPE, crypto, "mystskey",
- callbackHandler, realms);
+ callbackHandler, realms, STSConstants.BEARER_KEY_KEYTYPE);
Document doc = samlToken.getOwnerDocument();
samlToken = (Element)doc.appendChild(samlToken);
OnBehalfOfType onbehalfof = new OnBehalfOfType();
@@ -625,7 +1186,8 @@ public class IssueOnbehalfofUnitTest ext
private Element createSAMLAssertion(
String tokenType, Crypto crypto, String signatureUsername, CallbackHandler callbackHandler
) throws WSSecurityException {
- return createSAMLAssertion(tokenType, crypto, signatureUsername, callbackHandler, null);
+ return createSAMLAssertion(tokenType, crypto, signatureUsername,
+ callbackHandler, null, STSConstants.BEARER_KEY_KEYTYPE);
}
/*
@@ -633,14 +1195,14 @@ public class IssueOnbehalfofUnitTest ext
*/
private Element createSAMLAssertion(
String tokenType, Crypto crypto, String signatureUsername, CallbackHandler callbackHandler,
- Map<String, SAMLRealm> realms
+ Map<String, SAMLRealm> realms, String keyType
) throws WSSecurityException {
SAMLTokenProvider samlTokenProvider = new SAMLTokenProvider();
samlTokenProvider.setRealmMap(realms);
TokenProviderParameters providerParameters =
createProviderParameters(
- tokenType, STSConstants.BEARER_KEY_KEYTYPE, crypto, signatureUsername, callbackHandler
+ tokenType, keyType, crypto, signatureUsername, callbackHandler
);
if (realms != null) {
providerParameters.setRealm("A");
@@ -664,6 +1226,14 @@ public class IssueOnbehalfofUnitTest ext
KeyRequirements keyRequirements = new KeyRequirements();
keyRequirements.setKeyType(keyType);
+
+ CryptoType cryptoType = new CryptoType(CryptoType.TYPE.ALIAS);
+ cryptoType.setAlias("myclientkey");
+ X509Certificate[] certs = crypto.getX509Certificates(cryptoType);
+ ReceivedKey receivedKey = new ReceivedKey();
+ receivedKey.setX509Cert(certs[0]);
+ keyRequirements.setReceivedKey(receivedKey);
+
parameters.setKeyRequirements(keyRequirements);
parameters.setPrincipal(new CustomTokenPrincipal("alice"));
@@ -681,6 +1251,8 @@ public class IssueOnbehalfofUnitTest ext
stsProperties.setSignatureUsername(signatureUsername);
stsProperties.setCallbackHandler(callbackHandler);
stsProperties.setIssuer("STS");
+ stsProperties.setEncryptionUsername("myservicekey");
+ stsProperties.setEncryptionCrypto(crypto);
parameters.setStsProperties(stsProperties);
parameters.setEncryptionProperties(new EncryptionProperties());
@@ -761,5 +1333,20 @@ public class IssueOnbehalfofUnitTest ext
return claimType;
}
-
+ /*
+ * Mock up an AppliesTo element using the supplied address
+ */
+ private Element createAppliesToElement(String addressUrl) {
+ Document doc = DOMUtils.createDocument();
+ Element appliesTo = doc.createElementNS(STSConstants.WSP_NS, "wsp:AppliesTo");
+ appliesTo.setAttributeNS(WSConstants.XMLNS_NS, "xmlns:wsp", STSConstants.WSP_NS);
+ Element endpointRef = doc.createElementNS(STSConstants.WSA_NS_05, "wsa:EndpointReference");
+ endpointRef.setAttributeNS(WSConstants.XMLNS_NS, "xmlns:wsa", STSConstants.WSA_NS_05);
+ Element address = doc.createElementNS(STSConstants.WSA_NS_05, "wsa:Address");
+ address.setAttributeNS(WSConstants.XMLNS_NS, "xmlns:wsa", STSConstants.WSA_NS_05);
+ address.setTextContent(addressUrl);
+ endpointRef.appendChild(address);
+ appliesTo.appendChild(endpointRef);
+ return appliesTo;
+ }
}
Modified: cxf/trunk/services/sts/systests/advanced/src/test/resources/org/apache/cxf/systest/sts/deployment/cxf-sts.xml
URL: http://svn.apache.org/viewvc/cxf/trunk/services/sts/systests/advanced/src/test/resources/org/apache/cxf/systest/sts/deployment/cxf-sts.xml?rev=1520272&r1=1520271&r2=1520272&view=diff
==============================================================================
--- cxf/trunk/services/sts/systests/advanced/src/test/resources/org/apache/cxf/systest/sts/deployment/cxf-sts.xml (original)
+++ cxf/trunk/services/sts/systests/advanced/src/test/resources/org/apache/cxf/systest/sts/deployment/cxf-sts.xml Thu Sep 5 10:38:30 2013
@@ -54,12 +54,16 @@
<property name="validateOperation" ref="transportValidateDelegate" />
</bean>
+ <bean id="utDelegationHandler"
+ class="org.apache.cxf.sts.request.UsernameTokenDelegationHandler" />
+
<bean id="transportIssueDelegate" class="org.apache.cxf.sts.operation.TokenIssueOperation">
<property name="tokenProviders" ref="transportTokenProviders" />
<property name="services" ref="transportService" />
<property name="stsProperties" ref="transportSTSProperties" />
<property name="claimsManager" ref="claimsManager" />
<property name="tokenStore" ref="defaultTokenStore" />
+ <property name="delegationHandler" ref="utDelegationHandler" />
</bean>
<bean id="transportValidateDelegate" class="org.apache.cxf.sts.operation.TokenValidateOperation">
Added: cxf/trunk/services/sts/systests/basic/src/test/java/org/apache/cxf/systest/sts/common/HOKDelegationHandler.java
URL: http://svn.apache.org/viewvc/cxf/trunk/services/sts/systests/basic/src/test/java/org/apache/cxf/systest/sts/common/HOKDelegationHandler.java?rev=1520272&view=auto
==============================================================================
--- cxf/trunk/services/sts/systests/basic/src/test/java/org/apache/cxf/systest/sts/common/HOKDelegationHandler.java (added)
+++ cxf/trunk/services/sts/systests/basic/src/test/java/org/apache/cxf/systest/sts/common/HOKDelegationHandler.java Thu Sep 5 10:38:30 2013
@@ -0,0 +1,71 @@
+/**
+ * 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.systest.sts.common;
+
+import javax.xml.ws.WebServiceContext;
+
+import org.w3c.dom.Element;
+import org.apache.cxf.sts.request.DefaultDelegationHandler;
+import org.apache.cxf.sts.request.ReceivedToken;
+import org.apache.wss4j.common.ext.WSSecurityException;
+import org.apache.wss4j.common.saml.SamlAssertionWrapper;
+import org.apache.wss4j.common.saml.builder.SAML1Constants;
+import org.apache.wss4j.common.saml.builder.SAML2Constants;
+
+/**
+ * This DelegationHandler implementation extends the Default implementation to allow SAML
+ * Tokens with HolderOfKey Subject Confirmation. It also doesn't require that the AppliesTo
+ * address matches an AudienceRestriction condition in the SAML Token.
+ */
+public class HOKDelegationHandler extends DefaultDelegationHandler {
+
+ /**
+ * Is Delegation allowed for a particular token
+ */
+ @Override
+ protected boolean isDelegationAllowed(
+ WebServiceContext context,
+ ReceivedToken receivedToken,
+ String appliesToAddress
+ ) {
+ // It must be a SAML Token
+ if (!isSAMLToken(receivedToken)) {
+ return false;
+ }
+
+ Element validateTargetElement = (Element)receivedToken.getToken();
+ try {
+ SamlAssertionWrapper assertion = new SamlAssertionWrapper(validateTargetElement);
+
+ for (String confirmationMethod : assertion.getConfirmationMethods()) {
+ if (!(SAML1Constants.CONF_BEARER.equals(confirmationMethod)
+ || SAML1Constants.CONF_HOLDER_KEY.equals(confirmationMethod)
+ || SAML2Constants.CONF_BEARER.equals(confirmationMethod)
+ || SAML2Constants.CONF_HOLDER_KEY.equals(confirmationMethod))) {
+ return false;
+ }
+ }
+ } catch (WSSecurityException ex) {
+ return false;
+ }
+
+ return true;
+ }
+
+}
\ No newline at end of file
Modified: cxf/trunk/services/sts/systests/basic/src/test/java/org/apache/cxf/systest/sts/issueunit/IssueUnitTest.java
URL: http://svn.apache.org/viewvc/cxf/trunk/services/sts/systests/basic/src/test/java/org/apache/cxf/systest/sts/issueunit/IssueUnitTest.java?rev=1520272&r1=1520271&r2=1520272&view=diff
==============================================================================
--- cxf/trunk/services/sts/systests/basic/src/test/java/org/apache/cxf/systest/sts/issueunit/IssueUnitTest.java (original)
+++ cxf/trunk/services/sts/systests/basic/src/test/java/org/apache/cxf/systest/sts/issueunit/IssueUnitTest.java Thu Sep 5 10:38:30 2013
@@ -19,7 +19,6 @@
package org.apache.cxf.systest.sts.issueunit;
import java.net.URL;
-import java.security.cert.X509Certificate;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -27,10 +26,7 @@ import java.util.Properties;
import javax.security.auth.callback.CallbackHandler;
import javax.xml.namespace.QName;
-import javax.xml.parsers.DocumentBuilder;
-import javax.xml.parsers.DocumentBuilderFactory;
-import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.apache.cxf.Bus;
@@ -57,7 +53,6 @@ import org.apache.cxf.ws.security.tokens
import org.apache.cxf.ws.security.trust.STSClient;
import org.apache.wss4j.common.crypto.Crypto;
import org.apache.wss4j.common.crypto.CryptoFactory;
-import org.apache.wss4j.common.crypto.CryptoType;
import org.apache.wss4j.common.ext.WSSecurityException;
import org.apache.wss4j.common.principal.CustomTokenPrincipal;
import org.apache.wss4j.common.saml.OpenSAMLUtil;
@@ -67,7 +62,6 @@ import org.apache.wss4j.dom.WSConstants;
import org.apache.wss4j.dom.WSDocInfo;
import org.apache.wss4j.dom.WSSecurityEngineResult;
import org.apache.wss4j.dom.handler.RequestData;
-import org.apache.wss4j.dom.message.token.X509Security;
import org.apache.wss4j.dom.processor.Processor;
import org.apache.wss4j.dom.processor.SAMLTokenProcessor;
import org.junit.BeforeClass;
@@ -245,21 +239,10 @@ public class IssueUnitTest extends Abstr
SpringBusFactory.setDefaultBus(bus);
SpringBusFactory.setThreadDefaultBus(bus);
- DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
- DocumentBuilder builder = factory.newDocumentBuilder();
- Document doc = builder.newDocument();
-
- X509Security bst = new X509Security(doc);
- Crypto crypto = CryptoFactory.getInstance("clientKeystore.properties");
- CryptoType cryptoType = new CryptoType(CryptoType.TYPE.ALIAS);
- cryptoType.setAlias("myclientkey");
- X509Certificate[] certs = crypto.getX509Certificates(cryptoType);
- bst.setX509Certificate(certs[0]);
-
// Get a token
SecurityToken token =
requestSecurityToken(
- SAML2_TOKEN_TYPE, BEARER_KEYTYPE, bst.getElement(), bus, DEFAULT_ADDRESS, null, null, null, null
+ SAML2_TOKEN_TYPE, BEARER_KEYTYPE, null, bus, DEFAULT_ADDRESS, null, null, null, null
);
assertTrue(SAML2_TOKEN_TYPE.equals(token.getTokenType()));
assertTrue(token.getToken() != null);
Modified: cxf/trunk/services/sts/systests/basic/src/test/resources/org/apache/cxf/systest/sts/deployment/cxf-transport.xml
URL: http://svn.apache.org/viewvc/cxf/trunk/services/sts/systests/basic/src/test/resources/org/apache/cxf/systest/sts/deployment/cxf-transport.xml?rev=1520272&r1=1520271&r2=1520272&view=diff
==============================================================================
--- cxf/trunk/services/sts/systests/basic/src/test/resources/org/apache/cxf/systest/sts/deployment/cxf-transport.xml (original)
+++ cxf/trunk/services/sts/systests/basic/src/test/resources/org/apache/cxf/systest/sts/deployment/cxf-transport.xml Thu Sep 5 10:38:30 2013
@@ -46,11 +46,43 @@
<cxf:logging/>
</cxf:features>
</cxf:bus>
+
+ <bean id="hokDelegationHandler"
+ class="org.apache.cxf.systest.sts.common.HOKDelegationHandler" />
<bean id="transportSTSProviderBean2"
class="org.apache.cxf.ws.security.sts.provider.SecurityTokenServiceProvider">
- <property name="issueOperation" ref="transportIssueDelegate" />
- <property name="validateOperation" ref="transportValidateDelegate" />
+ <property name="issueOperation" ref="transportIssueDelegate2" />
+ <property name="validateOperation" ref="transportValidateDelegate2" />
+ </bean>
+
+ <bean id="transportIssueDelegate2" class="org.apache.cxf.sts.operation.TokenIssueOperation">
+ <property name="tokenProviders" ref="transportTokenProviders2" />
+ <property name="tokenValidators" ref="transportTokenValidators" />
+ <property name="services" ref="transportService" />
+ <property name="stsProperties" ref="transportSTSProperties" />
+ <property name="delegationHandler" ref="hokDelegationHandler" />
+ </bean>
+
+ <bean id="transportValidateDelegate2" class="org.apache.cxf.sts.operation.TokenValidateOperation">
+ <property name="tokenValidators" ref="transportTokenValidators2" />
+ <property name="stsProperties" ref="transportSTSProperties" />
+ </bean>
+
+ <util:list id="transportTokenValidators2">
+ <ref bean="transportSamlTokenValidator2" />
+ </util:list>
+
+ <util:list id="transportTokenProviders2">
+ <ref bean="transportSamlTokenProvider2" />
+ </util:list>
+
+ <bean id="transportSamlTokenValidator2" class="org.apache.cxf.sts.token.validator.SAMLTokenValidator">
+ <property name="samlRealmCodec" ref="samlRealmCodec" />
+ </bean>
+
+ <bean id="transportSamlTokenProvider2" class="org.apache.cxf.sts.token.provider.SAMLTokenProvider">
+ <property name="realmMap" ref="realms"/>
</bean>
<bean id="transportIssueDelegate" class="org.apache.cxf.sts.operation.TokenIssueOperation">
@@ -58,13 +90,14 @@
<property name="tokenValidators" ref="transportTokenValidators" />
<property name="services" ref="transportService" />
<property name="stsProperties" ref="transportSTSProperties" />
+ <property name="delegationHandler" ref="hokDelegationHandler" />
</bean>
<bean id="transportValidateDelegate" class="org.apache.cxf.sts.operation.TokenValidateOperation">
<property name="tokenValidators" ref="transportTokenValidators" />
<property name="stsProperties" ref="transportSTSProperties" />
</bean>
-
+
<util:list id="transportTokenValidators">
<ref bean="transportSamlTokenValidator" />
</util:list>
@@ -72,14 +105,18 @@
<util:list id="transportTokenProviders">
<ref bean="transportSamlTokenProvider" />
</util:list>
-
+
+ <bean id="transportSamlTokenValidator" class="org.apache.cxf.sts.token.validator.SAMLTokenValidator">
+ </bean>
+
+ <bean id="transportSamlTokenProvider" class="org.apache.cxf.sts.token.provider.SAMLTokenProvider">
+ </bean>
<bean id="transportSTSProviderBean"
- class="org.apache.cxf.sts.provider.DefaultSecurityTokenServiceProvider">
- <property name="services" ref="transportService" />
- <property name="stsProperties" ref="transportSTSProperties" />
+ class="org.apache.cxf.ws.security.sts.provider.SecurityTokenServiceProvider">
+ <property name="issueOperation" ref="transportIssueDelegate" />
+ <property name="validateOperation" ref="transportValidateDelegate" />
</bean>
-
<bean id="transportService" class="org.apache.cxf.sts.service.StaticService">
<property name="endpoints" ref="transportEndpoints" />
@@ -90,14 +127,6 @@
</value>
</util:list>
- <bean id="transportSamlTokenValidator" class="org.apache.cxf.sts.token.validator.SAMLTokenValidator">
- <property name="samlRealmCodec" ref="samlRealmCodec" />
- </bean>
-
- <bean id="transportSamlTokenProvider" class="org.apache.cxf.sts.token.provider.SAMLTokenProvider">
- <property name="realmMap" ref="realms"/>
- </bean>
-
<bean id="realmA"
class="org.apache.cxf.sts.token.realm.SAMLRealm">
<property name="issuer" value="a-issuer"/>
Modified: cxf/trunk/services/sts/systests/basic/src/test/resources/org/apache/cxf/systest/sts/deployment/cxf-x509.xml
URL: http://svn.apache.org/viewvc/cxf/trunk/services/sts/systests/basic/src/test/resources/org/apache/cxf/systest/sts/deployment/cxf-x509.xml?rev=1520272&r1=1520271&r2=1520272&view=diff
==============================================================================
--- cxf/trunk/services/sts/systests/basic/src/test/resources/org/apache/cxf/systest/sts/deployment/cxf-x509.xml (original)
+++ cxf/trunk/services/sts/systests/basic/src/test/resources/org/apache/cxf/systest/sts/deployment/cxf-x509.xml Thu Sep 5 10:38:30 2013
@@ -46,12 +46,16 @@
<property name="issueOperation" ref="x509IssueDelegate" />
<property name="validateOperation" ref="x509ValidateDelegate" />
</bean>
+
+ <bean id="utDelegationHandler"
+ class="org.apache.cxf.sts.request.UsernameTokenDelegationHandler" />
<bean id="x509IssueDelegate" class="org.apache.cxf.sts.operation.TokenIssueOperation">
<property name="tokenProviders" ref="x509SamlTokenProvider" />
<property name="tokenValidators" ref="x509TokenValidatorsOBO" />
<property name="services" ref="x509Service" />
<property name="stsProperties" ref="x509STSProperties" />
+ <property name="delegationHandler" ref="utDelegationHandler" />
</bean>
<bean id="x509ValidateDelegate" class="org.apache.cxf.sts.operation.TokenValidateOperation">