cxf-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ychawla <premiergenerat...@yahoo.com>
Subject Signing SAML token in STS - Namespace issue
Date Tue, 20 Nov 2012 17:08:19 GMT
Hello All,
I am writing a STS that has specific requirements.  Before asking my
question, I will give you some background information.

I started by using the STS client in the CXF distribution.  According to the
requirements, the client must:

-Have a RequestType of Issue
-Have a TokenType of SAML 2.0
-Include a token that it would like to present to the STS in the
'OnBehalfOf' element

The STS then receives the request and must:

-Validate the Audience, Issuer, Timestamp, Signature, and AppliesTo.  Some
of these attributes/elements must be verified against external resources.  I
do this in the Spring Configuration by declaring a custom validator:

	<bean id="transportIssueDelegate"
class="org.apache.cxf.sts.operation.TokenIssueOperation">
		<property name="tokenProviders" ref="transportTokenProviders" />
		<property name="tokenValidators" ref="myTransportTokenValidators" />
		<property name="services" ref="myTransportService" />
		<property name="stsProperties" ref="transportSTSProperties" />
	</bean>

	<util:list id="myTransportTokenValidators">
		<ref bean="myTransportSamlTokenValidator" />
	</util:list>

        <bean id="myTransportSamlTokenValidator"
class="org.mypackage.CustomSAMLTokenValidator"/>

In my CustomSAMLTokenValidator, I basically declare the CXF
SAMLTokenValidator and call the 'validateToken' method and then call a
custom validator:

private SAMLTokenValidator baseValidator = new SAMLTokenValidator();

public TokenValidatorResponse validateToken(
			TokenValidatorParameters tokenParameters) {
		TokenValidatorResponse baseResponse =
baseValidator.validateToken(tokenParameters);
		return validateCustomToken(baseResponse, tokenParameters);
}

After Token Validation, I need to create a Token Provider.  The requirements
of my STS state that I need to:

-Modify the Audience, change the method to 'sender-vouches', add a delegate
from an external resource, and then sign the token

To do this, I use a similar pattern to validation and write a custom token
provider:

	<util:list id="transportTokenProviders">
		<ref bean="transportSamlTokenProvider" />
	</util:list>

	<bean id="transportSamlTokenProvider"
class="org.mypackage.MySAMLTokenProvider"/>

I can retrieve the original token from the request like this:

		ReceivedToken recievedToken =
tokenParameters.getTokenRequirements().getOnBehalfOf();
		
		Element recievedTokenElement = (Element) recievedToken.getToken();
		Document recievedTokenDocument = recievedTokenElement.getOwnerDocument();

Now I can take the recievedTokenDocument and modify it as the requirements
state and then return this modified token.  The tricky part is signing the
token.  To sign the token, I lifted a bunch of code from the
SAMLTokenProvider.  I create an assertion wrapper with the token element and
then basically copy/paste the token signing code into my custom token
provider:

			  AssertionWrapper assertion = new
AssertionWrapper(recievedTokenElement);
                          //This is my private method that lifts the
existing signing code
			  signAssertion(tokenParameters, assertion);
			  
			  Document doc = DOMUtils.createDocument();
			  Element token = assertion.toDOM(doc);
                          response.setToken(token);

I then print out the token to confirm that it has been signed correctly. 
When I print the Assertion, the root element is:

<Assertion xmlns="urn:oasis:names:tc:SAML:2.0:assertion"
ID="_36e39772-2836-49ba-9c38-601e3458f0a2"
IssueInstant="2012-11-14T13:54:21.626Z" Version="2.0">...</Assertion>

However, later on when the message is serialized on the wire the assertion
is presented as:

<Assertion:Assertion xmlns="urn:oasis:names:tc:SAML:2.0:assertion"
xmlns:Assertion="urn:oasis:names:tc:SAML:2.0:assertion"
ID="_36e39772-2836-49ba-9c38-601e3458f0a2"
IssueInstant="2012-11-14T13:54:21.626Z"
Version="2.0">...</Assertion:Assertion>

The client that invoked the service then throws this error:

- Verification failed for URI "#_36e39772-2836-49ba-9c38-601e3458f0a2"
- Expected Digest: o9/dWrBJO6j+rxZucM8ARiJ2818=
- Actual Digest: x5Rc6VqzVtoazpDZmn+y/UFO488=

I suspect this is because the Assertion on the wire has a root element
'Assertion:Assertion' versus the signed Assertion with the root element of
'Assertion'.

Thanks for bearing with this long explanation.  I want to first confirm that
I am approaching this problem in a sensible way and then I wanted to see if
anyone had any ideas why the extra Assertion name prefix was added on the
wire.

Cheers,
Yogesh



--
View this message in context: http://cxf.547215.n5.nabble.com/Signing-SAML-token-in-STS-Namespace-issue-tp5718851.html
Sent from the cxf-user mailing list archive at Nabble.com.

Mime
View raw message