Author: beve
Date: 2009-10-30 06:05:58 -0400 (Fri, 30 Oct 2009)
New Revision: 886
Added:
identity-federation/trunk/jboss-identity-fed-core/src/main/java/org/jboss/identity/federation/core/wstrust/SamlCredential.java
identity-federation/trunk/jboss-identity-fed-core/src/main/java/org/jboss/identity/federation/core/wstrust/auth/
identity-federation/trunk/jboss-identity-fed-core/src/main/java/org/jboss/identity/federation/core/wstrust/auth/AbstractSTSLoginModule.java
identity-federation/trunk/jboss-identity-fed-core/src/main/java/org/jboss/identity/federation/core/wstrust/auth/STSIssuingLoginModule.java
identity-federation/trunk/jboss-identity-fed-core/src/main/java/org/jboss/identity/federation/core/wstrust/auth/STSValidatingLoginModule.java
identity-federation/trunk/jboss-identity-fed-core/src/main/java/org/jboss/identity/federation/core/wstrust/auth/TokenCallback.java
identity-federation/trunk/jboss-identity-fed-core/src/test/java/org/jboss/identity/
identity-federation/trunk/jboss-identity-fed-core/src/test/java/org/jboss/identity/federation/
identity-federation/trunk/jboss-identity-fed-core/src/test/java/org/jboss/identity/federation/core/
identity-federation/trunk/jboss-identity-fed-core/src/test/java/org/jboss/identity/federation/core/wstrust/
identity-federation/trunk/jboss-identity-fed-core/src/test/java/org/jboss/identity/federation/core/wstrust/SamlCredentialTestCase.java
identity-federation/trunk/jboss-identity-fed-core/src/test/java/org/jboss/identity/federation/core/wstrust/auth/
identity-federation/trunk/jboss-identity-fed-core/src/test/java/org/jboss/identity/federation/core/wstrust/auth/STSIssuingLoginModuleTestCase.java
identity-federation/trunk/jboss-identity-fed-core/src/test/java/org/jboss/identity/federation/core/wstrust/auth/STSValidatingLoginModuleTestCase.java
identity-federation/trunk/jboss-identity-fed-core/src/test/java/org/jboss/identity/federation/core/wstrust/auth/Util.java
identity-federation/trunk/jboss-identity-fed-core/src/test/resources/wstrust/assertion-expected.xml
identity-federation/trunk/jboss-identity-fed-core/src/test/resources/wstrust/assertion.xml
identity-federation/trunk/jboss-identity-fed-core/src/test/resources/wstrust/auth/
identity-federation/trunk/jboss-identity-fed-core/src/test/resources/wstrust/auth/jboss-sts-client.properties
Modified:
identity-federation/trunk/jboss-identity-fed-core/pom.xml
identity-federation/trunk/jboss-identity-fed-core/src/main/java/org/jboss/identity/federation/core/util/StringUtil.java
identity-federation/trunk/jboss-identity-fed-core/src/main/java/org/jboss/identity/federation/core/wstrust/STSClientConfig.java
Log:
Work for
https://jira.jboss.org/jira/browse/JBID-206 "Add JBossSTSLoginModule from
JBossESB project"
Modified: identity-federation/trunk/jboss-identity-fed-core/pom.xml
===================================================================
--- identity-federation/trunk/jboss-identity-fed-core/pom.xml 2009-10-29 18:17:54 UTC (rev
885)
+++ identity-federation/trunk/jboss-identity-fed-core/pom.xml 2009-10-30 10:05:58 UTC (rev
886)
@@ -114,6 +114,12 @@
<version>2.2.14.GA</version>
<scope>test</scope>
</dependency>
+ <dependency>
+ <groupId>xmlunit</groupId>
+ <artifactId>xmlunit</artifactId>
+ <version>1.1</version>
+ <scope>test</scope>
+ </dependency>
</dependencies>
<reporting>
Modified:
identity-federation/trunk/jboss-identity-fed-core/src/main/java/org/jboss/identity/federation/core/util/StringUtil.java
===================================================================
---
identity-federation/trunk/jboss-identity-fed-core/src/main/java/org/jboss/identity/federation/core/util/StringUtil.java 2009-10-29
18:17:54 UTC (rev 885)
+++
identity-federation/trunk/jboss-identity-fed-core/src/main/java/org/jboss/identity/federation/core/util/StringUtil.java 2009-10-30
10:05:58 UTC (rev 886)
@@ -37,4 +37,9 @@
{
return str != null && !"".equals(str);
}
+
+ public static boolean isNullOrEmpty(String str)
+ {
+ return str == null || "".equals(str);
+ }
}
\ No newline at end of file
Modified:
identity-federation/trunk/jboss-identity-fed-core/src/main/java/org/jboss/identity/federation/core/wstrust/STSClientConfig.java
===================================================================
---
identity-federation/trunk/jboss-identity-fed-core/src/main/java/org/jboss/identity/federation/core/wstrust/STSClientConfig.java 2009-10-29
18:17:54 UTC (rev 885)
+++
identity-federation/trunk/jboss-identity-fed-core/src/main/java/org/jboss/identity/federation/core/wstrust/STSClientConfig.java 2009-10-30
10:05:58 UTC (rev 886)
@@ -152,6 +152,31 @@
return this;
}
+ 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 STSClientConfig build()
{
validate(this);
Added:
identity-federation/trunk/jboss-identity-fed-core/src/main/java/org/jboss/identity/federation/core/wstrust/SamlCredential.java
===================================================================
---
identity-federation/trunk/jboss-identity-fed-core/src/main/java/org/jboss/identity/federation/core/wstrust/SamlCredential.java
(rev 0)
+++
identity-federation/trunk/jboss-identity-fed-core/src/main/java/org/jboss/identity/federation/core/wstrust/SamlCredential.java 2009-10-30
10:05:58 UTC (rev 886)
@@ -0,0 +1,175 @@
+/*
+ * 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.core.wstrust;
+
+import java.io.IOException;
+import java.io.Serializable;
+import java.io.StringWriter;
+
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.OutputKeys;
+import javax.xml.transform.Result;
+import javax.xml.transform.Source;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerConfigurationException;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.TransformerFactoryConfigurationError;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
+
+import org.jboss.identity.federation.core.exceptions.ConfigurationException;
+import org.jboss.identity.federation.core.exceptions.ParsingException;
+import org.jboss.identity.federation.core.exceptions.ProcessingException;
+import org.jboss.identity.federation.core.saml.v2.util.DocumentUtil;
+import org.jboss.identity.federation.core.util.StringUtil;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.xml.sax.SAXException;
+
+/**
+ * Credential that wraps a SAML Assertion.
+ *
+ * @author <a href="mailto:dbevenius@jboss.com">Daniel
Bevenius</a>
+ *
+ */
+public final class SamlCredential implements Serializable
+{
+ private static final long serialVersionUID = -8496414959425288835L;
+
+ private static final TransformerFactory TRANSFORMER_FACTORY =
TransformerFactory.newInstance();
+
+ private String assertion;
+
+ public SamlCredential(final Element assertion)
+ {
+ if (assertion == null)
+ throw new IllegalArgumentException("assertion Element must not be
null");
+
+ this.assertion = SamlCredential.assertionToString(assertion);
+ }
+
+ public SamlCredential(final String assertion)
+ {
+ if (StringUtil.isNullOrEmpty(assertion))
+ throw new IllegalArgumentException("assertion String must not be null or
empty");
+
+ this.assertion = assertion;
+ }
+
+ public String getAssertionAsString()
+ {
+ return assertion;
+ }
+
+ public Element getAssertionAsElement() throws ProcessingException
+ {
+ try
+ {
+ return SamlCredential.assertionToElement(assertion);
+ }
+ catch (final ConfigurationException e)
+ {
+ throw new ProcessingException(e.getMessage(), e);
+ }
+ catch (final ParsingException e)
+ {
+ throw new ProcessingException(e.getMessage(), e);
+ }
+ catch (final ParserConfigurationException e)
+ {
+ throw new ProcessingException(e.getMessage(), e);
+ }
+ catch (final SAXException e)
+ {
+ throw new ProcessingException(e.getMessage(), e);
+ }
+ catch (final IOException e)
+ {
+ throw new ProcessingException(e.getMessage(), e);
+ }
+ }
+
+ @Override
+ public boolean equals(final Object obj)
+ {
+ if (this == obj)
+ return true;
+
+ if (!(obj instanceof SamlCredential))
+ return false;
+
+ final SamlCredential that = (SamlCredential) obj;
+ return this.assertion.equals(that.assertion);
+ }
+
+ @Override
+ public int hashCode()
+ {
+ int result = 17;
+ result = 31 * result + assertion.hashCode();
+ return result;
+ }
+
+ @Override
+ public String toString()
+ {
+ return "SamlCredential[" + assertion + "]";
+ }
+
+ public static Element assertionToElement(final String assertion) throws
ParserConfigurationException, SAXException, IOException, ConfigurationException,
ParsingException, ProcessingException
+ {
+ final Document document = DocumentUtil.getDocument(assertion);
+ return (Element) document.getFirstChild();
+ }
+
+ public static String assertionToString(final Element assertion)
+ {
+ if (assertion == null)
+ throw new IllegalArgumentException("assertion Element must not be
null");
+
+ try
+ {
+ final Transformer transformer = TRANSFORMER_FACTORY.newTransformer();
+ transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION,
"yes");
+
+ final Source source = new DOMSource(assertion);
+ final StringWriter writer = new StringWriter();
+ final Result result = new StreamResult(writer);
+
+ transformer.transform(source, result);
+
+ return writer.toString();
+ }
+ catch (final TransformerConfigurationException e)
+ {
+ throw new IllegalStateException(e.getMessage(), e);
+ }
+ catch (final TransformerFactoryConfigurationError e)
+ {
+ throw new IllegalStateException(e.getMessage(), e);
+ }
+ catch (final TransformerException e)
+ {
+ throw new IllegalStateException(e.getMessage(), e);
+ }
+ }
+}
Added:
identity-federation/trunk/jboss-identity-fed-core/src/main/java/org/jboss/identity/federation/core/wstrust/auth/AbstractSTSLoginModule.java
===================================================================
---
identity-federation/trunk/jboss-identity-fed-core/src/main/java/org/jboss/identity/federation/core/wstrust/auth/AbstractSTSLoginModule.java
(rev 0)
+++
identity-federation/trunk/jboss-identity-fed-core/src/main/java/org/jboss/identity/federation/core/wstrust/auth/AbstractSTSLoginModule.java 2009-10-30
10:05:58 UTC (rev 886)
@@ -0,0 +1,310 @@
+/*
+ * 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.core.wstrust.auth;
+
+import java.util.Map;
+import java.util.Set;
+
+import javax.security.auth.Subject;
+import javax.security.auth.callback.CallbackHandler;
+import javax.security.auth.login.LoginException;
+import javax.security.auth.spi.LoginModule;
+
+import org.apache.log4j.Logger;
+import org.jboss.identity.federation.core.exceptions.ParsingException;
+import org.jboss.identity.federation.core.wstrust.STSClient;
+import org.jboss.identity.federation.core.wstrust.STSClientConfig;
+import org.jboss.identity.federation.core.wstrust.STSClientFactory;
+import org.jboss.identity.federation.core.wstrust.SamlCredential;
+import org.w3c.dom.Element;
+
+/**
+ * Abstract JAAS LoginModule for JBoss STS (Security Token Service).
+ * </p>
+ *
+ * Subclasses are required to implement {@link #login()} to perform their specific
actions.
+ *
+ * Subclasses can define more configuration options by overriding initialize.
+ * Also note that subclasses are not forced to put configuration options in a file. They
+ * can all be set as options just like the 'configFile' is specified above.
+ *
+ * @author <a href="mailto:dbevenius@jboss.com">Daniel
Bevenius</a>
+ */
+public abstract class AbstractSTSLoginModule implements LoginModule
+{
+ private Logger log = Logger.getLogger(AbstractSTSLoginModule.class);
+
+ /**
+ * Key used in share state map when LMs are stacked.
+ */
+ public static final String SHARED_TOKEN =
"org.jboss.identity.federation.core.wstrust.lm.stsToken";
+
+ /**
+ * This is the required option that should identify the configuration
+ * file for WSTrustClient.
+ */
+ public static final String STS_CONFIG_FILE = "configFile";
+
+ /**
+ * The subject to be populated.
+ */
+ private Subject subject;
+
+ /**
+ * Callback handler used to gather information from the caller.
+ */
+ private CallbackHandler callbackHandler;
+
+ /**
+ * WS-Trust SAML Assertion element.
+ */
+ private Element samlToken;
+
+ /**
+ * The outcome of the authentication process.
+ */
+ private boolean success;
+
+ /**
+ * The options map passed into this login modules initalize method.
+ */
+ private Map<String, ?> options;
+
+ /**
+ * The shared state map passed into this login modules initalize method.
+ */
+ private Map<String, ?> sharedState;
+
+ /**
+ * Initialized this login module. Simple stores the passed in fields and
+ * also validates the options.
+ *
+ * @param subject
+ * The subject to authenticate/populate.
+ * @param callbackHandler
+ * The callbackhandler that will gather information required by
+ * this login module.
+ * @param sharedState
+ * State that is shared with other login modules. Used when
+ * modules are chained/stacked.
+ * @param options
+ * The options that were specified for this login module. See
+ * "Usage" section of this types javadoc.
+ */
+ public void initialize(final Subject subject, final CallbackHandler callbackHandler,
final Map<String, ?> sharedState, final Map<String, ?> options)
+ {
+ this.subject = subject;
+ this.callbackHandler = callbackHandler;
+ this.options = options;
+ this.sharedState = sharedState;
+ }
+
+ /**
+ * Subclasses must implement the login to perform their specific tasks.
+ *
+ * The login module should call {@link #setSamlToken(Element)} with the saml token
+ * element that should be added to the public credentials in {@link #commit()}.
+ *
+ * @return true If the login was successful otherwise false.
+ * @throws LoginException If an error occurs while trying to perform the
authentication.
+ */
+ public abstract boolean login() throws LoginException;
+
+ /**
+ * Commit will package the samlToken set by the login method in a new {@link
SamlCredential}.
+ * This new SamlCredential will be put into the Subject public credentials set.
+ */
+ public boolean commit() throws LoginException
+ {
+ if (success)
+ {
+ final SamlCredential samlCredential = new SamlCredential(samlToken);
+ final boolean added = subject.getPublicCredentials().add(samlCredential);
+ if (added && log.isDebugEnabled())
+ log.debug("Added Credential :" + samlCredential);
+
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+ /**
+ * Called if the overall authentication failed (phase 2).
+ */
+ public boolean abort() throws LoginException
+ {
+ success = false;
+ clearState();
+ return true;
+ }
+
+ public boolean logout() throws LoginException
+ {
+ clearState();
+ return true;
+ }
+
+ /**
+ * This method gives users a chance to override how the {@link STSClientConfig} is
created.
+ * For example some users might perfer to not use a file containing the configuration
+ * properties, which is the default, but instead have the configuration options in
the
+ * login modules configuration directly.
+ *
+ * @param options The options passed to the initialize method.
+ * @return {@link STSClientConfig} The configuration for STSClient.
+ */
+ protected STSClientConfig getConfiguration(final Map<String, ?> options)
+ {
+ final String configFile = getRequiredOption(options, STS_CONFIG_FILE);
+ return new STSClientConfig.Builder(configFile).build();
+ }
+
+ protected STSClient createWSTrustClient(final STSClientConfig config)
+ {
+ try
+ {
+ return STSClientFactory.getInstance().create(config);
+ }
+ catch (final ParsingException e)
+ {
+ throw new IllegalStateException("Could not create WSTrustClient:",
e);
+ }
+ }
+
+ protected String getRequiredOption(final Map<String, ?> options, final String
optionName)
+ {
+ final String option = (String) options.get(optionName);
+ if (option == null)
+ throw new IllegalArgumentException("Required option '" +
optionName + "' was missing from the login modules configuration");
+
+ return option;
+ }
+
+ protected boolean isSuccess()
+ {
+ return success;
+ }
+
+ protected void setSuccess(boolean success)
+ {
+ this.success = success;
+ }
+
+ protected Subject getSubject()
+ {
+ return subject;
+ }
+
+ protected CallbackHandler getCallbackHandler()
+ {
+ return callbackHandler;
+ }
+
+ protected void setSamlToken(final Element samlToken)
+ {
+ this.samlToken = samlToken;
+ }
+
+ @SuppressWarnings ("unchecked")
+ protected void setSharedToken(final Object token)
+ {
+ if (sharedState == null)
+ return;
+ /*
+ * This is hidious but must be done since the signature of initialize in
LoginModule is:
+ * public void initialize(final Subject subject, final CallbackHandler
callbackHandler, final Map<String, ?> sharedState, final Map<String, ?>
options)
+ * Notice how sharedState is defined. This means that it will not be possible to
put anything into that map
+ * without bypassing generics.
+ */
+ // Cast the shartState to a raw map
+ final Map state = (Map) sharedState;
+ // Put the Token into the shared state map
+ state.put(SHARED_TOKEN, token);
+ }
+
+ /**
+ * Gets Security Token from the share state map if one was made available by
+ * a previous LM in the stack.
+ *
+ * @return Object A security token if one was stored in the shared state map. Or null
if one does not exist.
+ */
+ protected Object getSharedToken()
+ {
+ if (sharedState == null)
+ return null;
+
+ return sharedState.get(SHARED_TOKEN);
+ }
+
+ /**
+ * Gets the options provided to this LM in it's {@link #initialize(Subject,
CallbackHandler, Map, Map)}.
+ *
+ * @return Map<String, ?> The options map.
+ */
+ protected Map<String, ?> getOptions()
+ {
+ return options;
+ }
+
+ protected String getSharedUsername()
+ {
+ if (sharedState == null)
+ return null;
+
+ return (String) sharedState.get("javax.security.auth.login.name");
+ }
+
+ protected char[] getSharedPassword()
+ {
+ if (sharedState == null)
+ return null;
+
+ return (char[]) sharedState.get("javax.security.auth.login.password");
+ }
+
+ protected boolean isUseFirstPass()
+ {
+ if (options == null)
+ return false;
+
+ final String passwordStacking = (String)
options.get("password-stacking");
+ return "useFirstPass".equals(passwordStacking);
+ }
+
+ private void clearState()
+ {
+ removeAllSamlCredentials(subject);
+ samlToken = null;
+ }
+
+ private void removeAllSamlCredentials(final Subject subject)
+ {
+ final Set<SamlCredential> samlCredentials =
subject.getPublicCredentials(SamlCredential.class);
+ if (!samlCredentials.isEmpty())
+ {
+ subject.getPublicCredentials().removeAll(samlCredentials);
+ }
+ }
+
+}
Added:
identity-federation/trunk/jboss-identity-fed-core/src/main/java/org/jboss/identity/federation/core/wstrust/auth/STSIssuingLoginModule.java
===================================================================
---
identity-federation/trunk/jboss-identity-fed-core/src/main/java/org/jboss/identity/federation/core/wstrust/auth/STSIssuingLoginModule.java
(rev 0)
+++
identity-federation/trunk/jboss-identity-fed-core/src/main/java/org/jboss/identity/federation/core/wstrust/auth/STSIssuingLoginModule.java 2009-10-30
10:05:58 UTC (rev 886)
@@ -0,0 +1,150 @@
+/*
+ * 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.core.wstrust.auth;
+
+import java.io.IOException;
+import java.util.Map;
+
+import javax.security.auth.Subject;
+import javax.security.auth.callback.Callback;
+import javax.security.auth.callback.CallbackHandler;
+import javax.security.auth.callback.NameCallback;
+import javax.security.auth.callback.PasswordCallback;
+import javax.security.auth.callback.UnsupportedCallbackException;
+import javax.security.auth.login.LoginException;
+
+import org.jboss.identity.federation.core.wstrust.STSClient;
+import org.jboss.identity.federation.core.wstrust.STSClientConfig;
+import org.jboss.identity.federation.core.wstrust.WSTrustException;
+import org.jboss.identity.federation.core.wstrust.STSClientConfig.Builder;
+import org.w3c.dom.Element;
+
+/**
+ * JAAS LoginModule for JBoss STS (Security Token Service) that issues security tokens.
+ *
+ * <h3>Configuration example</h3>
+ * <pre>{@code
+ * <application-policy name="saml-issue-token">
+ * <authentication>
+ * <login-module
code="org.jboss.identity.federation.core.wstrust.auth.STSIssuingLoginModule"
flag="required">
+ * <module-option
name="configFile">/sts-client.properties</module-option>
+ * <module-option name="endpointURI"></module-option>
+ * <module-option name="tokenType"></module-option>
+ * </login-module>
+ * </authentication>
+ * </application-policy>
+ * }
+ * </pre>
+ *
+ * This login module expects to be created callback handler that can handle {@link
NameCallback}
+ * and a {@link PasswordCallback}, which should be match the username and password for
whom a security
+ * token will be issued.
+ * <p/>
+ *
+ * Password stacking is supported by using the option:
+ * <pre>{@code
+ * <module-option
name="password-stacking">useFirstPass</module-option>
+ * }</pre>
+ *
+ * @author <a href="mailto:dbevenius@jboss.com">Daniel
Bevenius</a>
+ *
+ */
+public class STSIssuingLoginModule extends AbstractSTSLoginModule
+{
+ public static final String ENDPOINT_OPTION = "endpointURI";
+ public static final String TOKEN_TYPE_OPTION = "tokenType";
+
+ private String endpointURI;
+ private String tokenType;
+
+ @Override
+ public void initialize(final Subject subject, final CallbackHandler callbackHandler,
final Map<String, ?> sharedState, final Map<String, ?> options)
+ {
+ super.initialize(subject, callbackHandler, sharedState, options);
+
+ if (callbackHandler == null && !isUseFirstPass())
+ {
+ throw new IllegalArgumentException("CallbackHandler must not be
null");
+ }
+
+ endpointURI = (String) options.get(ENDPOINT_OPTION);
+ tokenType = (String) options.get(TOKEN_TYPE_OPTION);
+ }
+
+ /**
+ * This method will issue a token for the configured user. This user will be either
+ * be the user from a previous stacked login module or the username and
+ * credentials will be retreived using the callbackhandler supplied to this
+ * login module.
+ *
+ * @return true If the login was successful otherwise false.
+ * @throws LoginException If an error occurs while trying to perform the
authentication.
+ */
+ public boolean login() throws LoginException
+ {
+ try
+ {
+ final Builder builder = new
STSClientConfig.Builder(getRequiredOption(getOptions(), STS_CONFIG_FILE));
+ if (isUseFirstPass())
+ {
+ // Use username/password from shared state.
+ builder.username(getSharedUsername()).password(new
String(getSharedPassword()));
+ }
+ else
+ {
+ final NameCallback nameCallback = new NameCallback("user:");
+ final PasswordCallback passwordCallback = new
PasswordCallback("password:", true);
+ try
+ {
+ getCallbackHandler().handle(new Callback[] { nameCallback,
passwordCallback });
+ // Use username/password from callbacks.
+ builder.username(nameCallback.getName()).password(new
String(passwordCallback.getPassword()));
+ }
+ catch (final IOException e)
+ {
+ throw new LoginException(e.getMessage());
+ }
+ catch (final UnsupportedCallbackException e)
+ {
+ throw new LoginException(e.getMessage());
+ }
+ }
+
+ final STSClient stsClient = createWSTrustClient(builder.build());
+
+ final Element token = stsClient.issueToken(endpointURI, tokenType);
+ if (token == null)
+ {
+ // Throw an exception as returing false only says that this login module
should be ignored.
+ throw new LoginException("Could not issue a SAML Security
Token");
+ }
+ setSuccess(true);
+ setSamlToken(token);
+ setSharedToken(token);
+ return true;
+ }
+ catch (WSTrustException e)
+ {
+ throw new LoginException("WSTrustException : " + e.getMessage());
+ }
+ }
+
+}
Added:
identity-federation/trunk/jboss-identity-fed-core/src/main/java/org/jboss/identity/federation/core/wstrust/auth/STSValidatingLoginModule.java
===================================================================
---
identity-federation/trunk/jboss-identity-fed-core/src/main/java/org/jboss/identity/federation/core/wstrust/auth/STSValidatingLoginModule.java
(rev 0)
+++
identity-federation/trunk/jboss-identity-fed-core/src/main/java/org/jboss/identity/federation/core/wstrust/auth/STSValidatingLoginModule.java 2009-10-30
10:05:58 UTC (rev 886)
@@ -0,0 +1,113 @@
+/*
+ * 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.core.wstrust.auth;
+
+import java.io.IOException;
+
+import javax.security.auth.callback.Callback;
+import javax.security.auth.callback.UnsupportedCallbackException;
+import javax.security.auth.login.LoginException;
+
+import org.apache.log4j.Logger;
+import org.jboss.identity.federation.core.wstrust.STSClient;
+import org.jboss.identity.federation.core.wstrust.WSTrustException;
+import org.w3c.dom.Element;
+
+/**
+ * JAAS LoginModule for JBoss STS (Security Token Service) that validates security
tokens.
+ * </p>
+ * This LoginModule only performs validation of existing SAML Assertions and
+ * does not issue any such Assertions.
+ *
+ * <h3>Configuration example</h3>
+ * <pre>{@code
+ * <application-policy name="saml-validate-token">
+ * <authentication>
+ * <login-module
code="org.jboss.identity.federation.core.wstrust.auth.STSValidatingLoginModule"
flag="required">
+ * <module-option
name="configFile">/sts-client.properties</module-option>
+ * </login-module>
+ * </authentication>
+ * </application-policy>
+ * }</pre>
+ *
+ * @author <a href="mailto:dbevenius@jboss.com">Daniel
Bevenius</a>
+ */
+public class STSValidatingLoginModule extends AbstractSTSLoginModule
+{
+ private Logger log = Logger.getLogger(STSValidatingLoginModule.class);
+
+ /**
+ * This method will validate the token retreived by the callback handler and
validate
+ * it with the configured STS.
+ *
+ * @return true If the login was successful otherwise false.
+ * @throws LoginException If an error occurs while trying to perform the
authentication.
+ */
+ public boolean login() throws LoginException
+ {
+ final STSClient stsClient = createWSTrustClient(getConfiguration(getOptions()));
+ try
+ {
+ // See if a previous stacked login module stored the token.
+ Element token = (Element) getSharedToken();
+
+ if (token == null)
+ token = getSamlTokenFromCaller();
+
+ final boolean success = stsClient.validateToken(token);
+ log.debug("Validation result: " + success);
+ setSuccess(success);
+ if (!isSuccess())
+ {
+ // Throw an exception as returing false only says that this login module
should be ignored.
+ throw new LoginException("Could not validate the SAML Security Token
:" + token);
+ }
+ setSamlToken(token);
+ return success;
+ }
+ catch (final WSTrustException e)
+ {
+ throw new LoginException("WSTrustException : " + e.getMessage());
+ }
+ catch (final IOException e)
+ {
+ throw new LoginException("IOException : " + e.getMessage());
+ }
+ catch (final UnsupportedCallbackException e)
+ {
+ throw new LoginException("UnsupportedCallbackException : " +
e.getMessage());
+ }
+ }
+
+ private Element getSamlTokenFromCaller() throws UnsupportedCallbackException,
LoginException, IOException
+ {
+ final TokenCallback callback = new TokenCallback();
+
+ getCallbackHandler().handle(new Callback[] { callback });
+
+ final Element token = (Element) callback.getToken();
+ if (token == null)
+ throw new LoginException("Could not locate a Security Token from the
callback.");
+
+ return token;
+ }
+
+}
Added:
identity-federation/trunk/jboss-identity-fed-core/src/main/java/org/jboss/identity/federation/core/wstrust/auth/TokenCallback.java
===================================================================
---
identity-federation/trunk/jboss-identity-fed-core/src/main/java/org/jboss/identity/federation/core/wstrust/auth/TokenCallback.java
(rev 0)
+++
identity-federation/trunk/jboss-identity-fed-core/src/main/java/org/jboss/identity/federation/core/wstrust/auth/TokenCallback.java 2009-10-30
10:05:58 UTC (rev 886)
@@ -0,0 +1,49 @@
+/*
+ * 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.core.wstrust.auth;
+
+import javax.security.auth.callback.Callback;
+
+/**
+ * Simple callback that stores an object.
+ *
+ * @author <a href="mailto:dbevenius@jboss.com">Daniel
Bevenius</a>
+ *
+ */
+public class TokenCallback implements Callback
+{
+ private transient Object token;
+
+ public Object getToken()
+ {
+ return token;
+ }
+
+ public void setToken(final Object token)
+ {
+ this.token = token;
+ }
+
+ public void clearToken()
+ {
+ token = null;
+ }
+}
Added:
identity-federation/trunk/jboss-identity-fed-core/src/test/java/org/jboss/identity/federation/core/wstrust/SamlCredentialTestCase.java
===================================================================
---
identity-federation/trunk/jboss-identity-fed-core/src/test/java/org/jboss/identity/federation/core/wstrust/SamlCredentialTestCase.java
(rev 0)
+++
identity-federation/trunk/jboss-identity-fed-core/src/test/java/org/jboss/identity/federation/core/wstrust/SamlCredentialTestCase.java 2009-10-30
10:05:58 UTC (rev 886)
@@ -0,0 +1,93 @@
+/*
+ * 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.core.wstrust;
+
+import java.io.StringReader;
+
+import junit.framework.TestCase;
+
+import org.custommonkey.xmlunit.XMLAssert;
+import org.custommonkey.xmlunit.XMLUnit;
+import org.jboss.identity.federation.core.saml.v2.util.DocumentUtil;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.xml.sax.InputSource;
+
+/**
+ * Unit test for {@link SamlCredential}.
+ *
+ * @author <a href="mailto:dbevenius@jboss.com">Daniel
Bevenius</a>
+ *
+ */
+public class SamlCredentialTestCase extends TestCase
+{
+ private Element assertionElement;
+ private InputSource expectedAssertion;
+
+ public void setUp() throws Exception
+ {
+ XMLUnit.setIgnoreWhitespace(true);
+ final Document assertionDoc =
DocumentUtil.getDocument(getClass().getResourceAsStream("/wstrust/assertion.xml"));
+ assertionElement = (Element) assertionDoc.getFirstChild();
+ expectedAssertion = new
InputSource(getClass().getResourceAsStream("/wstrust/assertion-expected.xml"));
+ }
+
+ public void testStringConstructor() throws Exception
+ {
+ final SamlCredential samlPrincipal = new
SamlCredential(DocumentUtil.getNodeAsString(assertionElement));
+
+ final InputSource actual = new InputSource(new
StringReader(samlPrincipal.getAssertionAsString()));
+
+ XMLAssert.assertXMLEqual(expectedAssertion, actual);
+ }
+
+ public void testElementConstructor() throws Exception
+ {
+ final SamlCredential samlPrincipal = new SamlCredential(assertionElement);
+
+ final InputSource actual = new InputSource(new
StringReader(samlPrincipal.getAssertionAsString()));
+
+ XMLAssert.assertXMLEqual(expectedAssertion, actual);
+ }
+
+ public void testShouldThrowIfStringIsNull()
+ {
+ try
+ {
+ new SamlCredential((String)null);
+ fail("Should not be allowed to create a SamlCredential with a null token
string");
+ }
+ catch(final Exception e)
+ {
+ assertTrue(e instanceof IllegalArgumentException);
+ }
+ }
+
+ public void testEqualsContract() throws Exception
+ {
+ final SamlCredential samlPrincipal1 = new SamlCredential(assertionElement);
+ final SamlCredential samlPrincipal2 = new SamlCredential(assertionElement);
+ assertEquals(samlPrincipal1, samlPrincipal2);
+ assertEquals(samlPrincipal1.hashCode(), samlPrincipal2.hashCode());
+ }
+
+}
+
Added:
identity-federation/trunk/jboss-identity-fed-core/src/test/java/org/jboss/identity/federation/core/wstrust/auth/STSIssuingLoginModuleTestCase.java
===================================================================
---
identity-federation/trunk/jboss-identity-fed-core/src/test/java/org/jboss/identity/federation/core/wstrust/auth/STSIssuingLoginModuleTestCase.java
(rev 0)
+++
identity-federation/trunk/jboss-identity-fed-core/src/test/java/org/jboss/identity/federation/core/wstrust/auth/STSIssuingLoginModuleTestCase.java 2009-10-30
10:05:58 UTC (rev 886)
@@ -0,0 +1,154 @@
+/*
+ * 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.core.wstrust.auth;
+
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
+import javax.security.auth.Subject;
+import javax.security.auth.callback.Callback;
+import javax.security.auth.callback.CallbackHandler;
+import javax.security.auth.callback.NameCallback;
+import javax.security.auth.callback.PasswordCallback;
+import javax.security.auth.callback.UnsupportedCallbackException;
+
+import org.jboss.identity.federation.core.wstrust.STSClient;
+import org.jboss.identity.federation.core.wstrust.STSClientConfig;
+import org.jboss.identity.federation.core.wstrust.SamlCredential;
+import org.jboss.identity.federation.core.wstrust.auth.STSIssuingLoginModule;
+import org.w3c.dom.Element;
+
+import junit.framework.TestCase;
+
+/**
+ * Unit test for {@link STSIssuingLoginModule}
+ *
+ * @author <a href="mailto:dbevenius@jboss.com">Daniel
Bevenius</a>
+ */
+public class STSIssuingLoginModuleTestCase extends TestCase
+{
+ private STSClient stsClient;
+
+ public void setUp()
+ {
+ stsClient = mock(STSClient.class);
+ }
+
+ public void testLoginWithValidToken() throws Exception
+ {
+ // Make the issueToken() method return a token.
+ when(stsClient.issueToken(any(String.class),
any(String.class))).thenReturn(Util.createSamlToken());
+
+ final STSIssuingLoginModule loginModule = new
FakeSTSIssuingLoginModule(stsClient);
+ final CallbackHandler callbackHandler = new
TestCallbackHandler("admin", "admin");
+ final Subject subject = new Subject();
+ final HashMap<String, Object> sharedState = new HashMap<String,
Object>();
+
+ loginModule.initialize(subject, callbackHandler, sharedState, allOptions());
+
+ // Simulate Phase 1
+ assertTrue(loginModule.login());
+
+ final Object token = loginModule.getSharedToken();
+ assertNotNull(token);
+ assertTrue(token instanceof Element);
+
+ // Simulate Phase 2
+ assertTrue(loginModule.commit());
+
+ final Set<SamlCredential> samlCredentials =
subject.<SamlCredential>getPublicCredentials(SamlCredential.class);
+ assertEquals(1, samlCredentials.size());
+ }
+
+ public void testUseFirstPass()
+ {
+ final String username = "Fletch";
+ final String password = "letMeIn";
+ final STSIssuingLoginModule loginModule = new STSIssuingLoginModule();
+ final Subject subject = new Subject();
+
+ final HashMap<String, Object> sharedState = new HashMap<String,
Object>();
+ sharedState.put("javax.security.auth.login.name", username);
+ sharedState.put("javax.security.auth.login.password",
password.toCharArray());
+
+ final Map<String, String> options = allOptions();
+ options.put("password-stacking", "useFirstPass");
+
+ loginModule.initialize(subject, null, sharedState, options);
+
+ assertTrue(loginModule.isUseFirstPass());
+ assertEquals(username, loginModule.getSharedUsername());
+ assertEquals(password, new String(loginModule.getSharedPassword()));
+ }
+
+ private Map<String, String> allOptions()
+ {
+ final Map<String, String> options = Util.allOptions();
+ options.put(STSIssuingLoginModule.ENDPOINT_OPTION, "someUrl");
+ options.put(STSIssuingLoginModule.TOKEN_TYPE_OPTION, "someTokenType");
+ return options;
+ }
+
+ private class TestCallbackHandler implements CallbackHandler
+ {
+ private final String username;
+ private final String password;
+
+ public TestCallbackHandler(final String username, final String password)
+ {
+ this.username = username;
+ this.password = password;
+ }
+
+ public void handle(final Callback[] callbacks) throws IOException,
UnsupportedCallbackException
+ {
+ for (Callback callback : callbacks)
+ {
+ if (callback instanceof NameCallback)
+ ((NameCallback)callback).setName(username);
+ if (callback instanceof PasswordCallback)
+ ((PasswordCallback)callback).setPassword(password.toCharArray());
+ }
+ }
+ }
+
+ private class FakeSTSIssuingLoginModule extends STSIssuingLoginModule
+ {
+ private STSClient client;
+
+ public FakeSTSIssuingLoginModule(final STSClient client)
+ {
+ this.client = client;
+ }
+
+ @Override
+ protected STSClient createWSTrustClient(final STSClientConfig config)
+ {
+ return client;
+ }
+ }
+}
Added:
identity-federation/trunk/jboss-identity-fed-core/src/test/java/org/jboss/identity/federation/core/wstrust/auth/STSValidatingLoginModuleTestCase.java
===================================================================
---
identity-federation/trunk/jboss-identity-fed-core/src/test/java/org/jboss/identity/federation/core/wstrust/auth/STSValidatingLoginModuleTestCase.java
(rev 0)
+++
identity-federation/trunk/jboss-identity-fed-core/src/test/java/org/jboss/identity/federation/core/wstrust/auth/STSValidatingLoginModuleTestCase.java 2009-10-30
10:05:58 UTC (rev 886)
@@ -0,0 +1,168 @@
+/*
+ * 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.core.wstrust.auth;
+
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
+import javax.security.auth.Subject;
+import javax.security.auth.callback.Callback;
+import javax.security.auth.callback.CallbackHandler;
+import javax.security.auth.callback.UnsupportedCallbackException;
+import javax.security.auth.login.LoginException;
+
+import org.jboss.identity.federation.core.wstrust.STSClient;
+import org.jboss.identity.federation.core.wstrust.STSClientConfig;
+import org.jboss.identity.federation.core.wstrust.SamlCredential;
+import org.jboss.identity.federation.core.wstrust.auth.STSIssuingLoginModule;
+import org.jboss.identity.federation.core.wstrust.auth.STSValidatingLoginModule;
+import org.jboss.identity.federation.core.wstrust.auth.TokenCallback;
+import org.w3c.dom.Element;
+
+import junit.framework.TestCase;
+
+/**
+ * Unit test for {@link STSIssuingLoginModule}.
+ *
+ * @author <a href="mailto:dbevenius@jboss.com">Daniel
Bevenius</a>
+ */
+public class STSValidatingLoginModuleTestCase extends TestCase
+{
+ private STSClient stsClient;
+
+ public void setUp()
+ {
+ stsClient = mock(STSClient.class);
+ }
+
+ public void testLoginWithValidToken() throws Exception
+ {
+ // Make the validateToken() method return true.
+ when(stsClient.validateToken(any(Element.class))).thenReturn(true);
+
+ final STSValidatingLoginModule loginModule = new
FakeSTSValidatingLoginModule(stsClient);
+ final CallbackHandler callbackHandler = new
TestCallbackHandler(Util.createSamlToken());
+ final Subject subject = new Subject();
+
+ loginModule.initialize(subject, callbackHandler, null, Util.allOptions());
+
+ // Simulate Phase 1
+ assertTrue(loginModule.login());
+
+ // Simulate Phase 2
+ assertTrue(loginModule.commit());
+
+ final Set<SamlCredential> samlCredentials =
subject.<SamlCredential>getPublicCredentials(SamlCredential.class);
+ assertEquals(1, samlCredentials.size());
+ }
+
+ public void testLoginWithInValidToken() throws Exception
+ {
+ // Make the validateToken() method return false.
+ when(stsClient.validateToken(any(Element.class))).thenReturn(false);
+
+ final STSValidatingLoginModule loginModule = new
FakeSTSValidatingLoginModule(stsClient);
+ final CallbackHandler callbackHandler = new
TestCallbackHandler(Util.createSamlToken());
+
+ loginModule.initialize(new Subject(), callbackHandler, null, Util.allOptions());
+
+ try
+ {
+ // Simulate Phase 1
+ loginModule.login();
+ fail("login should have thrown a LoginException!");
+ }
+ catch (final Exception e)
+ {
+ assertTrue(e instanceof LoginException);
+ }
+ }
+
+ public void testStackedModules() throws Exception
+ {
+ // Make the validateToken() method return true.
+ when(stsClient.validateToken(any(Element.class))).thenReturn(true);
+
+ final STSValidatingLoginModule loginModule = new
FakeSTSValidatingLoginModule(stsClient);
+ final Element token = Util.createSamlToken();
+
+ final Subject subject = new Subject();
+
+ final Map<String, Object> sharedState = new HashMap<String,
Object>();
+
+ loginModule.initialize(subject, null, sharedState, Util.allOptions());
+ // Simlulate that a previous LM stored a security token in the shared state.
+ loginModule.setSharedToken(token);
+
+ // Simulate Phase 1
+ assertTrue(loginModule.login());
+
+ // Simulate Phase 2
+ assertTrue(loginModule.commit());
+
+ final Set<SamlCredential> samlCredentials =
subject.<SamlCredential>getPublicCredentials(SamlCredential.class);
+ assertEquals(1, samlCredentials.size());
+ }
+
+ private class TestCallbackHandler implements CallbackHandler
+ {
+ private final Object token;
+
+ public TestCallbackHandler(final Object token)
+ {
+ this.token = token;
+ }
+
+ public void handle(final Callback[] callbacks) throws IOException,
UnsupportedCallbackException
+ {
+ for (Callback callback : callbacks)
+ {
+ if (callback instanceof TokenCallback)
+ {
+ ((TokenCallback)callback).setToken(token);
+ }
+ }
+ }
+ }
+
+ private class FakeSTSValidatingLoginModule extends STSValidatingLoginModule
+ {
+ private STSClient client;
+
+ public FakeSTSValidatingLoginModule(final STSClient client)
+ {
+ this.client = client;
+ }
+
+ @Override
+ protected STSClient createWSTrustClient(final STSClientConfig config)
+ {
+ return client;
+ }
+ }
+
+}
Added:
identity-federation/trunk/jboss-identity-fed-core/src/test/java/org/jboss/identity/federation/core/wstrust/auth/Util.java
===================================================================
---
identity-federation/trunk/jboss-identity-fed-core/src/test/java/org/jboss/identity/federation/core/wstrust/auth/Util.java
(rev 0)
+++
identity-federation/trunk/jboss-identity-fed-core/src/test/java/org/jboss/identity/federation/core/wstrust/auth/Util.java 2009-10-30
10:05:58 UTC (rev 886)
@@ -0,0 +1,55 @@
+/*
+ * 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.core.wstrust.auth;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.jboss.identity.federation.core.wstrust.plugins.saml.SAMLUtil;
+import org.jboss.identity.federation.saml.v2.assertion.AssertionType;
+import org.w3c.dom.Element;
+
+/**
+ * Test util methods.
+ *
+ * @author <a href="mailto:dbevenius@jboss.com">Daniel
Bevenius</a>
+ *
+ */
+public final class Util
+{
+ private Util()
+ {
+ }
+
+ public static Element createSamlToken() throws Exception
+ {
+ final AssertionType assertionType = new AssertionType();
+ return SAMLUtil.toElement(assertionType);
+ }
+
+ public static Map<String, String> allOptions()
+ {
+ Map<String, String> options = new HashMap<String, String>();
+ options.put(AbstractSTSLoginModule.STS_CONFIG_FILE,
"wstrust/auth/jboss-sts-client.properties");
+ return options;
+ }
+
+}
Added:
identity-federation/trunk/jboss-identity-fed-core/src/test/resources/wstrust/assertion-expected.xml
===================================================================
---
identity-federation/trunk/jboss-identity-fed-core/src/test/resources/wstrust/assertion-expected.xml
(rev 0)
+++
identity-federation/trunk/jboss-identity-fed-core/src/test/resources/wstrust/assertion-expected.xml 2009-10-30
10:05:58 UTC (rev 886)
@@ -0,0 +1,30 @@
+<Assertion xmlns="urn:oasis:names:tc:SAML:2.0:assertion"
ID="ID_74414f7f-1339-4f80-b29a-c947d9177445"
IssueInstant="2009-09-10T13:49:30.422Z" Version="2.0">
+ <Issuer>JBossSTS</Issuer>
+ <Subject>
+ <NameID
NameQualifier="urn:jboss:identity-federation">beve</NameID>
+ <SubjectConfirmation
Method="urn:oasis:names:tc:SAML:2.0:cm:bearer"/>
+ </Subject>
+ <Conditions NotBefore="2009-09-10T13:49:30.422Z"
NotOnOrAfter="2009-09-10T15:49:30.422Z"/>
+ <dsig:Signature
xmlns:dsig="http://www.w3.org/2000/09/xmldsig#">
+ <dsig:SignedInfo><dsig:CanonicalizationMethod
Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#WithComments"
xmlns:dsig="http://www.w3.org/2000/09/xmldsig#"/>
+ <dsig:SignatureMethod
Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"
xmlns:dsig="http://www.w3.org/2000/09/xmldsig#"/>
+ <dsig:Reference URI="#ID_74414f7f-1339-4f80-b29a-c947d9177445"
xmlns:dsig="http://www.w3.org/2000/09/xmldsig#">
+ <dsig:Transforms
xmlns:dsig="http://www.w3.org/2000/09/xmldsig#">
+ <dsig:Transform
Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"
xmlns:dsig="http://www.w3.org/2000/09/xmldsig#"/>
+ </dsig:Transforms>
+ <dsig:DigestMethod
Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"
xmlns:dsig="http://www.w3.org/2000/09/xmldsig#"/>
+ <dsig:DigestValue
xmlns:dsig="http://www.w3.org/2000/09/xmldsig#">so9bv09wxSna...
+ </dsig:Reference>
+ </dsig:SignedInfo>
+
<dsig:SignatureValue>Lf4DYODLtVxSVmd23HJzHTy61ZYDnpaJRTVbRLR2i2zU7v9mskYCVbXY8gm5PYY2V+iYvi+dJ3QlWP9dQu+DHK9rVJSGxSmzfPjrnMC84HH9j2BZBEdKVCpNCAFJQRL+E1jlRB194sjCiuxoMnlR927uMiNcHJRoBSi03kP5tOw=</dsig:SignatureValue>
+ <dsig:KeyInfo>
+ <dsig:KeyValue
xmlns:dsig="http://www.w3.org/2000/09/xmldsig#">
+ <dsig:RSAKeyValue
xmlns:dsig="http://www.w3.org/2000/09/xmldsig#">
+ <dsig:Modulus
xmlns:dsig="http://www.w3.org/2000/09/xmldsig#">suGIyhVTbFvD...
+ </dsig:Modulus>
+ <dsig:Exponent
xmlns:dsig="http://www.w3.org/2000/09/xmldsig#">AQAB</dsi...
+ </dsig:RSAKeyValue>
+ </dsig:KeyValue>
+ </dsig:KeyInfo>
+ </dsig:Signature>
+</Assertion>
Added:
identity-federation/trunk/jboss-identity-fed-core/src/test/resources/wstrust/assertion.xml
===================================================================
---
identity-federation/trunk/jboss-identity-fed-core/src/test/resources/wstrust/assertion.xml
(rev 0)
+++
identity-federation/trunk/jboss-identity-fed-core/src/test/resources/wstrust/assertion.xml 2009-10-30
10:05:58 UTC (rev 886)
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Assertion xmlns="urn:oasis:names:tc:SAML:2.0:assertion"
ID="ID_74414f7f-1339-4f80-b29a-c947d9177445"
IssueInstant="2009-09-10T13:49:30.422Z" Version="2.0">
+ <Issuer>JBossSTS</Issuer>
+ <Subject>
+ <NameID
NameQualifier="urn:jboss:identity-federation">beve</NameID>
+ <SubjectConfirmation
Method="urn:oasis:names:tc:SAML:2.0:cm:bearer"/>
+ </Subject>
+ <Conditions NotBefore="2009-09-10T13:49:30.422Z"
NotOnOrAfter="2009-09-10T15:49:30.422Z"/>
+ <dsig:Signature
xmlns:dsig="http://www.w3.org/2000/09/xmldsig#">
+ <dsig:SignedInfo><dsig:CanonicalizationMethod
Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#WithComments"
xmlns:dsig="http://www.w3.org/2000/09/xmldsig#"/>
+ <dsig:SignatureMethod
Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"
xmlns:dsig="http://www.w3.org/2000/09/xmldsig#"/>
+ <dsig:Reference URI="#ID_74414f7f-1339-4f80-b29a-c947d9177445"
xmlns:dsig="http://www.w3.org/2000/09/xmldsig#">
+ <dsig:Transforms
xmlns:dsig="http://www.w3.org/2000/09/xmldsig#">
+ <dsig:Transform
Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"
xmlns:dsig="http://www.w3.org/2000/09/xmldsig#"/>
+ </dsig:Transforms>
+ <dsig:DigestMethod
Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"
xmlns:dsig="http://www.w3.org/2000/09/xmldsig#"/>
+ <dsig:DigestValue
xmlns:dsig="http://www.w3.org/2000/09/xmldsig#">so9bv09wxSna...
+ </dsig:Reference>
+ </dsig:SignedInfo>
+
<dsig:SignatureValue>Lf4DYODLtVxSVmd23HJzHTy61ZYDnpaJRTVbRLR2i2zU7v9mskYCVbXY8gm5PYY2V+iYvi+dJ3QlWP9dQu+DHK9rVJSGxSmzfPjrnMC84HH9j2BZBEdKVCpNCAFJQRL+E1jlRB194sjCiuxoMnlR927uMiNcHJRoBSi03kP5tOw=</dsig:SignatureValue>
+ <dsig:KeyInfo>
+ <dsig:KeyValue
xmlns:dsig="http://www.w3.org/2000/09/xmldsig#">
+ <dsig:RSAKeyValue
xmlns:dsig="http://www.w3.org/2000/09/xmldsig#">
+ <dsig:Modulus
xmlns:dsig="http://www.w3.org/2000/09/xmldsig#">suGIyhVTbFvD...
+ </dsig:Modulus>
+ <dsig:Exponent
xmlns:dsig="http://www.w3.org/2000/09/xmldsig#">AQAB</dsi...
+ </dsig:RSAKeyValue>
+ </dsig:KeyValue>
+ </dsig:KeyInfo>
+ </dsig:Signature>
+</Assertion>
Added:
identity-federation/trunk/jboss-identity-fed-core/src/test/resources/wstrust/auth/jboss-sts-client.properties
===================================================================
---
identity-federation/trunk/jboss-identity-fed-core/src/test/resources/wstrust/auth/jboss-sts-client.properties
(rev 0)
+++
identity-federation/trunk/jboss-identity-fed-core/src/test/resources/wstrust/auth/jboss-sts-client.properties 2009-10-30
10:05:58 UTC (rev 886)
@@ -0,0 +1,5 @@
+serviceName=JBossSTS
+portName=JBossSTSPort
+endpointAddress=http://test:8080/JBossSTS
+username=user1
+password=pass1