Product SiteDocumentation Site

14.7. Trust

14.7.1. Security Token Server (STS)

14.7.1.1. Introduction

The WS-Trust specification defines extensions that build on WS-Security to provide a framework for requesting and issuing security tokens. Particularly, WS-Trust defines the concept of a security token service (STS), a service that can issue, cancel, renew and validate security tokens, and specifies the format of security token request and response messages.

Tip

Please look at the PicketLink Quickstarts for the PicketLink Identity Provider web application. The quickstarts are useful resources where you can get configuration files.

14.7.1.3. PicketLink JBoss Web Services Handlers

Page to list all the JBoss Web Services handlers that are part of the PicketLink project.
  1. SAML2Handler
  2. BinaryTokenHandler
  3. WSAuthenticationHandler
  4. WSAuthorizationHandler
14.7.1.3.1. BinaryTokenHandler
14.7.1.3.1.1. Fully Qualified Name
org.picketlink.trust.jbossws.handler.BinaryTokenHandler
14.7.1.3.1.2. Objective
A JBoss Web Services Handler that is stack agnostic that can be added on the client side to either pick a http header or cookie, that contains a binary token.
14.7.1.3.1.3. Author
Anil Saldhana
14.7.1.3.1.4. Settings
Configuration:
System Properties:
  • binary.http.header: http header name
  • binary.http.cookie: http cookie name
  • binary.http.encodingType: attribute value of the EncodingType attribute
  • binary.http.valueType: attribute value of the ValueType attribute
  • binary.http.valueType.namespace: namespace for the ValueType attribute
  • binary.http.valueType.prefix: namespace for the ValueType attribute
  • binary.http.cleanToken: true or false dependending on whether the binary token has to be cleaned
Setters:
Please see the see also section.See Also:setHttpHeaderName(String)setHttpCookieName(String)setEncodingType(String)setValueType(String)setValueTypeNamespace(String)setValueTypePrefix(String)
14.7.1.3.2. SAML2Handler
14.7.1.3.2.1. Full Name:
org.picketlink.trust.jbossws.handler.SAML2Handler
14.7.1.3.2.2. Authors:
  • Marcus Moyses
  • Anil Saldhana
14.7.1.3.2.3. Objective:
This is a JBossWS handler (stack agnostic) that supports the SAML token profile of the Oasis Web Services Security (WSS) standard.
It can be configured both on the client side and the server side. The configuration is shown below both the client(outbound) as well as server(inbound).
14.7.1.3.2.3.1. Outbound:
This is the behavior when the handler is configured on the client side.
The client side usage is shown in the following client class. If you need to use an XML file to specify the handler on the client side, then please look in the references section below.

Example 14.18. STSWSClientTestCase.java

package org.picketlink.test.trust.tests;

import java.net.URL;
import java.util.List;

import javax.xml.namespace.QName;
import javax.xml.ws.BindingProvider;
import javax.xml.ws.Service;
import javax.xml.ws.handler.Handler;

import org.junit.Test;
import org.picketlink.identity.federation.api.wstrust.WSTrustClient;
import org.picketlink.identity.federation.api.wstrust.WSTrustClient.SecurityInfo;
import org.picketlink.identity.federation.core.wstrust.WSTrustException;
import org.picketlink.identity.federation.core.wstrust.plugins.saml.SAMLUtil;
import org.picketlink.test.trust.ws.WSTest;
import org.picketlink.trust.jbossws.SAML2Constants;
import org.picketlink.trust.jbossws.handler.SAML2Handler;
import org.w3c.dom.Element;

/**
 * A Simple WS Test for the SAML Profile of WSS
 * @author Marcus Moyses
 * @author Anil Saldhana
 */
public class STSWSClientTestCase
{
   private static String username = "UserA";
   private static String password = "PassA";

   @SuppressWarnings("rawtypes")
   @Test
   public void testWSInteraction() throws Exception {
      WSTrustClient client = new WSTrustClient("PicketLinkSTS", "PicketLinkSTSPort",
            "http://localhost:8080/picketlink-sts/PicketLinkSTS",
            new SecurityInfo(username, password));
    Element assertion = null;
    try {
        System.out.println("Invoking token service to get SAML assertion for " + username);
        assertion = client.issueToken(SAMLUtil.SAML2_TOKEN_TYPE);
        System.out.println("SAML assertion for " + username + " successfully obtained!");
    } catch (WSTrustException wse) {
        System.out.println("Unable to issue assertion: " + wse.getMessage());
        wse.printStackTrace();
        System.exit(1);
    }

    URL wsdl = new URL("http://localhost:8080/picketlink-wstest-tests/WSTestBean?wsdl");
    QName serviceName = new QName("http://ws.trust.test.picketlink.org/", "WSTestBeanService");
    Service service = Service.create(wsdl, serviceName);
    WSTest port = service.getPort(new QName("http://ws.trust.test.picketlink.org/", "WSTestBeanPort"), WSTest.class);
    BindingProvider bp = (BindingProvider)port;
    bp.getRequestContext().put(SAML2Constants.SAML2_ASSERTION_PROPERTY, assertion);
    List<Handler> handlers = bp.getBinding().getHandlerChain();
    handlers.add(new SAML2Handler());
    bp.getBinding().setHandlerChain(handlers);

    port.echo("Test");
   }
}
Note: the SAML2Handler is instantiated and added to the handler list that is obtained from the BindingProvider binding.
There are two ways by which the SAML2Handler picks the SAML2 Assertion to send via the SOAP message.
  • The Client can push the SAML2 Assertion into the SOAP MessageContext under the key " org.picketlink.trust.saml.assertion ". In the example code above, look in the call bindingProvider.getRequestContext().put(xxxxx)
  • The SAML2 Assertion is available as part of the JAAS subject on the security context. This can happen if there has been a JAAS interaction with the usage of PicketLink STS login modules.
