Author: beve
Date: 2009-09-23 03:35:32 -0400 (Wed, 23 Sep 2009)
New Revision: 805
Added:
identity-federation/trunk/jboss-identity-fed-api/src/main/java/org/jboss/identity/federation/api/wstrust/WSTrustClientConfig.java
identity-federation/trunk/jboss-identity-fed-api/src/main/java/org/jboss/identity/federation/api/wstrust/WSTrustClientFactory.java
identity-federation/trunk/jboss-identity-fed-api/src/main/java/org/jboss/identity/federation/api/wstrust/handlers/
identity-federation/trunk/jboss-identity-fed-api/src/main/java/org/jboss/identity/federation/api/wstrust/handlers/JBossSTSSaml20Handler.java
identity-federation/trunk/jboss-identity-fed-api/src/main/java/org/jboss/identity/federation/api/wstrust/handlers/JBossSTSSecurityHandler.java
identity-federation/trunk/jboss-identity-fed-api/src/test/java/org/jboss/test/identity/federation/api/wstrust/handlers/
identity-federation/trunk/jboss-identity-fed-api/src/test/java/org/jboss/test/identity/federation/api/wstrust/handlers/JBossSTSSaml20HandlerTestCase.java
identity-federation/trunk/jboss-identity-fed-api/src/test/resources/wstrust/jboss-sts-client.properties
Modified:
identity-federation/trunk/jboss-identity-fed-api/pom.xml
Log:
Work for
https://jira.jboss.org/jira/browse/JBID-194 "Add a JAX-WS SOAP Protocol
handler for JBossSTS"
Modified: identity-federation/trunk/jboss-identity-fed-api/pom.xml
===================================================================
--- identity-federation/trunk/jboss-identity-fed-api/pom.xml 2009-09-22 14:34:10 UTC (rev
804)
+++ identity-federation/trunk/jboss-identity-fed-api/pom.xml 2009-09-23 07:35:32 UTC (rev
805)
@@ -127,6 +127,12 @@
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
+ <dependency>
+ <groupId>org.mockito</groupId>
+ <artifactId>mockito-all</artifactId>
+ <version>1.8.0</version>
+ <scope>test</scope>
+ </dependency>
</dependencies>
<reporting>
Added:
identity-federation/trunk/jboss-identity-fed-api/src/main/java/org/jboss/identity/federation/api/wstrust/WSTrustClientConfig.java
===================================================================
---
identity-federation/trunk/jboss-identity-fed-api/src/main/java/org/jboss/identity/federation/api/wstrust/WSTrustClientConfig.java
(rev 0)
+++
identity-federation/trunk/jboss-identity-fed-api/src/main/java/org/jboss/identity/federation/api/wstrust/WSTrustClientConfig.java 2009-09-23
07:35:32 UTC (rev 805)
@@ -0,0 +1,242 @@
+/*
+ * JBoss, Home of Professional Open Source Copyright 2009, Red Hat Middleware
+ * LLC, and individual contributors by the @authors tag. See the copyright.txt
+ * in the distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2.1 of the License, or (at your option)
+ * any later version.
+ *
+ * This software is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this software; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA, or see the FSF
+ * site:
http://www.fsf.org.
+ */
+package org.jboss.identity.federation.api.wstrust;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Properties;
+
+/**
+ * WSTrustClientConfig has the ability to either programatically construct
+ * the configuration needed for {@link WSTrustClient} or parse a file
+ * containing the configuration parameters.
+ * <p/>
+ *
+ * <h3>Configure programatically</h3>
+ * <pre>{@code
+ *
+ * Builder builder = new WSTrustClientConfig.Builder();
+ * builder.serviceName("JBossSTS");
+ * builder.portName("JBossSTSPort");
+ * ...
+ * WSTrustClientConfig config = builder.build();
+ *
+ * }</pre>
+ *
+ * <h3>Configure from file</h3>
+ * <pre>{@code
+ *
+ * WSTrustClientConfig config = new WSTrustClientConfig.Builder().build(configFile);
+ *
+ * }</pre>
+ *
+ * @author <a href="mailto:dbevenius@jboss.com">Daniel
Bevenius</a>
+ */
+public class WSTrustClientConfig
+{
+ public static final String DEFAULT_CONFIG_FILE =
"jboss-sts-client.properties";
+
+ public static final String SERVICE_NAME = "serviceName";
+ public static final String PORT_NAME = "portName";
+ public static final String ENDPOINT_ADDRESS = "endpointAddress";
+ public static final String USERNAME = "username";
+ public static final String PASSWORD = "password";
+ public static final String TOKEN_TYPE = "tokenType";
+
+ private String serviceName;
+ private String portName;
+ private String endpointAddress;
+ private String username;
+ private String password;
+
+ private WSTrustClientConfig(final Builder builder)
+ {
+ serviceName = builder.serviceName;
+ portName = builder.portName;
+ endpointAddress = builder.endpointAddress;
+ username = builder.username;
+ password = builder.password;
+ }
+
+ public String getServiceName()
+ {
+ return serviceName;
+ }
+
+ public String getPortName()
+ {
+ return portName;
+ }
+
+ public String getEndPointAddress()
+ {
+ return endpointAddress;
+ }
+
+ public String getUsername()
+ {
+ return username;
+ }
+
+ public String getPassword()
+ {
+ return password;
+ }
+
+ public String toString()
+ {
+ return getClass().getSimpleName() + "[serviceName=" + serviceName +
", portName=" + portName + ", endpointAddress=" + endpointAddress +
"]";
+ }
+
+ public static class Builder
+ {
+ private String serviceName;
+ private String portName;
+ private String endpointAddress;
+ private String username;
+ private String password;
+
+ public Builder serviceName(final String serviceName)
+ {
+ this.serviceName = serviceName;
+ return this;
+ }
+
+ public Builder portName(final String portName)
+ {
+ this.portName = portName;
+ return this;
+ }
+
+ public Builder endpointAddress(final String address)
+ {
+ this.endpointAddress = address;
+ return this;
+ }
+
+ public Builder username(final String username)
+ {
+ this.username = username;
+ return this;
+ }
+
+ public Builder password(final String password)
+ {
+ this.password = password;
+ return this;
+ }
+
+ public WSTrustClientConfig build()
+ {
+ validate(this);
+ return new WSTrustClientConfig(this);
+ }
+
+ private void validate(Builder builder)
+ {
+ checkPropertyShowValue(serviceName, SERVICE_NAME);
+ checkPropertyShowValue(portName, PORT_NAME);
+ checkPropertyShowValue(endpointAddress, endpointAddress);
+ checkProperty(username, USERNAME);
+ checkProperty(password, PASSWORD);
+ }
+
+ private void checkPropertyShowValue(final String propertyName, final String
propertyValue)
+ {
+ if (propertyValue == null || propertyValue.equals(""))
+ throw new IllegalArgumentException(propertyName + " property must
not be null or empty was:" + propertyValue);
+ }
+
+ private void checkProperty(final String propertyName, final String
propertyValue)
+ {
+ if (propertyValue == null || propertyValue.equals(""))
+ throw new IllegalArgumentException(propertyName + " property must
not be null");
+ }
+
+ public WSTrustClientConfig build(final String configFile)
+ {
+ InputStream in = null;
+
+ try
+ {
+ in = getResource(configFile);
+ if (in == null)
+ {
+ throw new IllegalStateException("Could not find properties file
" + configFile);
+
+ }
+ final Properties properties = new Properties();
+ properties.load(in);
+ this.serviceName = properties.getProperty(SERVICE_NAME);
+ this.portName = properties.getProperty(PORT_NAME);
+ this.endpointAddress = properties.getProperty(ENDPOINT_ADDRESS);
+ this.username = properties.getProperty(USERNAME);
+ this.password = properties.getProperty(PASSWORD);
+ }
+ catch (IOException e)
+ {
+ throw new IllegalStateException("Could not load properties from
" + configFile);
+ }
+ finally
+ {
+ try
+ {
+ if (in != null)
+ in.close();
+ }
+ catch (final IOException ignored)
+ {
+ ignored.printStackTrace();
+ }
+ }
+
+ validate(this);
+ return new WSTrustClientConfig(this);
+ }
+ }
+
+ private static InputStream getResource(String resource) throws IOException
+ {
+ // Try it as a File resource...
+ final File file = new File(resource);
+
+ if (file.exists() && !file.isDirectory())
+ {
+ return new FileInputStream(file);
+ }
+ // Try it as a classpath resource ...
+ final ClassLoader threadClassLoader =
Thread.currentThread().getContextClassLoader() ;
+ if (threadClassLoader != null)
+ {
+ final InputStream is = threadClassLoader.getResourceAsStream(resource) ;
+ if (is != null)
+ {
+ return is ;
+ }
+ }
+
+ return null;
+ }
+
+}
+
Added:
identity-federation/trunk/jboss-identity-fed-api/src/main/java/org/jboss/identity/federation/api/wstrust/WSTrustClientFactory.java
===================================================================
---
identity-federation/trunk/jboss-identity-fed-api/src/main/java/org/jboss/identity/federation/api/wstrust/WSTrustClientFactory.java
(rev 0)
+++
identity-federation/trunk/jboss-identity-fed-api/src/main/java/org/jboss/identity/federation/api/wstrust/WSTrustClientFactory.java 2009-09-23
07:35:32 UTC (rev 805)
@@ -0,0 +1,50 @@
+/*
+ * JBoss, Home of Professional Open Source Copyright 2009, Red Hat Middleware
+ * LLC, and individual contributors by the @authors tag. See the copyright.txt
+ * in the distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2.1 of the License, or (at your option)
+ * any later version.
+ *
+ * This software is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this software; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA, or see the FSF
+ * site:
http://www.fsf.org.
+ */
+package org.jboss.identity.federation.api.wstrust;
+
+import org.jboss.identity.federation.api.wstrust.WSTrustClient;
+import org.jboss.identity.federation.api.wstrust.WSTrustClient.SecurityInfo;
+import org.jboss.identity.federation.core.exceptions.ParsingException;
+
+/**
+ * Simple factory for creating {@link WSTrustClient}s.
+ *
+ * @author <a href="mailto:dbevenius@jboss.com">Daniel
Bevenius</a>
+ */
+public final class WSTrustClientFactory
+{
+ private static final WSTrustClientFactory INSTANCE = new WSTrustClientFactory();
+
+ private WSTrustClientFactory()
+ {
+ }
+
+ public static WSTrustClientFactory getInstance()
+ {
+ return INSTANCE;
+ }
+
+ public WSTrustClient create(final WSTrustClientConfig c) throws ParsingException
+ {
+ return new WSTrustClient(c.getServiceName(), c.getPortName(),
c.getEndPointAddress(), new SecurityInfo(c.getUsername(), c.getPassword()));
+ }
+}
+
Added:
identity-federation/trunk/jboss-identity-fed-api/src/main/java/org/jboss/identity/federation/api/wstrust/handlers/JBossSTSSaml20Handler.java
===================================================================
---
identity-federation/trunk/jboss-identity-fed-api/src/main/java/org/jboss/identity/federation/api/wstrust/handlers/JBossSTSSaml20Handler.java
(rev 0)
+++
identity-federation/trunk/jboss-identity-fed-api/src/main/java/org/jboss/identity/federation/api/wstrust/handlers/JBossSTSSaml20Handler.java 2009-09-23
07:35:32 UTC (rev 805)
@@ -0,0 +1,67 @@
+/*
+ * JBoss, Home of Professional Open Source Copyright 2009, Red Hat Middleware
+ * LLC, and individual contributors by the @authors tag. See the copyright.txt
+ * in the distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2.1 of the License, or (at your option)
+ * any later version.
+ *
+ * This software is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this software; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA, or see the FSF
+ * site:
http://www.fsf.org.
+ */
+package org.jboss.identity.federation.api.wstrust.handlers;
+
+import static org.jboss.identity.federation.core.wstrust.WSTrustConstants.WSSE_NS;
+import static
org.jboss.identity.federation.core.wstrust.WSTrustConstants.SAML2_ASSERTION_NS;
+import javax.xml.namespace.QName;
+
+
+/**
+ * A concrete implementation of {@link JBossSTSSecurityHandler} that can
+ * handle SAML version 2.0 Assertion inside of {@link WSTrustConstants#WSSE_NS} elements
+ * <p/>
+ *
+ * @author <a href="mailto:dbevenius@jboss.com">Daniel
Bevenius</a>
+ */
+public class JBossSTSSaml20Handler extends JBossSTSSecurityHandler
+{
+ /**
+ * Qualified name for WSSE Security Header ({@link
WSTrustConstants#WSSE_NS}:"Security")
+ */
+ public static final QName SECURITY_QNAME = new QName(WSSE_NS, "Security");
+
+ /**
+ * Qualified name for SAML Version 2.0 ({@link
WSTrustConstants#SAML2_ASSERTION_NS}:"Assertion")
+ */
+ public static final QName SAML_TOKEN_QNAME = new QName(SAML2_ASSERTION_NS,
"Assertion");
+
+ /*
+ * (non-Javadoc)
+ * @see
org.jboss.identity.federation.api.wstrust.handlers.JBossSTSSecurityHandler#getSecurityElementQName()
+ */
+ @Override
+ public QName getSecurityElementQName()
+ {
+ return SECURITY_QNAME;
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see
org.jboss.identity.federation.api.wstrust.handlers.JBossSTSSecurityHandler#getTokenElementQName()
+ */
+ @Override
+ public QName getTokenElementQName()
+ {
+ return SAML_TOKEN_QNAME;
+ }
+
+}
Added:
identity-federation/trunk/jboss-identity-fed-api/src/main/java/org/jboss/identity/federation/api/wstrust/handlers/JBossSTSSecurityHandler.java
===================================================================
---
identity-federation/trunk/jboss-identity-fed-api/src/main/java/org/jboss/identity/federation/api/wstrust/handlers/JBossSTSSecurityHandler.java
(rev 0)
+++
identity-federation/trunk/jboss-identity-fed-api/src/main/java/org/jboss/identity/federation/api/wstrust/handlers/JBossSTSSecurityHandler.java 2009-09-23
07:35:32 UTC (rev 805)
@@ -0,0 +1,266 @@
+/*
+ * JBoss, Home of Professional Open Source Copyright 2009, Red Hat Middleware
+ * LLC, and individual contributors by the @authors tag. See the copyright.txt
+ * in the distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2.1 of the License, or (at your option)
+ * any later version.
+ *
+ * This software is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this software; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA, or see the FSF
+ * site:
http://www.fsf.org.
+ */
+package org.jboss.identity.federation.api.wstrust.handlers;
+
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.Set;
+
+import javax.annotation.PostConstruct;
+import javax.annotation.Resource;
+import javax.xml.namespace.QName;
+import javax.xml.soap.SOAPException;
+import javax.xml.soap.SOAPHeader;
+import javax.xml.soap.SOAPHeaderElement;
+import javax.xml.ws.WebServiceException;
+import javax.xml.ws.handler.MessageContext;
+import javax.xml.ws.handler.soap.SOAPHandler;
+import javax.xml.ws.handler.soap.SOAPMessageContext;
+
+import org.jboss.identity.federation.api.wstrust.WSTrustClient;
+import org.jboss.identity.federation.api.wstrust.WSTrustClientConfig;
+import org.jboss.identity.federation.api.wstrust.WSTrustClientFactory;
+import org.jboss.identity.federation.core.exceptions.ParsingException;
+import org.jboss.identity.federation.core.wstrust.WSTrustException;
+import org.w3c.dom.Element;
+
+/**
+ * JBossSTSSecurityHandler is a server-side JAX-WS SOAP Protocol handler that will
extract
+ * a Security Token from the SOAP Security Header and validate the token with JBoss
Security
+ * Token Service (STS)
+ * <p/>
+ *
+ * <h3>Concrete implementations</h3>
+ * Subclasses a required to implement two methods:
+ * <ul>
+ * <li> {@link #getSecurityElementQName()}
+ * This should return the qualified name of the security header. This lets us support
+ * different versions. </li>
+ *
+ * <li>{@link #getTokenElementQName()}
+ * This should return the qualified name of the security token element that should
exist
+ * in the security header. This lets us support different tokens that can be
validated
+ * with JBossSTS.</li>
+ * </ul>
+ *
+ * This class is abstract to simpify is usage as the intention is for a handler to be
specified
+ * in a server side handler chain. Here different Security Header specifications and
security token
+ * specifications can be specified using class names instead of using properties which
would force
+ * users to finding and setting the correct namespaces. Hopefully this will be easier and
less
+ * error prone.
+ *
+ * handlerchain.xml example:
+ * <pre>{@code
+ * <?xml version="1.0" encoding="UTF-8"?>
+ * <jws:handler-config
xmlns:jws="http://java.sun.com/xml/ns/javaee">
+ * <jws:handler-chains>
+ * <jws:handler-chain>
+ * <jws:handler>
+ *
<jws:handler-class>org.jboss.identity.federation.api.wstrust.handlers.JBossSTSSaml20Handler</jws:handler-class>
+ * </jws:handler>
+ * </jws:handler-chain>
+ * </jws:handler-chains>
+ * </jws:handler-config>
+ * }</pre>
+ * <p/>
+ *
+ * <h3>Configuration</h3>
+ * This class uses {@link WSTrustClient} to interact with JBossSTS. By default the
configuration
+ * properties are set in a file named {@link WSTrustClientConfig#DEFAULT_CONFIG_FILE}.
+ * This can be overridden by specifying environment entries in a deployment descriptor.
+ *
+ * For example in web.xml:
+ * <pre>{@code
+ * <env-entry>
+ * <env-entry-name>JBossSTSClientConfig</env-entry-name>
+ * <env-entry-type>java.lang.String</env-entry-type>
+ * <env-entry-value>/jboss-sts-client.properties</env-entry-value>
+ * </env-entry>
+ * }</pre>
+ *
+ *
+ * @author <a href="mailto:dbevenius@jboss.com">Daniel
Bevenius</a>
+ */
+public abstract class JBossSTSSecurityHandler implements
SOAPHandler<SOAPMessageContext>
+{
+ /**
+ * The path to the jboss-sts-client.properties file.
+ */
+ private String configFile = WSTrustClientConfig.DEFAULT_CONFIG_FILE;
+
+ /**
+ * The {@link WSTrustClient client} that will call JBossSTS.
+ */
+ private WSTrustClient wsTrustClient;
+
+ /**
+ * Subclasses can return the QName of the Security header element in usage.
+ *
+ * @return QName
+ */
+ public abstract QName getSecurityElementQName();
+
+ /**
+ * Subclasses can return the QName of the Security Element that should be used
+ * as the token for validation.
+ *
+ * @return QName
+ */
+ public abstract QName getTokenElementQName();
+
+
+ /**
+ * Post constuct will be called when the handler is deployed.
+ *
+ * @throws WebServiceException
+ */
+ @PostConstruct
+ public void createWSTrustClient() throws WebServiceException
+ {
+ if (wsTrustClient == null)
+ {
+ try
+ {
+ final WSTrustClientConfig config = new
WSTrustClientConfig.Builder().build(configFile);
+ wsTrustClient = WSTrustClientFactory.getInstance().create(config);
+ }
+ catch (final ParsingException e)
+ {
+ throw new WebServiceException(e.getMessage(), e);
+ }
+ }
+ }
+
+ /**
+ * Will process in-bound messages and extract a security token from the SOAP Header.
This token
+ * will then be validated using by calling JBossSTS.
+ *
+ * @param messageContext The {@link SOAPMessageContext messageContext}.
+ * @return true If the security token was correctly validated or if this call was an
outbound message.
+ * @throws WebServiceException If the security token could not be validated.
+ */
+ public boolean handleMessage(final SOAPMessageContext messageContext)
+ {
+ if (isOutBound(messageContext))
+ {
+ return true;
+ }
+
+ try
+ {
+ final Element securityToken = extractSecurityToken(messageContext,
getSecurityElementQName(), getTokenElementQName());
+
+ if (wsTrustClient.validateToken(securityToken))
+ {
+ return true;
+ }
+ else
+ {
+ throw new WebServiceException("Could not validate security token
"+ securityToken);
+ }
+ }
+ catch (final SOAPException e)
+ {
+ throw new WebServiceException(e.getMessage(), e);
+ }
+ catch (final WSTrustException e)
+ {
+ throw new WebServiceException(e.getMessage(), e);
+ }
+ }
+
+ /**
+ * Allows the {@link WSTrustClient} to be injected if required.
+ *
+ * @param client The WSTrustClient to be used by this handler.
+ */
+ public void setWSTrustClient(final WSTrustClient client)
+ {
+ wsTrustClient = client;
+ }
+
+
+ public Set<QName> getHeaders()
+ {
+ return Collections.singleton(getSecurityElementQName());
+ }
+
+ /**
+ *
+ */
+ public boolean handleFault(final SOAPMessageContext messageContext)
+ {
+ return true;
+ }
+
+ public void close(final MessageContext messageContext)
+ {
+ // NoOp.
+ }
+
+ /**
+ * This setter enables the injection of the jboss-sts-client.properties file
+ * path.
+ *
+ * Note: This resource injection does not work with AS4.2.3 but with AS 5.1.0 this
works as expected.
+ *
+ * @param configFile
+ */
+ @Resource (name = "JBossSTSClientConfig")
+ public void setConfigFile(final String configFile)
+ {
+ if (configFile != null)
+ {
+ this.configFile = configFile;
+ }
+ }
+
+ private boolean isOutBound(final SOAPMessageContext messageContext)
+ {
+ return ((Boolean)
messageContext.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY)).booleanValue();
+ }
+
+ @SuppressWarnings("unchecked")
+ private Element extractSecurityToken(final SOAPMessageContext messageContext, final
QName securityQName, final QName tokenQName) throws SOAPException
+ {
+ if (securityQName == null)
+ throw new IllegalStateException("securityQName from subclass cannot be
null!");
+ if (tokenQName == null)
+ throw new IllegalStateException("tokenQName from subclass cannot be
null!");
+
+ final SOAPHeader soapHeader = messageContext.getMessage().getSOAPHeader();
+ final Iterator securityHeaders = soapHeader.getChildElements(securityQName);
+ while (securityHeaders.hasNext())
+ {
+ final SOAPHeaderElement elem = (SOAPHeaderElement) securityHeaders.next();
+ // Check if the header is equal to the one this Handler is configured for.
+ if (elem.getElementQName().equals(securityQName))
+ {
+ final Iterator childElements = elem.getChildElements(tokenQName);
+ while (childElements.hasNext())
+ {
+ return (Element) childElements.next();
+ }
+ }
+ }
+ return null;
+ }
+}
Added:
identity-federation/trunk/jboss-identity-fed-api/src/test/java/org/jboss/test/identity/federation/api/wstrust/handlers/JBossSTSSaml20HandlerTestCase.java
===================================================================
---
identity-federation/trunk/jboss-identity-fed-api/src/test/java/org/jboss/test/identity/federation/api/wstrust/handlers/JBossSTSSaml20HandlerTestCase.java
(rev 0)
+++
identity-federation/trunk/jboss-identity-fed-api/src/test/java/org/jboss/test/identity/federation/api/wstrust/handlers/JBossSTSSaml20HandlerTestCase.java 2009-09-23
07:35:32 UTC (rev 805)
@@ -0,0 +1,153 @@
+/*
+ * JBoss, Home of Professional Open Source Copyright 2009, Red Hat Middleware
+ * LLC, and individual contributors by the @authors tag. See the copyright.txt
+ * in the distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2.1 of the License, or (at your option)
+ * any later version.
+ *
+ * This software is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this software; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA, or see the FSF
+ * site:
http://www.fsf.org.
+ */
+package org.jboss.test.identity.federation.api.wstrust.handlers;
+
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import javax.xml.namespace.QName;
+import javax.xml.soap.MessageFactory;
+import javax.xml.soap.SOAPElement;
+import javax.xml.soap.SOAPException;
+import javax.xml.soap.SOAPHeader;
+import javax.xml.soap.SOAPHeaderElement;
+import javax.xml.soap.SOAPMessage;
+import javax.xml.ws.WebServiceException;
+import javax.xml.ws.handler.MessageContext;
+import javax.xml.ws.handler.soap.SOAPMessageContext;
+
+import junit.framework.TestCase;
+
+import org.jboss.identity.federation.api.wstrust.WSTrustClient;
+import org.jboss.identity.federation.api.wstrust.handlers.JBossSTSSaml20Handler;
+import org.jboss.identity.federation.api.wstrust.handlers.JBossSTSSecurityHandler;
+import org.w3c.dom.Element;
+
+/**
+ * Unit test for {@link JBossSTSSaml20Handler}.
+ *
+ * @author <a href="mailto:dbevenius@jboss.com">Daniel
Bevenius</a>
+ *
+ */
+public class JBossSTSSaml20HandlerTestCase extends TestCase
+{
+ private SOAPMessageContext soapMessageContext;
+ private SOAPMessage soapMessage;
+ private WSTrustClient wsTrustClient;
+ private JBossSTSSaml20Handler samlHandler;
+
+ public void testHandleMessageOutbound() throws SOAPException
+ {
+ setOutbound(soapMessageContext, true);
+ assertTrue(new JBossSTSSaml20Handler().handleMessage(soapMessageContext));
+ }
+
+ public void testHandleMessageInboundValidToken() throws Exception
+ {
+ final SOAPHeader soapHeader = soapMessage.getSOAPHeader();
+
+ // Make the Mocked WSTrustClient validateToken method return true.
+ when(wsTrustClient.validateToken((any(Element.class)))).thenReturn(true);
+
+ final SOAPHeaderElement securityHeader = addSecurityHeader(samlHandler,
soapHeader);
+ addAssertionElement(samlHandler, securityHeader);
+
+ setOutbound(soapMessageContext, false);
+ setMessageOnContext(soapMessageContext, soapMessage);
+
+ boolean result = samlHandler.handleMessage(soapMessageContext);
+ assertTrue(result);
+ }
+
+ public void testHandleMessageInValidToken() throws Exception
+ {
+ final SOAPHeader soapHeader = soapMessage.getSOAPHeader();
+
+ // Make the Mocked WSTrustClient validateToken method return false.
+ when(wsTrustClient.validateToken((any(Element.class)))).thenReturn(false);
+
+ final SOAPHeaderElement securityHeader = addSecurityHeader(samlHandler,
soapHeader);
+ addAssertionElement(samlHandler, securityHeader);
+
+ setOutbound(soapMessageContext, false);
+ setMessageOnContext(soapMessageContext, soapMessage);
+ try
+ {
+ samlHandler.handleMessage(soapMessageContext);
+ fail("handleMessage should have thrown a exception!");
+ }
+ catch(final Exception e)
+ {
+ assertTrue (e instanceof WebServiceException);
+ }
+ }
+
+ public void setUp()
+ {
+ // Create a Mock for WSTrustClient.
+ wsTrustClient = mock(WSTrustClient.class);
+
+ samlHandler = new JBossSTSSaml20Handler();
+ // Set the WSTrustClient to our mocked client.
+ samlHandler.setWSTrustClient(wsTrustClient);
+ // Simulate the WS Engine calling @PostConstruct.
+ samlHandler.createWSTrustClient();
+
+ soapMessageContext = mock(SOAPMessageContext.class);
+
+ try
+ {
+ soapMessage = MessageFactory.newInstance().createMessage();
+ }
+ catch (SOAPException e)
+ {
+ e.printStackTrace();
+ fail(e.getMessage());
+ }
+ }
+ private SOAPHeaderElement addSecurityHeader(final JBossSTSSecurityHandler handler,
final SOAPHeader soapHeader) throws SOAPException
+ {
+ final QName securityQName = handler.getSecurityElementQName();
+ final SOAPHeaderElement securityHeader = soapHeader.addHeaderElement(new
QName(securityQName.getNamespaceURI(), securityQName.getLocalPart(), "wsse"));
+ soapHeader.addChildElement(securityHeader);
+ return securityHeader;
+ }
+
+ private SOAPElement addAssertionElement(final JBossSTSSecurityHandler handler, final
SOAPHeaderElement securityHeader) throws SOAPException
+ {
+ final QName tokenElementQName = handler.getTokenElementQName();
+ final SOAPElement tokenElement = securityHeader.addChildElement(new
QName(tokenElementQName.getNamespaceURI(), tokenElementQName.getLocalPart(),
"saml"));
+ return securityHeader.addChildElement(tokenElement);
+ }
+
+ private void setMessageOnContext(final SOAPMessageContext messageContext, final
SOAPMessage soapMessage)
+ {
+ when(messageContext.getMessage()).thenReturn(soapMessage);
+ }
+
+ private void setOutbound(MessageContext messageContext, boolean outbound)
+ {
+
when(messageContext.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY)).thenReturn(outbound);
+ }
+
+}
+
Added:
identity-federation/trunk/jboss-identity-fed-api/src/test/resources/wstrust/jboss-sts-client.properties
===================================================================
---
identity-federation/trunk/jboss-identity-fed-api/src/test/resources/wstrust/jboss-sts-client.properties
(rev 0)
+++
identity-federation/trunk/jboss-identity-fed-api/src/test/resources/wstrust/jboss-sts-client.properties 2009-09-23
07:35:32 UTC (rev 805)
@@ -0,0 +1,5 @@
+serviceName=JBossSTS
+portName=JBossSTSPort
+endpointAddress=http://localhost:8080/jboss-sts/JBossSTS
+username=admin
+password=admin