Author: sguilhen(a)redhat.com
Date: 2010-01-07 14:18:07 -0500 (Thu, 07 Jan 2010)
New Revision: 1097
Modified:
migration/picketlink/federation/trunk/picketlink-fed-core/src/main/java/org/picketlink/identity/federation/core/wstrust/StandardRequestHandler.java
migration/picketlink/federation/trunk/picketlink-fed-core/src/main/java/org/picketlink/identity/federation/core/wstrust/WSTrustJAXBFactory.java
migration/picketlink/federation/trunk/picketlink-fed-core/src/test/java/org/picketlink/test/identity/federation/core/wstrust/PicketLinkSTSUnitTestCase.java
Log:
JBID-233: request handler now checks for empty targets (cancel/renew/validate) to avoid
NPEs. Tests have been added to PicketLinkSTSUnitTestCase to verify that the expected
exceptions are raised when invalid requests are made to the STS
Modified:
migration/picketlink/federation/trunk/picketlink-fed-core/src/main/java/org/picketlink/identity/federation/core/wstrust/StandardRequestHandler.java
===================================================================
---
migration/picketlink/federation/trunk/picketlink-fed-core/src/main/java/org/picketlink/identity/federation/core/wstrust/StandardRequestHandler.java 2009-12-17
17:15:36 UTC (rev 1096)
+++
migration/picketlink/federation/trunk/picketlink-fed-core/src/main/java/org/picketlink/identity/federation/core/wstrust/StandardRequestHandler.java 2010-01-07
19:18:07 UTC (rev 1097)
@@ -292,9 +292,18 @@
if (trace)
log.trace("Validating token for renew request " +
request.getContext());
if (request.getRenewTargetElement() == null)
- throw new WSTrustException("Unable to renew token: renew target is
null");
+ throw new WSTrustException("Unable to renew token: request does not have a
renew target");
Node securityToken = request.getRenewTargetElement().getFirstChild();
+ if (securityToken == null)
+ throw new WSTrustException("Unable to renew token: security token is
null");
+
+ SecurityTokenProvider provider =
this.configuration.getProviderForTokenElementNS(securityToken.getLocalName(),
+ securityToken.getNamespaceURI());
+ if (provider == null)
+ throw new WSTrustException("No SecurityTokenProvider configured for "
+ securityToken.getNamespaceURI() + ":"
+ + securityToken.getLocalName());
+
if (this.configuration.signIssuedToken() &&
this.configuration.getSTSKeyPair() != null)
{
KeyPair keyPair = this.configuration.getSTSKeyPair();
@@ -329,11 +338,6 @@
// create a context and dispatch to the proper security token provider for
renewal.
WSTrustRequestContext context = new WSTrustRequestContext(request,
callerPrincipal);
- SecurityTokenProvider provider =
this.configuration.getProviderForTokenElementNS(securityToken.getLocalName(),
- securityToken.getNamespaceURI());
- if (provider == null)
- throw new WSTrustException("No SecurityTokenProvider configured for "
+ securityToken.getNamespaceURI() + ":"
- + securityToken.getLocalName());
provider.renewToken(context);
// create the WS-Trust response with the renewed token.
@@ -368,12 +372,15 @@
throw new IllegalArgumentException("Request does not contain the DOM
Document");
if (request.getValidateTargetElement() == null)
- throw new WSTrustException("Unable to validate token: validate target is
null");
+ throw new WSTrustException("Unable to validate token: request does not have
a validate target");
if (request.getTokenType() == null)
request.setTokenType(URI.create(WSTrustConstants.STATUS_TYPE));
Node securityToken = request.getValidateTargetElement().getFirstChild();
+ if (securityToken == null)
+ throw new WSTrustException("Unable to validate token: security token is
null");
+
SecurityTokenProvider provider =
this.configuration.getProviderForTokenElementNS(securityToken.getLocalName(),
securityToken.getNamespaceURI());
if (provider == null)
@@ -455,10 +462,13 @@
if (rstDocument == null)
throw new IllegalArgumentException("Request does not contain the DOM
Document");
if (request.getCancelTargetElement() == null)
- throw new WSTrustException("Illegal cancel request: cancel target is
null");
+ throw new WSTrustException("Unable to cancel token: request does not have a
cancel target");
// obtain the token provider that will handle the request.
Node securityToken = request.getCancelTargetElement().getFirstChild();
+ if (securityToken == null)
+ throw new WSTrustException("Unable to cancel token: security token is
null");
+
SecurityTokenProvider provider =
this.configuration.getProviderForTokenElementNS(securityToken.getLocalName(),
securityToken.getNamespaceURI());
if (provider == null)
Modified:
migration/picketlink/federation/trunk/picketlink-fed-core/src/main/java/org/picketlink/identity/federation/core/wstrust/WSTrustJAXBFactory.java
===================================================================
---
migration/picketlink/federation/trunk/picketlink-fed-core/src/main/java/org/picketlink/identity/federation/core/wstrust/WSTrustJAXBFactory.java 2009-12-17
17:15:36 UTC (rev 1096)
+++
migration/picketlink/federation/trunk/picketlink-fed-core/src/main/java/org/picketlink/identity/federation/core/wstrust/WSTrustJAXBFactory.java 2010-01-07
19:18:07 UTC (rev 1097)
@@ -220,17 +220,17 @@
Element targetElement = null;
// if the request has a validate, cancel, or renew target, we must preserve it from
JAXB marshaling.
String requestType = request.getRequestType().toString();
- if (requestType.equalsIgnoreCase(WSTrustConstants.VALIDATE_REQUEST))
+ if (requestType.equalsIgnoreCase(WSTrustConstants.VALIDATE_REQUEST) &&
request.getValidateTarget() != null)
{
targetElement = (Element) request.getValidateTarget().getAny();
request.getValidateTarget().setAny(null);
}
- else if (requestType.equalsIgnoreCase(WSTrustConstants.RENEW_REQUEST))
+ else if (requestType.equalsIgnoreCase(WSTrustConstants.RENEW_REQUEST) &&
request.getRenewTarget() != null)
{
targetElement = (Element) request.getRenewTarget().getAny();
request.getRenewTarget().setAny(null);
}
- else if (requestType.equalsIgnoreCase(WSTrustConstants.CANCEL_REQUEST))
+ else if (requestType.equalsIgnoreCase(WSTrustConstants.CANCEL_REQUEST) &&
request.getCancelTarget() != null)
{
targetElement = (Element) request.getCancelTarget().getAny();
request.getCancelTarget().setAny(null);
Modified:
migration/picketlink/federation/trunk/picketlink-fed-core/src/test/java/org/picketlink/test/identity/federation/core/wstrust/PicketLinkSTSUnitTestCase.java
===================================================================
---
migration/picketlink/federation/trunk/picketlink-fed-core/src/test/java/org/picketlink/test/identity/federation/core/wstrust/PicketLinkSTSUnitTestCase.java 2009-12-17
17:15:36 UTC (rev 1096)
+++
migration/picketlink/federation/trunk/picketlink-fed-core/src/test/java/org/picketlink/test/identity/federation/core/wstrust/PicketLinkSTSUnitTestCase.java 2010-01-07
19:18:07 UTC (rev 1097)
@@ -38,6 +38,8 @@
import junit.framework.TestCase;
import org.picketlink.identity.federation.core.exceptions.ConfigurationException;
+import org.picketlink.identity.federation.core.saml.v2.common.IDGenerator;
+import org.picketlink.identity.federation.core.saml.v2.util.DocumentUtil;
import org.picketlink.identity.federation.core.wstrust.PicketLinkSTS;
import org.picketlink.identity.federation.core.wstrust.STSConfiguration;
import org.picketlink.identity.federation.core.wstrust.SecurityTokenProvider;
@@ -79,6 +81,7 @@
import org.picketlink.identity.xmlsec.w3.xmldsig.KeyInfoType;
import org.picketlink.identity.xmlsec.w3.xmldsig.X509DataType;
import org.picketlink.identity.xmlsec.w3.xmlenc.EncryptedKeyType;
+import org.w3c.dom.Document;
import org.w3c.dom.Element;
/**
@@ -730,6 +733,232 @@
/**
* <p>
+ * This test verifies if the token service is correctly identifying invalid issue
requests.
+ * </p>
+ *
+ * @throws Exception if an error occurs while running the test.
+ */
+ public void testInvalidIssueRequests() throws Exception
+ {
+ // lets create an issue request that container neither an applies-to nor a token
type.
+ RequestSecurityToken request = this.createRequest("testcontext",
WSTrustConstants.ISSUE_REQUEST, null, null);
+ WSTrustJAXBFactory factory = WSTrustJAXBFactory.getInstance();
+ Source requestMessage = factory.marshallRequestSecurityToken(request);
+
+ // invoke the token service. A WSTrustException should be raised.
+ try
+ {
+ this.tokenService.invoke(requestMessage);
+ fail("An exception should have been raised by the security token
service");
+ }
+ catch (WebServiceException we)
+ {
+ assertNotNull("Unexpected null cause", we.getCause());
+ assertTrue("Unexpected cause type", we.getCause() instanceof
WSTrustException);
+ assertEquals("Either AppliesTo or TokenType must be present in a security
token request", we.getCause()
+ .getMessage());
+ }
+
+ // a request that asks for a public key to be used as proof key will fail if the
public key is not available.
+ request.setTokenType(URI.create(SAMLUtil.SAML2_TOKEN_TYPE));
+ request.setKeyType(URI.create(WSTrustConstants.KEY_TYPE_PUBLIC));
+ requestMessage = factory.marshallRequestSecurityToken(request);
+
+ try
+ {
+ this.tokenService.invoke(requestMessage);
+ fail("An exception should have been raised by the security token
service");
+ }
+ catch (WebServiceException we)
+ {
+ assertNotNull("Unexpected null cause", we.getCause());
+ assertTrue("Unexpected cause type", we.getCause() instanceof
WSTrustException);
+ assertEquals("Unexpected exception message", "Unable to locate
client public key", we.getCause().getMessage());
+ }
+ }
+
+ /**
+ * <p>
+ * This test verifies if the token service is correctly identifying invalid renew
requests.
+ * </p>
+ *
+ * @throws Exception if an error occurs while running the test.
+ */
+ public void testInvalidRenewRequests() throws Exception
+ {
+ // first create a request that doesn't have a renew target element.
+ RequestSecurityToken request = this.createRequest("renewcontext",
WSTrustConstants.RENEW_REQUEST,
+ SAMLUtil.SAML2_TOKEN_TYPE, null);
+ WSTrustJAXBFactory factory = WSTrustJAXBFactory.getInstance();
+ Source requestMessage = factory.marshallRequestSecurityToken(request);
+
+ // invoke the token service.
+ try
+ {
+ this.tokenService.invoke(requestMessage);
+ fail("An exception should have been raised by the security token
service");
+ }
+ catch (WebServiceException we)
+ {
+ assertNotNull("Unexpected null cause", we.getCause());
+ assertTrue("Unexpected cause type", we.getCause() instanceof
WSTrustException);
+ assertEquals("Unable to renew token: request does not have a renew
target", we.getCause().getMessage());
+ }
+
+ // a request with an empty renew target should also result in a failure.
+ request.setRenewTarget(new RenewTargetType());
+ requestMessage = factory.marshallRequestSecurityToken(request);
+ try
+ {
+ this.tokenService.invoke(requestMessage);
+ fail("An exception should have been raised by the security token
service");
+ }
+ catch (WebServiceException we)
+ {
+ assertNotNull("Unexpected null cause", we.getCause());
+ assertTrue("Unexpected cause type", we.getCause() instanceof
WSTrustException);
+ assertEquals("Unable to renew token: security token is null",
we.getCause().getMessage());
+ }
+
+ // a request to renew an unknown token (i.e. there's no provider can handle the
token) should also fail.
+ request.getRenewTarget().setAny(this.createUnknownToken());
+ requestMessage = factory.marshallRequestSecurityToken(request);
+ try
+ {
+ this.tokenService.invoke(requestMessage);
+ fail("An exception should have been raised by the security token
service");
+ }
+ catch (WebServiceException we)
+ {
+ assertNotNull("Unexpected null cause", we.getCause());
+ assertTrue("Unexpected cause type", we.getCause() instanceof
WSTrustException);
+ assertEquals("No SecurityTokenProvider configured for
http://www.unknowntoken.org:UnknownToken",
+ we.getCause().getMessage());
+ }
+ }
+
+ /**
+ * <p>
+ * This test verifies if the token service is correctly identifying invalid validate
requests.
+ * </p>
+ *
+ * @throws Exception if an error occurs while running the test.
+ */
+ public void testInvalidValidateRequests() throws Exception
+ {
+ // first create a request that doesn't have a validate target element.
+ RequestSecurityToken request = this.createRequest("validatecontext",
WSTrustConstants.VALIDATE_REQUEST,
+ SAMLUtil.SAML2_TOKEN_TYPE, null);
+ WSTrustJAXBFactory factory = WSTrustJAXBFactory.getInstance();
+ Source requestMessage = factory.marshallRequestSecurityToken(request);
+
+ // invoke the token service.
+ try
+ {
+ this.tokenService.invoke(requestMessage);
+ fail("An exception should have been raised by the security token
service");
+ }
+ catch (WebServiceException we)
+ {
+ assertNotNull("Unexpected null cause", we.getCause());
+ assertTrue("Unexpected cause type", we.getCause() instanceof
WSTrustException);
+ assertEquals("Unable to validate token: request does not have a validate
target", we.getCause().getMessage());
+ }
+
+ // a request with an empty validate target should also result in a failure.
+ request.setValidateTarget(new ValidateTargetType());
+ requestMessage = factory.marshallRequestSecurityToken(request);
+ try
+ {
+ this.tokenService.invoke(requestMessage);
+ fail("An exception should have been raised by the security token
service");
+ }
+ catch (WebServiceException we)
+ {
+ assertNotNull("Unexpected null cause", we.getCause());
+ assertTrue("Unexpected cause type", we.getCause() instanceof
WSTrustException);
+ assertEquals("Unable to validate token: security token is null",
we.getCause().getMessage());
+ }
+
+ // a request to validate an unknown token (i.e. there's no provider can handle
the token) should also fail.
+ request.getValidateTarget().setAny(this.createUnknownToken());
+ requestMessage = factory.marshallRequestSecurityToken(request);
+ try
+ {
+ this.tokenService.invoke(requestMessage);
+ fail("An exception should have been raised by the security token
service");
+ }
+ catch (WebServiceException we)
+ {
+ assertNotNull("Unexpected null cause", we.getCause());
+ assertTrue("Unexpected cause type", we.getCause() instanceof
WSTrustException);
+ assertEquals("No SecurityTokenProvider configured for
http://www.unknowntoken.org:UnknownToken",
+ we.getCause().getMessage());
+ }
+ }
+
+ /**
+ * <p>
+ * This test verifies if the token service is correctly identifying invalid cancel
requests.
+ * </p>
+ *
+ * @throws Exception if an error occurs while running the test.
+ */
+ public void testInvalidCancelRequests() throws Exception
+ {
+ // first create a request that doesn't have a cancel target element.
+ RequestSecurityToken request = this.createRequest("cancelcontext",
WSTrustConstants.CANCEL_REQUEST,
+ SAMLUtil.SAML2_TOKEN_TYPE, null);
+ WSTrustJAXBFactory factory = WSTrustJAXBFactory.getInstance();
+ Source requestMessage = factory.marshallRequestSecurityToken(request);
+
+ // invoke the token service.
+ try
+ {
+ this.tokenService.invoke(requestMessage);
+ fail("An exception should have been raised by the security token
service");
+ }
+ catch (WebServiceException we)
+ {
+ assertNotNull("Unexpected null cause", we.getCause());
+ assertTrue("Unexpected cause type", we.getCause() instanceof
WSTrustException);
+ assertEquals("Unable to cancel token: request does not have a cancel
target", we.getCause().getMessage());
+ }
+
+ // a request with an empty cancel target should also result in a failure.
+ request.setCancelTarget(new CancelTargetType());
+ requestMessage = factory.marshallRequestSecurityToken(request);
+ try
+ {
+ this.tokenService.invoke(requestMessage);
+ fail("An exception should have been raised by the security token
service");
+ }
+ catch (WebServiceException we)
+ {
+ assertNotNull("Unexpected null cause", we.getCause());
+ assertTrue("Unexpected cause type", we.getCause() instanceof
WSTrustException);
+ assertEquals("Unable to cancel token: security token is null",
we.getCause().getMessage());
+ }
+
+ // a request to cancel an unknown token (i.e. there's no provider can handle
the token) should also fail.
+ request.getCancelTarget().setAny(this.createUnknownToken());
+ requestMessage = factory.marshallRequestSecurityToken(request);
+ try
+ {
+ this.tokenService.invoke(requestMessage);
+ fail("An exception should have been raised by the security token
service");
+ }
+ catch (WebServiceException we)
+ {
+ assertNotNull("Unexpected null cause", we.getCause());
+ assertTrue("Unexpected cause type", we.getCause() instanceof
WSTrustException);
+ assertEquals("No SecurityTokenProvider configured for
http://www.unknowntoken.org:UnknownToken",
+ we.getCause().getMessage());
+ }
+ }
+
+ /**
+ * <p>
* Validates the contents of a WS-Trust response message that contains a custom token
issued by the test {@code
* SpecialTokenProvider}.
* </p>
@@ -923,6 +1152,26 @@
/**
* <p>
+ * Creates a simple token that is not known to the STS for testing purposes.
+ * </p>
+ *
+ * @return an {@code Element} representing the unknown token.
+ * @throws Exception if an error occurs while creating the token.
+ */
+ private Element createUnknownToken() throws Exception
+ {
+ Document doc = DocumentUtil.createDocument();
+ String namespaceURI = "http://www.unknowntoken.org";
+ Element root = doc.createElementNS(namespaceURI, "token:UnknownToken");
+ root.appendChild(doc.createTextNode("Unknown content"));
+ String id = IDGenerator.create("ID_");
+ root.setAttributeNS(namespaceURI, "ID", id);
+
+ return root;
+ }
+
+ /**
+ * <p>
* Helper class that exposes the PicketLinkSTS methods as public for the tests to
work.
* </p>
*