14.7.1.3.2.3.2. Inbound:
This is the behavior when the handler is configured on the server side.
The server side setting is as follows:

Example 14.19. handlers.xml

<?xml version="1.0" encoding="UTF-8"?>


<handler-chains xmlns="http://java.sun.com/xml/ns/javaee"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:ns1="http://org.jboss.ws/jaxws/samples/logicalhandler"
  xsi:schemaLocation="http://java.sun.com/xml/ns/javaee javaee_web_services_1_2.xsd">



  <handler-chain>
    <handler>
      <handler-name>SAML2Handler</handler-name>
      <handler-class>org.picketlink.trust.jbossws.handler.SAML2Handler</handler-class>
    </handler>
  </handler-chain>


</handler-chains>
The SAML2Handler looks for a SAML2 Assertion on the SOAP message. If it is available then it constructs a SamlCredential object with the assertion and then sets it on the SecurityContext for the JAAS layer to authenticate the call.
14.7.1.3.3. WSAuthenticationHandler
14.7.1.3.3.1. FQN:
org.picketlink.trust.jbossws.handler.WSAuthenticationHandler
14.7.1.3.3.2. Objective:
Perform authentication for POJO based webservices.
14.7.1.3.3.3. Example Usage:
Assume that you have a POJO.
package org.picketlink.test.trust.ws;

import javax.jws.HandlerChain;
import javax.jws.WebMethod;
import javax.jws.WebService;
import javax.jws.soap.SOAPBinding;

/**
 * POJO that is exposed as WS
 * @author Anil Saldhana
 */
@WebService
@SOAPBinding(style = SOAPBinding.Style.RPC)
@HandlerChain(file="authorize-handlers.xml")
public class POJOBean
{
   @WebMethod
   public void echo(String echo)
   {
      System.out.println(echo);
   }

   @WebMethod
   public void echoUnchecked(String echo)
   {
      System.out.println(echo);
   }
}
Note the use of the @HandlerChain annotation that defines the handler xml.
The handler xml is authorize-handlers.xml.
<?xml version="1.0" encoding="UTF-8"?>


<handler-chains xmlns="http://java.sun.com/xml/ns/javaee"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://java.sun.com/xml/ns/javaee javaee_web_services_1_2.xsd">

  <handler-chain>


    <handler>
      <handler-name>WSAuthorizationHandler</handler-name>
      <handler-class>org.picketlink.trust.jbossws.handler.WSAuthorizationHandler</handler-class>
    </handler>

    <handler>
      <handler-name>WSAuthenticationHandler</handler-name>
      <handler-class>org.picketlink.trust.jbossws.handler.WSAuthenticationHandler</handler-class>
    </handler>

    <handler>
      <handler-name>SAML2Handler</handler-name>
      <handler-class>org.picketlink.trust.jbossws.handler.SAML2Handler</handler-class>
    </handler>


  </handler-chain>


</handler-chains>

Warning

Note : The order of execution of the handlers is SAML2Handler, WSAuthenticationHandler and WSAuthorizationHandler. These need to be defined in reverse order in the xml.
Since we intend to expose a POJO as a webservice, we need to package in a web archive (war).
The web.xml is:
<web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
	version="2.5">

	<servlet>
		<display-name>POJO Web Service</display-name>
		<servlet-name>POJOBeanService</servlet-name>
		<servlet-class>org.picketlink.test.trust.ws.POJOBean</servlet-class>
		<load-on-startup>1</load-on-startup>
	</servlet>
	<servlet-mapping>
		<servlet-name>POJOBeanService</servlet-name>
		<url-pattern>/POJOBeanService</url-pattern>
	</servlet-mapping>
</web-app>

Warning

Please do not define any <security-constraint> in the web.xml
The jboss-web.xml is:
<jboss-web>
  <security-domain>sts</security-domain>
</jboss-web>
The jboss-wsse.xml is
<jboss-ws-security xmlns="http://www.jboss.com/ws-security/config"
                   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                   xsi:schemaLocation="http://www.jboss.com/ws-security/config
                   http://www.jboss.com/ws-security/schema/jboss-ws-security_1_0.xsd">

  <port name="POJOBeanPort">
    <operation name="{http://ws.trust.test.picketlink.org/}echoUnchecked">
      <config>
        <authorize>
          <unchecked/>
        </authorize>
      </config>
    </operation>

    <operation name="{http://ws.trust.test.picketlink.org/}echo">
      <config>
        <authorize>
          <role>JBossAdmin</role>
        </authorize>
      </config>
    </operation>
  </port>



