Author: anil.saldhana(a)jboss.com
Date: 2009-08-29 03:08:02 -0400 (Sat, 29 Aug 2009)
New Revision: 751
Modified:
identity-federation/trunk/jboss-identity-bindings/src/main/java/org/jboss/identity/federation/bindings/jboss/wstrust/JBossSTS.java
identity-federation/trunk/jboss-identity-fed-api/src/main/java/org/jboss/identity/federation/api/wstrust/StandardRequestHandler.java
identity-federation/trunk/jboss-identity-fed-api/src/main/java/org/jboss/identity/federation/api/wstrust/WSTrustException.java
identity-federation/trunk/jboss-identity-fed-api/src/main/java/org/jboss/identity/federation/api/wstrust/WSTrustRequestHandler.java
identity-federation/trunk/jboss-identity-fed-api/src/main/java/org/jboss/identity/federation/api/wstrust/plugins/saml/SAML20TokenProvider.java
Log:
JBID-180: do post processing
Modified:
identity-federation/trunk/jboss-identity-bindings/src/main/java/org/jboss/identity/federation/bindings/jboss/wstrust/JBossSTS.java
===================================================================
---
identity-federation/trunk/jboss-identity-bindings/src/main/java/org/jboss/identity/federation/bindings/jboss/wstrust/JBossSTS.java 2009-08-29
07:04:54 UTC (rev 750)
+++
identity-federation/trunk/jboss-identity-bindings/src/main/java/org/jboss/identity/federation/bindings/jboss/wstrust/JBossSTS.java 2009-08-29
07:08:02 UTC (rev 751)
@@ -27,6 +27,7 @@
import javax.annotation.Resource;
import javax.xml.bind.JAXBElement;
import javax.xml.transform.Source;
+import javax.xml.transform.dom.DOMSource;
import javax.xml.ws.Service;
import javax.xml.ws.ServiceMode;
import javax.xml.ws.WebServiceContext;
@@ -39,7 +40,7 @@
import org.jboss.identity.federation.api.wstrust.WSTrustConstants;
import org.jboss.identity.federation.api.wstrust.WSTrustException;
import org.jboss.identity.federation.api.wstrust.WSTrustJAXBFactory;
-import org.jboss.identity.federation.api.wstrust.WSTrustRequestHandler;
+import org.jboss.identity.federation.api.wstrust.WSTrustRequestHandler;
import org.jboss.identity.federation.core.config.STSType;
import org.jboss.identity.federation.core.exceptions.ConfigurationException;
import org.jboss.identity.federation.core.exceptions.ParsingException;
@@ -49,6 +50,7 @@
import org.jboss.identity.federation.core.wstrust.RequestSecurityTokenCollection;
import org.jboss.identity.federation.core.wstrust.RequestSecurityTokenResponse;
import org.jboss.identity.federation.core.wstrust.RequestSecurityTokenResponseCollection;
+import org.w3c.dom.Document;
/**
* <p>
@@ -126,7 +128,12 @@
try
{
if (requestType.equals(WSTrustConstants.ISSUE_REQUEST))
- return this.marshallResponse(handler.issue(request,
this.context.getUserPrincipal()));
+ {
+ Source source = this.marshallResponse(handler.issue(request,
this.context.getUserPrincipal()));
+ Document doc = handler.postProcess((Document)((DOMSource)source).getNode(),
request);
+ return new DOMSource(doc);
+ }
+
else if (requestType.equals(WSTrustConstants.RENEW_REQUEST))
return this.marshallResponse(handler.renew(request,
this.context.getUserPrincipal()));
else if (requestType.equals(WSTrustConstants.CANCEL_REQUEST))
Modified:
identity-federation/trunk/jboss-identity-fed-api/src/main/java/org/jboss/identity/federation/api/wstrust/StandardRequestHandler.java
===================================================================
---
identity-federation/trunk/jboss-identity-fed-api/src/main/java/org/jboss/identity/federation/api/wstrust/StandardRequestHandler.java 2009-08-29
07:04:54 UTC (rev 750)
+++
identity-federation/trunk/jboss-identity-fed-api/src/main/java/org/jboss/identity/federation/api/wstrust/StandardRequestHandler.java 2009-08-29
07:08:02 UTC (rev 751)
@@ -124,7 +124,7 @@
throw new WSTrustException("Token issued by provider " +
provider.getClass().getName() + " is null");
// sign the issued token if needed.
- if (this.configuration.signIssuedToken() &&
this.configuration.getSTSKeyPair() != null)
+ /*if (this.configuration.signIssuedToken() &&
this.configuration.getSTSKeyPair() != null)
{
KeyPair keyPair = this.configuration.getSTSKeyPair();
if (keyPair != null)
@@ -154,7 +154,7 @@
throw new WSTrustException("Failed to sign security token",
e);
}
}
- }
+ }*/
// construct the ws-trust security token response.
RequestedSecurityTokenType requestedSecurityToken = new
RequestedSecurityTokenType();
@@ -197,8 +197,74 @@
if( rstDocument == null)
throw new IllegalArgumentException("Request does not contain the DOM
Document");
- // TODO: implement renew logic.
- throw new UnsupportedOperationException();
+ SecurityTokenProvider provider = null;
+
+ // first try to obtain the security token provider using the applies-to contents.
+ AppliesTo appliesTo = request.getAppliesTo();
+ PublicKey providerPublicKey = null;
+ if (appliesTo != null)
+ {
+ String serviceName = WSTrustUtil.parseAppliesTo(appliesTo);
+ if (serviceName != null)
+ {
+ provider = this.configuration.getProviderForService(serviceName);
+
request.setTokenType(URI.create(this.configuration.getTokenTypeForService(serviceName)));
+ providerPublicKey =
this.configuration.getServiceProviderPublicKey(serviceName);
+ }
+ }
+ // if applies-to is not available or if no provider was found for the service, use
the token type.
+ if (provider == null && request.getTokenType() != null)
+ {
+ provider =
this.configuration.getProviderForTokenType(request.getTokenType().toString());
+ }
+ else if (appliesTo == null && request.getTokenType() == null)
+ throw new WSTrustException("Either AppliesTo or TokenType must be present
in a security token request");
+
+ // TODO: get the provider using the token from the request.
+ provider = this.configuration.getProviderForTokenType(SAMLUtil.SAML2_TOKEN_TYPE);
+
+ if (provider != null)
+ {
+ // create the request context and delegate token generation to the provider.
+ WSTrustRequestContext requestContext = new WSTrustRequestContext(request,
callerPrincipal);
+ requestContext.setTokenIssuer(this.configuration.getSTSName());
+ if (request.getLifetime() == null &&
this.configuration.getIssuedTokenTimeout() != 0)
+ {
+ // if no lifetime has been specified, use the configured timeout value.
+
request.setLifetime(WSTrustUtil.createDefaultLifetime(this.configuration.getIssuedTokenTimeout()));
+ }
+ requestContext.setServiceProviderPublicKey(providerPublicKey);
+ provider.renewToken(requestContext);
+
+ if (requestContext.getSecurityToken() == null)
+ throw new WSTrustException("Token issued by provider " +
provider.getClass().getName() + " is null");
+
+
+ // construct the ws-trust security token response.
+ RequestedSecurityTokenType requestedSecurityToken = new
RequestedSecurityTokenType();
+
requestedSecurityToken.setAny(requestContext.getSecurityToken().getTokenValue());
+
+ // TODO: create proof token and encrypt the token if needed
+
+ RequestSecurityTokenResponse response = new RequestSecurityTokenResponse();
+ if (request.getContext() != null)
+ response.setContext(request.getContext());
+
+ response.setTokenType(request.getTokenType());
+ response.setLifetime(request.getLifetime());
+ response.setAppliesTo(appliesTo);
+ response.setRequestedSecurityToken(requestedSecurityToken);
+
+ // set the attached and unattached references.
+ if (requestContext.getAttachedReference() != null)
+
response.setRequestedAttachedReference(requestContext.getAttachedReference());
+ if (requestContext.getUnattachedReference() != null)
+
response.setRequestedUnattachedReference(requestContext.getUnattachedReference());
+
+ return response;
+ }
+ else
+ throw new WSTrustException("Unable to find a token provider for the token
request");
}
/*
@@ -301,4 +367,57 @@
// TODO: implement cancel logic.
throw new UnsupportedOperationException();
}
+
+ public Document postProcess(Document rstrDocument, RequestSecurityToken request)
throws WSTrustException
+ {
+ if(WSTrustConstants.ISSUE_REQUEST.equals(request.getRequestType().toString())
+ ||
WSTrustConstants.RENEW_REQUEST.equals(request.getRequestType().toString()))
+ {
+ rstrDocument = DocumentUtil.normalizeNamespaces(rstrDocument);
+
+ //Sign and encrypt
+ if (this.configuration.signIssuedToken() &&
this.configuration.getSTSKeyPair() != null)
+ {
+ KeyPair keyPair = this.configuration.getSTSKeyPair();
+ if (keyPair != null)
+ {
+ URI signatureURI = request.getSignatureAlgorithm();
+ String signatureMethod = signatureURI != null ? signatureURI.toString() :
SignatureMethod.RSA_SHA1;
+ try
+ {
+ Node rst =
rstrDocument.getElementsByTagNameNS(WSTrustConstants.BASE_NAMESPACE,
+ "RequestedSecurityToken").item(0);
+ Element tokenElement = (Element) rst.getFirstChild();
+ if(trace)
+ {
+ log.trace("NamespaceURI of element to be signed:"
+tokenElement.getNamespaceURI() );
+ }
+ /* XMLSignatureUtil.sign(tokenElement.getOwnerDocument(), keyPair,
DigestMethod.SHA1, signatureMethod,
+ "#" + tokenElement.getAttribute("ID"));
+ */
+ rstrDocument = XMLSignatureUtil.sign(rstrDocument, tokenElement,
keyPair,
+ DigestMethod.SHA1, signatureMethod, "#" +
tokenElement.getAttribute("ID"));
+ if(trace)
+ {
+ try
+ {
+ log.trace("Signed Token:" +
DocumentUtil.getNodeAsString(tokenElement));
+
+ Document tokenDocument = DocumentUtil.createDocument();
+ tokenDocument.appendChild(tokenDocument.importNode(tokenElement,
true));
+ log.trace("valid=" +
XMLSignatureUtil.validate(tokenDocument, keyPair.getPublic()));
+
+ }catch(Exception ignore){}
+ }
+ }
+ catch (Exception e)
+ {
+ throw new WSTrustException("Failed to sign security token",
e);
+ }
+ }
+ }
+ }
+
+ return rstrDocument;
+ }
}
\ No newline at end of file
Modified:
identity-federation/trunk/jboss-identity-fed-api/src/main/java/org/jboss/identity/federation/api/wstrust/WSTrustException.java
===================================================================
---
identity-federation/trunk/jboss-identity-fed-api/src/main/java/org/jboss/identity/federation/api/wstrust/WSTrustException.java 2009-08-29
07:04:54 UTC (rev 750)
+++
identity-federation/trunk/jboss-identity-fed-api/src/main/java/org/jboss/identity/federation/api/wstrust/WSTrustException.java 2009-08-29
07:08:02 UTC (rev 751)
@@ -21,6 +21,8 @@
*/
package org.jboss.identity.federation.api.wstrust;
+import java.security.GeneralSecurityException;
+
/**
* <p>
* Exception used to convey that an error has happened when handling a WS-Trust request
message.
@@ -28,11 +30,10 @@
*
* @author <a href="mailto:sguilhen@redhat.com">Stefan Guilhen</a>
*/
-public class WSTrustException extends Exception
+public class WSTrustException extends GeneralSecurityException
{
-
private static final long serialVersionUID = -232066282004315310L;
-
+
/**
* <p>
* Creates an instance of {@code WSTrustException} using the specified error message.
@@ -57,4 +58,4 @@
{
super(message, cause);
}
-}
+}
\ No newline at end of file
Modified:
identity-federation/trunk/jboss-identity-fed-api/src/main/java/org/jboss/identity/federation/api/wstrust/WSTrustRequestHandler.java
===================================================================
---
identity-federation/trunk/jboss-identity-fed-api/src/main/java/org/jboss/identity/federation/api/wstrust/WSTrustRequestHandler.java 2009-08-29
07:04:54 UTC (rev 750)
+++
identity-federation/trunk/jboss-identity-fed-api/src/main/java/org/jboss/identity/federation/api/wstrust/WSTrustRequestHandler.java 2009-08-29
07:08:02 UTC (rev 751)
@@ -25,6 +25,7 @@
import org.jboss.identity.federation.core.wstrust.RequestSecurityToken;
import org.jboss.identity.federation.core.wstrust.RequestSecurityTokenResponse;
+import org.w3c.dom.Document;
/**
* <p>
@@ -35,8 +36,7 @@
* @author <a href="mailto:sguilhen@redhat.com">Stefan Guilhen</a>
*/
public interface WSTrustRequestHandler
-{
-
+{
/**
* <p>
* Initializes the concrete {@code WSTrustRequestHandler} instance.
@@ -98,4 +98,14 @@
*/
public RequestSecurityTokenResponse validate(RequestSecurityToken request, Principal
callerPrincipal)
throws WSTrustException;
+
+ /**
+ * Perform Post Processing on the generated RSTR Collection Document
+ * Steps such as signing and encryption need to be done here.
+ * @param rstrDocument
+ * @param request
+ * @return
+ * @throws WSTrustException
+ */
+ public Document postProcess(Document rstrDocument, RequestSecurityToken request)
throws WSTrustException;
}
Modified:
identity-federation/trunk/jboss-identity-fed-api/src/main/java/org/jboss/identity/federation/api/wstrust/plugins/saml/SAML20TokenProvider.java
===================================================================
---
identity-federation/trunk/jboss-identity-fed-api/src/main/java/org/jboss/identity/federation/api/wstrust/plugins/saml/SAML20TokenProvider.java 2009-08-29
07:04:54 UTC (rev 750)
+++
identity-federation/trunk/jboss-identity-fed-api/src/main/java/org/jboss/identity/federation/api/wstrust/plugins/saml/SAML20TokenProvider.java 2009-08-29
07:08:02 UTC (rev 751)
@@ -40,6 +40,7 @@
import org.jboss.identity.federation.core.saml.v2.factories.SAMLAssertionFactory;
import org.jboss.identity.federation.core.saml.v2.util.AssertionUtil;
import org.jboss.identity.federation.core.wstrust.Lifetime;
+import org.jboss.identity.federation.core.wstrust.RequestSecurityToken;
import org.jboss.identity.federation.saml.v2.assertion.AssertionType;
import org.jboss.identity.federation.saml.v2.assertion.AudienceRestrictionType;
import org.jboss.identity.federation.saml.v2.assertion.ConditionsType;
@@ -83,54 +84,7 @@
// generate an id for the new assertion.
String assertionID = IDGenerator.create("ID_");
- // lifetime and audience restrictions.
- Lifetime lifetime = context.getRequestSecurityToken().getLifetime();
- AudienceRestrictionType restriction = null;
- AppliesTo appliesTo = context.getRequestSecurityToken().getAppliesTo();
- if (appliesTo != null)
- restriction =
SAMLAssertionFactory.createAudienceRestriction(WSTrustUtil.parseAppliesTo(appliesTo));
- ConditionsType conditions =
SAMLAssertionFactory.createConditions(lifetime.getCreated(), lifetime.getExpires(),
- restriction);
-
- // TODO: implement support for the other confirmation methods.
- String confirmationMethod = SAMLUtil.SAML2_BEARER_URI;
- SubjectConfirmationType subjectConfirmation =
SAMLAssertionFactory.createSubjectConfirmation(null,
- confirmationMethod, null);
-
- // create a subject using the caller principal.
- Principal principal = context.getCallerPrincipal();
- String subjectName = principal == null ? "ANONYMOUS" :
principal.getName();
- NameIDType nameID = SAMLAssertionFactory.createNameID(null,
"urn:jboss:identity-federation", subjectName);
- SubjectType subject = SAMLAssertionFactory.createSubject(nameID,
subjectConfirmation);
-
- // TODO: add SAML statements that corresponds to the claims provided by the
requester.
-
- // create the SAML assertion.
- NameIDType issuerID = SAMLAssertionFactory.createNameID(null, null,
context.getTokenIssuer());
- AssertionType assertion = SAMLAssertionFactory.createAssertion(assertionID,
issuerID, lifetime.getCreated(),
- conditions, subject, null);
-
- // convert the constructed assertion to element.
- Element assertionElement = null;
- try
- {
- assertionElement = SAMLUtil.toElement(assertion);
- }
- catch (Exception e)
- {
- throw new WSTrustException("Failed to marshall SAMLV2 assertion", e);
- }
-
- SecurityToken token = new
StandardSecurityToken(context.getRequestSecurityToken().getTokenType().toString(),
- assertionElement, assertionID);
- context.setSecurityToken(token);
-
- // set the SAML assertion attached reference.
- KeyIdentifierType keyIdentifier =
WSTrustUtil.createKeyIdentifier(SAMLUtil.SAML2_VALUE_TYPE, "#" + assertionID);
- Map<QName, String> attributes = new HashMap<QName, String>();
- attributes.put(new QName(WSTrustConstants.WSSE11_NS, "TokenType"),
SAMLUtil.SAML2_TOKEN_TYPE);
- RequestedReferenceType attachedReference =
WSTrustUtil.createRequestedReference(keyIdentifier, attributes);
- context.setAttachedReference(attachedReference);
+ issueToken(context, assertionID);
}
/*
@@ -140,7 +94,11 @@
*/
public void renewToken(WSTrustRequestContext context) throws WSTrustException
{
- // TODO: implement renew logic.
+ Element assertion = (Element)
context.getRequestSecurityToken().getRenewTarget().getAny();
+
+ String id = assertion.getAttribute("ID");
+
+ issueToken(context, id); //Just reissue
}
/*
@@ -224,4 +182,62 @@
return element == null ? false :
"Assertion".equals(element.getLocalName())
&&
WSTrustConstants.SAML2_ASSERTION_NS.equals(element.getNamespaceURI());
}
+
+ /**
+ * Issue a SAML assertion token with the provided ID
+ * @param context
+ * @param assertionID
+ * @throws WSTrustException
+ */
+ private void issueToken(WSTrustRequestContext context, String assertionID) throws
WSTrustException
+ {
+ // lifetime and audience restrictions.
+ Lifetime lifetime = context.getRequestSecurityToken().getLifetime();
+ AudienceRestrictionType restriction = null;
+ AppliesTo appliesTo = context.getRequestSecurityToken().getAppliesTo();
+ if (appliesTo != null)
+ restriction =
SAMLAssertionFactory.createAudienceRestriction(WSTrustUtil.parseAppliesTo(appliesTo));
+ ConditionsType conditions =
SAMLAssertionFactory.createConditions(lifetime.getCreated(), lifetime.getExpires(),
+ restriction);
+
+ // TODO: implement support for the other confirmation methods.
+ String confirmationMethod = SAMLUtil.SAML2_BEARER_URI;
+ SubjectConfirmationType subjectConfirmation =
SAMLAssertionFactory.createSubjectConfirmation(null,
+ confirmationMethod, null);
+
+ // create a subject using the caller principal.
+ Principal principal = context.getCallerPrincipal();
+ String subjectName = principal == null ? "ANONYMOUS" :
principal.getName();
+ NameIDType nameID = SAMLAssertionFactory.createNameID(null,
"urn:jboss:identity-federation", subjectName);
+ SubjectType subject = SAMLAssertionFactory.createSubject(nameID,
subjectConfirmation);
+
+ // TODO: add SAML statements that corresponds to the claims provided by the
requester.
+
+ // create the SAML assertion.
+ NameIDType issuerID = SAMLAssertionFactory.createNameID(null, null,
context.getTokenIssuer());
+ AssertionType assertion = SAMLAssertionFactory.createAssertion(assertionID,
issuerID, lifetime.getCreated(),
+ conditions, subject, null);
+
+ // convert the constructed assertion to element.
+ Element assertionElement = null;
+ try
+ {
+ assertionElement = SAMLUtil.toElement(assertion);
+ }
+ catch (Exception e)
+ {
+ throw new WSTrustException("Failed to marshall SAMLV2 assertion", e);
+ }
+
+ SecurityToken token = new
StandardSecurityToken(context.getRequestSecurityToken().getTokenType().toString(),
+ assertionElement, assertionID);
+ context.setSecurityToken(token);
+
+ // set the SAML assertion attached reference.
+ KeyIdentifierType keyIdentifier =
WSTrustUtil.createKeyIdentifier(SAMLUtil.SAML2_VALUE_TYPE, "#" + assertionID);
+ Map<QName, String> attributes = new HashMap<QName, String>();
+ attributes.put(new QName(WSTrustConstants.WSSE11_NS, "TokenType"),
SAMLUtil.SAML2_TOKEN_TYPE);
+ RequestedReferenceType attachedReference =
WSTrustUtil.createRequestedReference(keyIdentifier, attributes);
+ context.setAttachedReference(attachedReference);
+ }
}
\ No newline at end of file