</jboss-ws-security>
As you can see, there are two operations defined on the POJO web services and each of these operations require different access control. The echoUnchecked() method allows free access to any authenticated user whereas the echo() method requires the caller to have "JBossAdmin" role.
The war should look as:
anil@localhost:~/picketlink/picketlink/integration-tests/trunk/picketlink-trust-tests$ jar tvf target/pojo-test.war
     0 Mon Apr 11 19:48:32 CDT 2011 META-INF/
   123 Mon Apr 11 19:48:30 CDT 2011 META-INF/MANIFEST.MF
     0 Mon Apr 11 19:48:30 CDT 2011 WEB-INF/
     0 Mon Apr 11 19:48:30 CDT 2011 WEB-INF/classes/
     0 Mon Apr 11 19:48:30 CDT 2011 WEB-INF/classes/org/
     0 Mon Apr 11 19:48:30 CDT 2011 WEB-INF/classes/org/picketlink/
     0 Mon Apr 11 19:48:30 CDT 2011 WEB-INF/classes/org/picketlink/test/
     0 Mon Apr 11 19:48:30 CDT 2011 WEB-INF/classes/org/picketlink/test/trust/
     0 Mon Apr 11 19:48:30 CDT 2011 WEB-INF/classes/org/picketlink/test/trust/ws/
     0 Mon Apr 11 19:48:30 CDT 2011 WEB-INF/lib/
   858 Mon Apr 11 19:48:26 CDT 2011 WEB-INF/classes/authorize-handlers.xml
  1021 Mon Apr 11 19:48:28 CDT 2011 WEB-INF/classes/org/picketlink/test/trust/ws/POJOBean.class
    65 Mon Apr 11 12:00:32 CDT 2011 WEB-INF/jboss-web.xml
   770 Mon Apr 11 17:44:16 CDT 2011 WEB-INF/jboss-wsse.xml
   598 Mon Apr 11 16:25:46 CDT 2011 WEB-INF/web.xml
     0 Mon Apr 11 19:48:32 CDT 2011 META-INF/maven/
     0 Mon Apr 11 19:48:32 CDT 2011 META-INF/maven/org.picketlink/
     0 Mon Apr 11 19:48:32 CDT 2011 META-INF/maven/org.picketlink/picketlink-integration-trust-tests/
  7918 Mon Apr 11 18:56:16 CDT 2011 META-INF/maven/org.picketlink/picketlink-integration-trust-tests/pom.xml
   142 Mon Apr 11 19:48:30 CDT 2011 META-INF/maven/org.picketlink/picketlink-integration-trust-tests/pom.properties
anil@localhost:~/picketlink/picketlink/integration-tests/trunk/picketlink-trust-tests
The Test Case is something like:
 package org.picketlink.test.trust.tests;

import java.net.URL;
import java.util.List;

import javax.xml.namespace.QName;
import javax.xml.ws.BindingProvider;
import javax.xml.ws.Service;
import javax.xml.ws.handler.Handler;

import org.junit.Test;
import org.picketlink.identity.federation.api.wstrust.WSTrustClient;
import org.picketlink.identity.federation.api.wstrust.WSTrustClient.SecurityInfo;
import org.picketlink.identity.federation.core.wstrust.WSTrustException;
import org.picketlink.identity.federation.core.wstrust.plugins.saml.SAMLUtil;
import org.picketlink.test.trust.ws.WSTest;
import org.picketlink.trust.jbossws.SAML2Constants;
import org.picketlink.trust.jbossws.handler.SAML2Handler;
import org.w3c.dom.Element;

/**
 * A Simple WS Test for POJO WS Authorization using PicketLink
 * @author Anil Saldhana
 * @since Oct 3, 2010
 */
public class POJOWSAuthorizationTestCase
{
   private static String username = "UserA";
   private static String password = "PassA";

   @SuppressWarnings("rawtypes")
   @Test
   public void testWSInteraction() throws Exception
   {
      // Step 1:  Get a SAML2 Assertion Token from the STS
      WSTrustClient client = new WSTrustClient("PicketLinkSTS", "PicketLinkSTSPort",
            "http://localhost:8080/picketlink-sts/PicketLinkSTS",
            new SecurityInfo(username, password));
      Element assertion = null;
      try {
         System.out.println("Invoking token service to get SAML assertion for " + username);
         assertion = client.issueToken(SAMLUtil.SAML2_TOKEN_TYPE);
         System.out.println("SAML assertion for " + username + " successfully obtained!");
      } catch (WSTrustException wse) {
         System.out.println("Unable to issue assertion: " + wse.getMessage());
         wse.printStackTrace();
         System.exit(1);
      }

      // Step 2: Stuff the Assertion on the SOAP message context and add the SAML2Handler to client side handlers
      URL wsdl = new URL("http://localhost:8080/pojo-test/POJOBeanService?wsdl");
      QName serviceName = new QName("http://ws.trust.test.picketlink.org/", "POJOBeanService");
      Service service = Service.create(wsdl, serviceName);
      WSTest port = service.getPort(new QName("http://ws.trust.test.picketlink.org/", "POJOBeanPort"), WSTest.class);
      BindingProvider bp = (BindingProvider)port;
      bp.getRequestContext().put(SAML2Constants.SAML2_ASSERTION_PROPERTY, assertion);
      List<Handler> handlers = bp.getBinding().getHandlerChain();
      handlers.add(new SAML2Handler());
      bp.getBinding().setHandlerChain(handlers);

      //Step 3: Access the WS. Exceptions will be thrown anyway.
      port.echo("Test");
   }
}
14.7.1.3.4. WSAuthorizationHandler
14.7.1.3.4.1. FQN:
org.picketlink.trust.jbossws.handler.WSAuthorizationHandler
14.7.1.3.4.2. Objective:
Provide authorization capabilities to POJO based web services.
14.7.1.3.4.3. Example Usage:
Please refer to the documentation on WSAuthenticationHandler.

Important

The example is in WSAuthenticationHandler section.

14.7.1.4. Protecting EJB Endpoints

14.7.1.4.1. Introduction
PicketLink provides ways to protect your EJB endpoints using a SAML Security Token Service. This means that you can apply some security to your EJBs where only users with a valid SAML assertion can invoke to them.
This scenario is very common if you are looking for:
  1. Leverage your Single Sign-On infrastructure to your service layer (EJBs, Web Services, etc)
  2. Integrate your SAML Service Providers with your services by trusting the assertion previously issued by the Identity Provider
  3. Any situation that requires the propagation of authorization/authentication information from one domain to another
14.7.1.4.1.1. Process Overview
The client must first obtain the SAML assertion from PicketLink STS by sending a WS-Trust request to the token service. This process usually involves authentication of the client. After obtaining the SAML assertion from the STS, the client includes the assertion in the security context of the EJB request before invoking an operation on the bean. Upon receiving the invocation, the EJB container extracts the assertion and validates it by sending a WS-Trust validate message to the STS. If the assertion is considered valid by the STS (and the proof of possession token has been verified if needed), the client is authenticated.
TODO Gliffy image title empty

Figure 14.1. TODO Gliffy image title empty

On JBoss, the SAML assertion validation process is handled by the SAML2STSLoginModule. It reads properties from a configurable file (specified by the configFile option) and establishes communication with the STS based on these properties. We will see how a configuration file looks like later on. If the assertion is valid, a Principal is created using the assertion subject name and if the assertion contains roles, these roles are also extracted and associated with the caller's Subject.
The client must first obtain the SAML assertion from the PicketLink STS or you Identity Provider. This process usually involves authentication of the client. After obtaining the SAML assertion, the client includes the assertion in the security context of the EJB request before invoking an operation on the bean. Upon receiving the invocation, the EJB container extracts the assertion and validates it by sending a WS-Trust validate message to the STS. If the assertion is considered valid by the STS (and the proof of possession token has been verified if needed), the client is authenticated.
On JBoss, the SAML assertion validation process is handled by the Section 14.7.1.5.3, “SAML2STSLoginModule” . It reads properties from a configurable file (specified by the configFile option) and establishes communication with the STS based on these properties. We will see how a configuration file looks like later on. If the assertion is valid, a Principal is created using the assertion subject name and if the assertion contains roles, these roles are also extracted and associated with the caller's Subject.
14.7.1.4.2. Configuration
This section will cover two possible scenarios to protect and access your secured EJB endpoints. The main difference between these two scenarios is where the EJB client is deployed.
  • Remote EJB Client using JNDI
  • EJB Client is deployed at the same instance than your EJB endpoints
14.7.1.4.2.1. Remote EJB Client using JNDI

Important

Before starting, please take a look at the following documentation Remote EJB invocations via JNDI .
The configuration described in this section only works with versions 7.2.0+ and 7.1.3+ of JBoss Application Server.
If your endpoints are accessible from remote clients (in a different VM or server than your endpoints) you need to configure your JBoss Application Server 7 to allow use a SAML Assertion during the InitialContext creation.
Basically, the configuration envolves the following steps:
  1. Add a new Security Realm to your standalone.xml
  2. Create a Security Domain using the Section 14.7.1.5.3, “SAML2STSLoginModule”
  3. Change the Remoting Connector to use the new Security Realm
14.7.1.4.2.1.1. Add a new Security Realm

Important

Security Realms are better described in the JBoss Application Server Documentation.
Edit your standalone.xml and add the following configuration for a new Security Realm:
<security-realm name="SAMLRealm">
    <authentication>
        <jaas name="ejb-remoting-sts"/>
    </authentication>
</security-realm>
The configuration above defines a Security Realm that delegates the username/password information to a JAAS Security Domain (that we'll create later) in order to authenticate an user.
When using the JAAS configuration for Security Realms, the remoting subsystem enables the PLAIN SASL authentication. This will allow your remote clients send the username/password where the password would be the previously issued SAML Assertion.In our case, the password will be the String representation of the SAML Assertion.

Tip

Make sure you also enable SSL. Otherwise all communication with the server will be done using plain text.
14.7.1.4.2.1.2. Create a Security Domain using the SAML2STSLoginModule
Edit your standalone.xml and add the following configuration for a new Security Domain:
<security-domain name="ejb-remoting-sts" cache-type="default">
    <authentication>
        <login-module code="org.picketlink.identity.federation.bindings.jboss.auth.SAML2STSLoginModule" flag="required" module="org.picketlink">
            <module-option name="configFile" value="${jboss.server.config.dir}/sts-config.properties"/>
            <module-option name="password-stacking" value="useFirstPass"/>
        </login-module>
    </authentication>
</security-domain>
This configuration above defines a Security Domain that uses the SAML2STSLoginModule to get the String representation of the SAML Assertion and validate it against the Security Token Service.
You may notice that we provided a properties file as module-option. This properties file defines all the configuration needed to invoke the PicketLink STS. It should look like this:
serviceName=PicketLinkSTS
portName=PicketLinkSTSPort
endpointAddress=http://localhost:8080/picketlink-sts/PicketLinkSTS
username=admin
#password=admin
password=MASK-0BbleBL2LZk=
salt=18273645
iterationCount=56

#java -cp picketlink-fed-core.jar org.picketlink.identity.federation.core.util.PBEUtils 18273645 56 admin
#Encoded password: MASK-0BbleBL2LZk=
This security domain will be used to authenticate your remote clients during the creation of the JNDI Initial Context.
14.7.1.4.2.1.3. Change the Remoting Connector Security Realm
Edit your standalone.xml and change the security-realm attribute of the remoting connector:
<subsystem xmlns="urn:jboss:domain:remoting:1.1">
    <connector name="remoting-connector" socket-binding="remoting" security-realm="SAMLRealm"/>
</subsystem>
The connector configuration is already present in your standalone.xml. You only need to change the security-realm attribute to match the one we created before.
14.7.1.4.2.1.4. EJB Remote Client
The code above shows you how a EJB Rremote Client may look like:
// add the JDK SASL Provider that allows to use the PLAIN SASL Client
Security.addProvider(new Provider());

Element assertion = getAssertionFromSTS("UserA", "PassA");

// JNDI environment configuration properties
Hashtable<String, Object> env = new Hashtable<String, Object>();

env.put(Context.URL_PKG_PREFIXES, "org.jboss.ejb.client.naming");
env.put("java.naming.factory.initial", "org.jboss.naming.remote.client.InitialContextFactory");
env.put("java.naming.provider.url", "remote://localhost:4447");
env.put("jboss.naming.client.ejb.context", "true");
env.put("jboss.naming.client.connect.options.org.xnio.Options.SASL_POLICY_NOPLAINTEXT", "false");
env.put("javax.security.sasl.policy.noplaintext", "false");

// provide the user principal and credential. The credential is the previously issued SAML assertion
env.put(Context.SECURITY_PRINCIPAL, "admin");
env.put(Context.SECURITY_CREDENTIALS, DocumentUtil.getNodeAsString(assertion));

// create the JNDI Context and perform the authentication using the SAML2STSLoginModule
Context context = new InitialContext(env);

// lookup the EJB
EchoService object = (EchoService) context.lookup("ejb-test/EchoServiceImpl!org.picketlink.test.trust.ejb.EchoService");

// If everything is ok the Principal name will be added to the message
Assert.assertEquals("Hi UserA", object.echo("Hi "));

14.7.1.5. STS Login Modules

This page references the PicketLink Login Modules for the Security Token Server.
14.7.1.5.1. References

Tip

PicketLink STS Login Modules has the required details.
14.7.1.5.2. JBWSTokenIssuingLoginModule
14.7.1.5.2.1. Fully Qualified Name
org.picketlink.trust.jbossws.jaas. JBWSTokenIssuingLoginModule
14.7.1.5.2.2. Objective
A variant of the PicketLink STSIssuingLoginModule that allows us to:
  1. Inject BinaryTokenHandler or SAML2Handler or both as client side handlers to the STS WS call.
  2. Inject the JaasSecurityDomainServerSocketFactory DomainSocketFactory as a request property to the BindingProvider set to the key "org.jboss.ws.socketFactory". This is useful for mutually authenticated SSL with the STS where in we use a trust store defined by a JaasSecurityDomain instance.
14.7.1.5.2.3. Configuration
Options Include:
  • configFile : a properties file that gives details on the STS to the login module. This can be optional if you want to specify values directly.
  • handlerChain : Comma separated list of handlers you need to set for handling outgoing message to STS. Values: binary (to inject BinaryTokenHandler), saml2 (to inject SAML2Handler), map (to inject MapBasedTokenHandler) or class name of your own handler with default constructor.
  • cache.invalidation : set it to "true" if you want the JBoss auth cache to invalidate caches based on saml token expiry. By default, this value is false.
  • inject.callerprincipa l: set it to "true" if the login module should add a group principal called "CallerPrincipal" to the subject. This is useful in JBoss AS for programmatic security in web/ejb components.
  • groupPrincipalName : by default, JBoss AS security uses "Roles" as the group principal name in the subject. You can give a different value.
  • endpointAddress : endpoint url of STS
  • serviceName : service Name of STS
  • portName : port name of STS
  • username : username of account on STS.
  • password : password of account on STS
  • wsaIssuer : if you need to customize the WS-Addressing Issuer address in the WS-Trust call to the STS.
  • wspAppliesTo : if you need to customize the WS-Policy AppliesTo in the WS-Trust call to the STS.
  • securityDomainForFactory : if you have a JaasSecurityDomain mbean service in JBoss AS that provides the truststore.
  • map.token.key : key to find binary token in JAAS sharedState map. Defaults to "ClientID".
  • soapBinding : allow to change SOAP binding for SAML reuest.
  • requestType : allows to override SAML request type when sending request to STS. Default: "http://docs.oasis-open.org/ws-sx/ws-trust/200512/Issue" Other possible value: "http://docs.oasis-open.org/ws-sx/ws-trust/200512/Validate".
Note: The configFile option is optional. If you provide that, then it should be as below.
Configuration file such as sts-client.properties.
serviceName=PicketLinkSTS
portName=PicketLinkSTSPort
endpointAddress=http://localhost:8080/picketlink-sts/PicketLinkSTS
username=admin
password=admin
wsaIssuer=http://localhost:8080/someissuer
wspAppliesTo=http://localhost:8080/testws
Note:
  • the password can be masked according to http://community.jboss.org/wiki/PicketLinkConfigurationMaskpassword which would give us something like, password=MASK-dsfdsfdslkfh
  • wsaIssuer can be optionally added if you want a value for the WS-Addressing issuer in the WS-Trust call to the STS.
  • wspAppliesTo can be optionally added if you want a value for WS-Policy AppliesTo in the WS-Trust call to the STS.
  • serviceName, portName, endpointAddress are mandatory .
  • username and password keys are not needed if you are using mutual authenticated ssl (MASSL) with the STS.
14.7.1.5.2.3.1. SSL DomainSocketFactory in use by the client side
Many a times, the login module has to communicate with the STS over a mutually authenticated SSL. In this case, you want to specify the truststore. JBoss AS provides JaasSecurityDomain mbean to specify truststore. For this reason, there is a special JaasSecurityDomainServerSocketFactory that can be used for making the JBWS calls. Specify the "securityDomainForFactory" module option with the security domain name (in the JaasSecurityDomain mbean service).
14.7.1.5.2.4. Example configurations
Either you specify the module options directly or you can use a properties file for the STS related properties.
14.7.1.5.2.4.1. Configuration specified directly
<application-policy name="saml-issue-token">
 <authentication>
  <login-module code="org.picketlink.identity.federation.core.wstrust.auth.JBWSTokenIssuingLoginModule" flag="required">

       <module-option name="password-stacking">useFirstPass</module-option>

       <module-option name="endpointAddress">http://somests</module-option>

        <module-option name="serviceName">PicketLinkSTS</module-option>

       <module-option name="portName">PicketLinkPort</module-option>

       <module-option name="username">admin</module-option>

       <module-option name="password">admin</module-option>

       <module-option name="inject.callerprincipal">true</module-option>
       <module-option name="groupPrincipalName">Membership</module-option>
     </login-module>
    </authentication>
</application-policy>

14.7.1.5.2.4.2. Configuration with configFileOption
<application-policy name="saml-issue-token">
 <authentication>
  <login-module code="org.picketlink.identity.federation.core.wstrust.auth.JBWSTokenIssuingLoginModule" flag="required">
       <module-option name="configFile">/sts-client.properties</module-option>
       <module-option name="password-stacking">useFirstPass</module-option>
<module-option name="cache.invalidation">true</module-option>
<module-option name="inject.callerprincipal">true</module-option>
<module-option name="groupPrincipalName">Membership</module-option>
     </login-module>
    </authentication>
</application-policy>
14.7.1.5.2.4.3. Dealing with Roles
If the STS sends roles via Attribute Statements in the SAML assertion, then the user has to use the SAMLRoleLoginModule.
<application-policy name="saml">
  <authentication>
    <login-module code="org.picketlink.trust.jbossws.jaas.JBWSTokenIssuingLoginModule"  flag="required">
         <module-option name="endpointAddress">SOME_URL</module-option>
         <module-option name="serviceName">SecurityTokenService</module-option>
         <module-option name="portName">RequestSecurityToken</module-option>
         <module-option name="inject.callerprincipal">true</module-option>
         <module-option name="handlerChain">binary</module-option>
    </login-module>
    <login-module code="org.picketlink.trust.jbossws.jaas.SAMLRoleLoginModule"  flag="required"/>
  </authentication>
</application-policy>
If the STS does not send roles, then the user has to configure a different JAAS login module to pick the roles for the username. Something like the UsernamePasswordLoginModule.
<application-policy xmlns="urn:jboss:security-beans:1.0" name="binary">
      <authentication>
         <login-module code="org.picketlink.trust.jbossws.jaas.JBWSTokenIssuingLoginModule" flag="required">
            <module-option name="endpointAddress">http://localhost:8080/picketlink-sts/PicketLinkSTS</module-option>
            <module-option name="serviceName">PicketLinkSTS</module-option>
            <module-option name="portName">PicketLinkSTSPort</module-option>
            <module-option name="inject.callerprincipal">true</module-option>
            <module-option name="handlerChain">binary</module-option>
            <module-option name="username">admin</module-option>
            <module-option name="password">MASK-0BbleBL2LZk=</module-option>
            <module-option name="salt">18273645</module-option>
            <module-option name="iterationCount">56</module-option>
            <module-option name="useOptionsCredentials">true</module-option>
            <module-option name="overrideDispatch">true</module-option>
            <module-option name="wspAppliesTo">http://services.testcorp.org/provider1</module-option>
            <module-option name="wsaIssuer">http://something</module-option>
            <module-option name="password-stacking">useFirstPass</module-option>
         </login-module>

         <login-module code="org.jboss.security.auth.spi.UsersRolesLoginModule" flag="required">
            <module-option name="usersProperties">sts-users.properties</module-option>
            <module-option name="rolesProperties">sts-roles.properties</module-option>
            <module-option name="password-stacking">useFirstPass</module-option>
         </login-module>
      </authentication>
   </application-policy>
14.7.1.5.3. SAML2STSLoginModule
14.7.1.5.3.1. FQN
org.picketlink.identity.federation.bindings.jboss.auth. SAML2STSLoginModule
14.7.1.5.3.2. Author:
Stefan Guilhen
14.7.1.5.3.3. Objective
This LoginModule authenticates clients by validating their SAML assertions with an external security token service (such as PicketLinkSTS). If the supplied assertion contains roles, these roles are extracted and included in the Group returned by the getRoleSets method.
The LoginModule could be also used to retrieve and validate SAML assertion token from HTTP request header.
14.7.1.5.3.4. Module Options
This module defines the following module options:
  • configFile - this property identifies the properties file that will be used to establish communication with the external security token service.
  • cache.invalidation : set it to true if you require invalidation of JBoss Auth Cache at SAML Principal expiration.
  • jboss.security.security_domain -security domain at which Principal will expire if cache.invalidation is used.
  • roleKey : key of the attribute name that we need to use for Roles from the SAML assertion. This can be a comma-separated string values such as (Role,Membership)
  • localValidation : if you want to validate the assertion locally for signature and expiry
  • localValidationSecurityDomain : the security domain for the trust store information (via the JaasSecurityDomain)
  • tokenEncodingType : encoding type of SAML token delivered via http request's header. Possible values are:
    • base64 - content encoded as base64. In case of encoding will vary between base64 and gzip use base64 and LoginModule will detect gzipped data.
    • gzip - gzipped content encoded as base64
    • none - content not encoded in any way
  • samlTokenHttpHeader - name of http request header to fetch SAML token from. For example: "Authorize"
  • samlTokenHttpHeaderRegEx - Java regular expression to be used to get SAML token from "samlTokenHttpHeader". Example: use: . "(. )".* to parse SAML token from header content like this: SAML_assertion="HHDHS=", at the same time set samlTokenHttpHeaderRegExGroup to 1.
  • samlTokenHttpHeaderRegExGroup - Group value to be used when parsing out value of http request header specified by "samlTokenHttpHeader" using "samlTokenHttpHeaderRegEx".
pattern = Pattern.compile(samlTokenHttpHeaderRegEx, Pattern.DOTALL);
Matcher m = pattern.matcher(content);
m.matches();
m.group(samlTokenHttpHeaderRegExGroup)
Any properties specified besides the above properties are assumed to be used to configure how the STSClient will connect to the STS. For example, the JBossWS StubExt.PROPERTY_SOCKET_FACTORY can be specified in order to inform the socket factory that must be used to connect to the STS. All properties will be set in the request context of the Dispatch instance used by the STSClient to send requests to the STS.
An example of a configFile can be seen bellow:
serviceName=PicketLinkSTS
portName=PicketLinkSTSPort
endpointAddress=[http://localhost:8080/picketlink-sts/PicketLinkSTS]
username=JBoss
password=JBoss
The first three properties specify the STS endpoint URL, service name, and port name. The last two properties specify the username and password that are to be used by the application server to authenticate to the STS and have the SAML assertions validated.
NOTE: Sub-classes can use getSTSClient() method to customize the STSClient class to make calls to STS
14.7.1.5.3.5. Examples
Example Configuration 1:
<application-policy xmlns="urn:jboss:security-beans:1.0" name="cache-test">
      <authentication>
         <login-module code="org.picketlink.identity.federation.bindings.jboss.auth.SAML2STSLoginModule" flag="required">
            <module-option name="password-stacking">useFirstPass</module-option>
            <module-option name="configFile">sts-config.properties</module-option>
            <module-option name="cache.invalidation">true</module-option>
            <module-option name="localValidation">true</module-option>
            <module-option name="localValidationSecurityDomain">MASSL</module-option>
         </login-module>
      </authentication>
   </application-policy>
Example Configuration 2 using http header and local validation:
   <application-policy xmlns="urn:jboss:security-beans:1.0" name="service">
      <authentication>
         <login-module code="org.picketlink.identity.federation.bindings.jboss.auth.SAML2STSLoginModule" flag="required">
            <module-option name="password-stacking">useFirstPass</module-option>
            <module-option name="cache.invalidation">true</module-option>
            <module-option name="localValidation">true</module-option>
            <module-option name="localValidationSecurityDomain">java:jaas/localValidationDomain</module-option>
            <module-option name="tokenEncodingType">gzip</module-option>
            <module-option name="samlTokenHttpHeader">Auth</module-option>
            <module-option name="samlTokenHttpHeaderRegEx">.*"(.*)".*</module-option>
            <module-option name="samlTokenHttpHeaderRegExGroup">1</module-option>
         </login-module>
         <login-module code="org.picketlink.trust.jbossws.jaas.SAMLRoleLoginModule" flag="required"/>
      </authentication>
   </application-policy>
In case of local validation here is example of jboss-beans.xml file to use to configure JAAS Security Domain for (JBoss AS6 or EAP5):
<?xml version="1.0" encoding="UTF-8"?>
<deployment xmlns="urn:jboss:bean-deployer:2.0">
   <!-- localValidationDomain bean -->
   <bean name="LocalValidationBean" class="org.jboss.security.plugins.JaasSecurityDomain">
     <constructor>
          <parameter>localValidationDomain</parameter>
     </constructor>
     <property name="keyStoreURL">file://${jboss.server.home.dir}/conf/stspub.jks</property>
     <property name="keyStorePass">keypass</property>
     <property name="keyStoreAlias">sts</property>
     <property name="securityManagement"><inject bean="JNDIBasedSecurityManagement"/></property>
   </bean>
</deployment>
For JBoss AS7 or JBoss EAP6 add following security domain to your configuration file:
<security-domain name="localValidationDomain">
      <jsse
         keystore-password="keypass"
         keystore-type="JKS"
         keystore-url="file:///${jboss.server.config.dir}/stspub.jks"
         server-alias="sts"/>
</security-domain>
and reference this security domain as: <module-option name="localValidationSecurityDomain">localValidationDomain</module-option>.
14.7.1.5.4. SAMLTokenCertValidatingLoginModule
org.picketlink.identity.federation.bindings.jboss.auth. SAMLTokenCertValidatingLoginModule
14.7.1.5.4.1. Author:
Peter Skopek
14.7.1.5.4.2. Objective
This LoginModule authenticates clients by validating their SAML assertions locally. If the supplied assertion contains roles, these roles are extracted and included in the Group returned by the getRoleSets method.
The LoginModule is designed to validate SAML token using X509 certificate stored in XML signature within SAML assertion token.
It validates:
  1. CertPath against specified truststore. It has to have common valid public certificate in the trusted entries.
  2. X509 certificate stored in SAML token didn't expire
  3. if signature itself is valid
  4. SAML token expiration
14.7.1.5.4.3. Module Options
This module defines the following module options:
  • roleKey : key of the attribute name that we need to use for Roles from the SAML assertion. This can be a comma-separated string values such as (Role,Membership)
  • localValidationSecurityDomain : the security domain for the trust store information (via the JaasSecurityDomain)
  • cache.invalidation - set it to true if you require invalidation of JBoss Auth Cache at SAML Principal expiration.
  • jboss.security.security_domain -security domain at which Principal will expire if cache.invalidation is used.
  • tokenEncodingType : encoding type of SAML token delivered via http request's header. Possible values are:
    • base64 - content encoded as base64. In case of encoding will vary between base64 and gzip use base64 and LoginModule will detect gzipped data.
    • gzip - gzipped content encoded as base64
    • none - content not encoded in any way
  • samlTokenHttpHeader - name of http request header to fetch SAML token from. For example: "Authorize"
  • samlTokenHttpHeaderRegEx - Java regular expression to be used to get SAML token from "samlTokenHttpHeader". Example: use: . "(. )".* to parse SAML token from header content like this: SAML_assertion="HHDHS=", at the same time set samlTokenHttpHeaderRegExGroup to 1.
  • samlTokenHttpHeaderRegExGroup - Group value to be used when parsing out value of http request header specified by "samlTokenHttpHeader" using "samlTokenHttpHeaderRegEx".
pattern = Pattern.compile(samlTokenHttpHeaderRegEx, Pattern.DOTALL);
Matcher m = pattern.matcher(content);
m.matches();
m.group(samlTokenHttpHeaderRegExGroup)
14.7.1.5.4.4. Examples
Example Configuration 1:
<application-policy xmlns="urn:jboss:security-beans:1.0" name="certpath">
      <authentication>
         <login-module code="org.picketlink.identity.federation.bindings.jboss.auth.SAMLTokenCertValidatingLoginModule" flag="required">
            <module-option name="password-stacking">useFirstPass</module-option>
            <module-option name="cache.invalidation">true</module-option>
            <module-option name="localValidationSecurityDomain">java:jaas/localValidationDomain</module-option>
         </login-module>
      </authentication>
</application-policy>
Example Configuration 2 using http header:
   <application-policy xmlns="urn:jboss:security-beans:1.0" name="service">
      <authentication>
         <login-module code="org.picketlink.identity.federation.bindings.jboss.auth.SAML2STSLoginModule" flag="required">
            <module-option name="password-stacking">useFirstPass</module-option>
            <module-option name="cache.invalidation">true</module-option>
            <module-option name="localValidationSecurityDomain">java:jaas/localValidationDomain</module-option>
            <module-option name="tokenEncodingType">gzip</module-option>
            <module-option name="samlTokenHttpHeader">Auth</module-option>
            <module-option name="samlTokenHttpHeaderRegEx">.*"(.*)".*</module-option>
            <module-option name="samlTokenHttpHeaderRegExGroup">1</module-option>
         </login-module>
      </authentication>
   </application-policy>
Example of jboss-beans.xml file to use to configure JAAS Security Domain containing trust store for above examples:
<?xml version="1.0" encoding="UTF-8"?>
<deployment xmlns="urn:jboss:bean-deployer:2.0">
   <!-- localValidationDomain bean -->
   <bean name="LocalValidationBean" class="org.jboss.security.plugins.JaasSecurityDomain">
     <constructor>
          <parameter>localValidationDomain</parameter>
     </constructor>
     <property name="keyStoreURL">file://${jboss.server.home.dir}/conf/stspub.jks</property>
     <property name="keyStorePass">keypass</property>
     <property name="keyStoreAlias">sts</property>
     <property name="securityManagement"><inject bean="JNDIBasedSecurityManagement"/></property>
   </bean>
</deployment>
14.7.1.5.5. STSValidatingLoginModule
14.7.1.5.5.1. FQN:
org.picketlink.identity.federation.core.wstrust.auth.STSValidatingLoginModule
14.7.1.5.5.2. Author:
Daniel Bevenius
14.7.1.5.5.3. Objective/Features:
  • Calls the configured STS and validates an available security token.
  • A call to STS typically requires authentication. This LoginModule uses credentials from one of the following sources:
    • Its properties file, if the useOptionsCredentials module-option is set to true
    • Previous login module credentials if the password-stacking module-option is set to useFirstPass
    • From the configured CallbackHandler by supplying a Name and Password Callback
  • Upon successful authentication, the SamlCredential is inserted in the Subject's public credentials if one with the same Assertion is not found to be already present there.
  • New features included since 1.0.4 based on PLFED-87 :
    • If a Principal MappingProvider is configured, retrieves and inserts the Principal into the Subject
    • If a RoleGroup MappingProvider is configured, retrieves and inserts the user roles into the Subject
    • Roles can only be returned if they are included in the Security Token. Configure your STS to return roles through an AttributeProvider