Monday, September 28, 2015

Good Options for Oracle Datasource - JBoss Middleware

Good Options for Oracle Datasource - JBoss Middleware

Hi, i am back :)

I would like to demonstrate a sample configuration about Oracle Datasource. Open your domain.xml or standalone*.xml and fill these options below:

(Non-XA Datasource - ojdbc6)

<datasource jta="true" jndi-name="java:/jdbc/<your-jdbc-name>" pool-name="jdbc/<your-jdbc-pool-name>" enabled="true" use-ccm="false"
                            statistics-enabled="true">
                        <connection-url>jdbc:oracle:thin:@//localhost:1521/<your-service-name></connection-url>
                        <driver>oracle</driver>
                        <transaction-isolation>TRANSACTION_READ_COMMITTED</transaction-isolation>
                        <pool>
                            <min-pool-size>6</min-pool-size>
                            <max-pool-size>10</max-pool-size>
                            <prefill>true</prefill>
                            <flush-strategy>IdleConnections</flush-strategy>
                        </pool>
                        <security>
                            <user-name>xxxxx</user-name>
                            <password>yyyyy</password>
                        </security>

                        <validation>
                            <valid-connection-checker class-name="org.jboss.jca.adapters.jdbc.extensions.oracle.OracleValidConnectionChecker"/>
                            <background-validation>true</background-validation>
                            <background-validation-millis>60000</background-validation-millis>
                            <stale-connection-checker class-name="org.jboss.jca.adapters.jdbc.extensions.oracle.OracleStaleConnectionChecker"/>
                            <exception-sorter class-name="org.jboss.jca.adapters.jdbc.extensions.oracle.OracleExceptionSorter"/>
                        </validation>
                        <timeout>
                            <idle-timeout-minutes>1</idle-timeout-minutes>
                        </timeout>
                        <statement>
                            <prepared-statement-cache-size>100</prepared-statement-cache-size>
                            <share-prepared-statements>true</share-prepared-statements>
                        </statement>
                           
                    </datasource>

...

                    <drivers>
                        <driver name="oracle" module="oracle">
                            <driver-class>oracle.jdbc.driver.OracleDriver</driver-class>
                        </driver>
                        <driver name="xa-oracle" module="oracle">
                            <xa-datasource-class>oracle.jdbc.xa.client.OracleXADataSource</xa-datasource-class>
                        </driver>
                    </drivers>

To use a good configuration over datasources, you need to know about number of connections...So, how can i set the min and max pool ?

                            <min-pool-size>6</min-pool-size>
                            <max-pool-size>10</max-pool-size>


Min-pool-size for a large number of invocations from your applications this option must be set with 60%-70% of the max-pool-size value.

Timeouts and Transaction Isolation are an important configurations too...for example, if you are trying to access data just to show informations in a report, without transaction, please try to use this:

  <transaction-isolation>TRANSACTION_SERIALIZABLE</transaction-isolation>

Thanks a lot and see you on the next time...

Thursday, April 30, 2015

How To Improve JBoss AS 7 / JBoss EAP 6.x Performance

Hi all, let's talk about performance over JBoss App Server...for example, JBoss EAP 6.3

I will give some clues about JBoss Performance...how to improve the container

- Datasources

Try to use prefill...

<datasource jta="true" jndi-name="java:/jdbc/<xpto>" enabled="true" use-ccm="false"> pool-name="<pool>"

<transaction-isolation>TRANSACTION_READ_COMMITTED</transaction-isolation> <!-- Serializable can be a good choice, depending reads of course -->
<pool>
<min-pool-size>8</min-pool-size>
<max-pool-size>32</max-pool-size>
<prefill>true</prefill>
</pool>
...
<!-- mysql for example try to use batch statements -->
<connection-property name="rewriteBatchedStatements">true</connection-property>
<connection-property name="maintainTimeStats">false</connection-property>

</datasource>


- EJB

<subsystem xmlns="urn:jboss:domain:ejb3:1.4">
    ...
<pools>
<bean-instance-pools>

<strict-max-pool name="slsb-strict-max-pool" max-pool-size="600"
instance-acquisition-timeout="1" instance-acquisition-timeout-unit="SECONDS"/>

<strict-max-pool name="mdb-strict-max-pool" max-pool-size="150"
instance-acquisition-timeout="1" instance-acquisition-timeout-unit="SECONDS"/>

</bean-instance-pools>
</pools>
   ...
<remote connector-ref="remoting-connector" thread-pool-name="default">
  <channel-creation-options>
  <option name="WORKER_READ_THREADS" value="2" type="xnio"/>
  <option name="WORKER_WRITE_THREADS" value="2" type="xnio"/>
  <option name="MAX_INBOUND_MESSAGES" value="150" type="remoting"/>
   <option name="MAX_OUTBOUND_MESSAGES" value="150" type="remoting"/>
   </channel-creation-options>
</remote>

  <thread-pools>
           <thread-pool name="default">
           <max-threads count="150"/>
           <keepalive-time time="60" unit="minutes"/>

      </thread-pool>
  </thread-pools>

  <in-vm-remote-interface-invocation pass-by-value="false"/>
</subsystem>


- Infinispan and Hibernate Cache (LIRS instead of LRU)

<subsystem xmlns="urn:jboss:domain:infinispan:1.5">
    . . .
   <cache-container name="hibernate" module="org.jboss.as.jpa.hibernate:4" default-cache="local-query">

   <transport lock-timeout="60000"/>
   <local-cache name="local-query">
      <transaction mode="NONE"/>
      <eviction strategy="LIRS" max-entries="150"/>
      <expiration max-idle="200000" lifespan="200000"/>
   </local-cache>

   <local-cache name="entity">
      <transaction mode="NON_XA"/>
      <eviction strategy="LIRS" max-entries="17030000"/>
      <expiration max-idle="1200000" lifespan="1200000"/>
   </local-cache>
      ...
 </cache-container>
      ...
</subsystem>


- Threads


<subsystem xmlns="urn:jboss:domain:threads:1.1">
     <unbounded-queue-thread-pool name="thread-http">
        <max-threads count="300"/>
        <keepalive-time time="60" unit="minutes"/>
     </unbounded-queue-thread-pool>

     <unbounded-queue-thread-pool name="thread-ajp">
         <max-threads count="300"/>
         <keepalive-time time="60" unit="minutes"/>
      </unbounded-queue-thread-pool>
</subsystem>


- Web

<subsystem xmlns="urn:jboss:domain:web:2.1" default-virtual-server="default-host" native="true" >

<connector name="http" protocol="HTTP/1.1" scheme="http" socket-
binding="http" enable-lookups="false" executor="thread-http" max-connections="400" />

<connector name="ajp" protocol="AJP/1.3" scheme="http" socket-binding="ajp" enable-lookups="false" executor="thread-ajp" max-connections="400" />

<virtual-server name="default-host" enable-welcome-root="true">
     <alias name="localhost"/>
     <alias name="example.com"/>
 </virtual-server>

</subsystem>


- Huge Pages and JVM Heap Size (just an example about 6GB)

/etc/sysctl.conf → vm.nr_hugepages = n (use /proc/meminfo → large page size). Ex: n = 10

/etc/sysctl.conf → kernel.shmmax = n ( maybe 3 times O. S Memory )
Try to avoid “error-no=22” when putting low values

/etc/sysctl.conf → vm.huge_tlb_shm_group = gid (gid groups). Ex: jboss groups


How to aply: sysctl -p

Example of values...
3072 large pages * 2048 KB page size – 3072 * 2048 = 6291456 (6GB / 2MB=3072)

Try to use the linux command
      "ulimit -a" or
      "ulimit -n"

So, check values for configurating and improve some properties to "unlimited" (see possibilities, of course).
Sample: how to see open files -> "lsof | grep jboss | wc -l"


So, use -XX:+UseLargePages for JVM Properties...as described before.

Another choose is using CMS collectors or default jvm values as:

<!-- JVM by Group Server -->
<jvm name="default">
<heap size="6GB" max-size="6GB"/>
<permgen size="256m" max-size="512m"/>
<jvm-options>
<option value="-XX:+DoEscapeAnalysis" />
<option value="-XX:+UseCompressedOops" />
<option value="-XX:+UseConcMarkSweepGC" />
<!-- option value="-XX:+HeapDumpOnOutOfMemoryError"/-->
</jvm-options>
</jvm>

See more about NUMA Architecture (non-uniform memory architecture - RHEL 6.x for example) to improve jboss process. See links about it.

NUMA
https://access.redhat.com/solutions/700683
https://access.redhat.com/solutions/48756

Huge Pages
https://access.redhat.com/solutions/317593
https://access.redhat.com/solutions/659103
https://access.redhat.com/solutions/69306 (HugePages Oracle)

JVM Options
https://access.redhat.com/solutions/629563
https://access.redhat.com/labsinfo/jvmconfig

Thanks a lot and see you on the next time...

Wednesday, March 11, 2015

How to implement IDP (SSO) with Picketlink 2.5 using JSF login page

Hi All,
Thanks for reading my articles...

This article is a part of implementation about Picketlink SSO based on my last post:

 "How to Implement SSO using Picketlink 2.5, SEAM 2.x and JBoss AS/Wildfly" (2015-03-11)

You need to implement the code described in the link above to create the project...

So let's do it:

Take a look over idp implementation on my last article...

The login.jsp will be replaced by login.xhtml and some revisions will be necessary...

pom.xml

        <dependency>
             <groupId>org.jboss.spec.javax.faces</groupId>
             <artifactId>jboss-jsf-api_2.1_spec</artifactId>
             <scope>provided</scope>
        </dependency>

 

1 - login.xhtml

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
 

<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:f="http://java.sun.com/jsf/core"
      xmlns:ui="http://java.sun.com/jsf/facelets">

<h:head>
    <title>
        <ui:insert name="title">IDP Picketlink SAML Identity Provider JSF 2.0</ui:insert>
    </title>
</h:head>

<body>
    <form id="login_form" name="login_form"
           action="j_security_check" method="post"
           enctype="application/x-www-form-urlencoded">

            <p>
                <b>IDP - JSF Login - PicketLink 2.5</b>
            </p>
            <p>Please login to proceed...</p>
          
            <div style="margin-left: 15px;">
                <p>          
                    <h:outputLabel for="j_username" value="Username"></h:outputLabel>
                    <br />
                    <h:inputText id="j_username" size="20" />
                </p>
                <p>
                    <h:outputLabel for="j_password" value="Password"></h:outputLabel>
                    <br />
                    <h:inputSecret id="j_password" size="20"/>
                </p>

                   <input type="submit" value="login" />
            </div>
    </form>

    </body>
</html>
 

2 - /WEB-INF/web.xml
...

    <servlet>
        <servlet-name>Faces Servlet</servlet-name>
        <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>Faces Servlet</servlet-name>
        <url-pattern>*.xhtml</url-pattern>
    </servlet-mapping>

 ...

    <login-config>
        <auth-method>FORM</auth-method>
        <realm-name>PicketLink IDP JSF Application</realm-name>
        <form-login-config>
            <form-login-page>/login.xhtml</form-login-page>
            <form-error-page>/login.xhtml</form-error-page>
        </form-login-config>
    </login-config>



 3 - /WEB-INF/picketlink.xml

 <PicketLink xmlns="urn:picketlink:identity-federation:config:2.1">
    <PicketLinkIDP xmlns="urn:picketlink:identity-federation:config:2.1"
        ServerEnvironment="tomcat" BindingType="REDIRECT" RelayState="someURL">
  
    <IdentityURL>${idp.url::http://localhost:9080/idp-jsf/}</IdentityURL>
        <Trust>
            <Domains>localhost</Domains>
        </Trust>
    </PicketLinkIDP>
  
    <Handlers xmlns="urn:picketlink:identity-federation:handler:config:2.1">
        <Handler
            class="org.picketlink.identity.federation.web.handlers.saml2.SAML2IssuerTrustHandler" />
        <Handler
            class="org.picketlink.identity.federation.web.handlers.saml2.SAML2LogOutHandler" />

        <Handler class="org.picketlink.identity.federation.web.handlers.saml2.SAML2AuthenticationHandler">
                    <Option Key="CLOCK_SKEW_MILIS" Value="30000"/>
        </Handler>  
      
      
        <Handler
            class="org.picketlink.identity.federation.web.handlers.saml2.RolesGenerationHandler" />
    </Handlers>
  
    <PicketLinkSTS xmlns="urn:picketlink:identity-federation:config:2.1" TokenTimeout="5000" ClockSkew="0">
        <TokenProviders>
            <TokenProvider
                ProviderClass="org.picketlink.identity.federation.core.saml.v1.providers.SAML11AssertionTokenProvider"
                TokenType="urn:oasis:names:tc:SAML:1.0:assertion"
                TokenElement="Assertion" TokenElementNS="urn:oasis:names:tc:SAML:1.0:assertion" />
            <TokenProvider
                ProviderClass="org.picketlink.identity.federation.core.saml.v2.providers.SAML20AssertionTokenProvider"
                TokenType="urn:oasis:names:tc:SAML:2.0:assertion"
                TokenElement="Assertion" TokenElementNS="urn:oasis:names:tc:SAML:2.0:assertion" />
        </TokenProviders>
    </PicketLinkSTS>
</PicketLink>


 OR just replace the ${idp.url} property described on my last article inside picketlink.xml 


  4 - /WEB-INF/jboss-web.xml

<jboss-web>
  <context-root>idp-jsf</context-root>
  <security-domain>idp</security-domain>
  <valve>
     <class-name>org.picketlink.identity.federation.bindings.tomcat.idp.IDPWebBrowserSSOValve</class-name>
   </valve>
</jboss-web>
 

 That's it...



How to Implement SSO using Picketlink 2.5, SEAM 2.x and JBoss AS/Wildfly

Hi Everyone,
Thanks for reading my first article...
I will demonstrate how to write a code that implements SAML Authentication with Picketlink and how to use the SEAM framework events to get attributes propagated by IDP. 
First of all, take a look at links for more informations about Picketlink:

     https://docs.jboss.org/author/display/PLINK/PicketLink+Quickstarts
     https://github.com/picketlink
     https://github.com/jboss-developer/jboss-picketlink-quickstarts

So, let's do it:

1 - IDP

1.a. pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>br.fred.pickelink.saml.sample</groupId>
    <artifactId>saml-idp</artifactId>
    <version>1.0.0-SNAPSHOT</version>
    <packaging>war</packaging>
    <name>saml-idp</name>
    <description>IDP: Web Project (war)</description>

    <!--
    <repositories>
        <repository>
            <id>jboss-picketlink</id>
            <url>http://....</url>
            <releases>
                <enabled>true</enabled>
            </releases>
            <snapshots>
                <enabled>false</enabled>
            </snapshots>
        </repository>
    </repositories>
    -->

    <properties>
        <version.picketlink>2.5.3.Final</version.picketlink>
        <version.picketlink.javaee.bom>2.5.3.Final</version.picketlink.javaee.bom>

        <version.junit>4.8.2</version.junit>

        <!-- Indicate the defaut server/binding version to package the applications -->
        <binding>jboss</binding>
        <binding-version>as7</binding-version>
      
        <project.build.sourceEncoding>ISO-8859-1</project.build.sourceEncoding>
        <version.compiler.plugin>2.3.1</version.compiler.plugin>
      
        <maven.compiler.target>1.7</maven.compiler.target>
        <maven.compiler.source>1.7</maven.compiler.source>
       
        <version.org.jboss.bom>1.0.7.Final</version.org.jboss.bom>
        <version.org.jboss.as.plugins.maven.plugin>7.3.Final</version.org.jboss.as.plugins.maven.plugin>

    </properties>

    <dependencyManagement>
          <dependencies>
          <dependency>
          <groupId>org.jboss.bom</groupId>
          <artifactId>jboss-javaee-6.0-with-hibernate3</artifactId>
          <version>${version.org.jboss.bom}</version>
          <type>pom</type>
          <scope>import</scope>
          </dependency>
      </dependencies>
       </dependencyManagement>
   
    <dependencies>
        <dependency>
            <groupId>org.picketlink.distribution</groupId>
            <artifactId>picketlink-jbas7</artifactId>
            <version>2.5.3.Final</version>
            <scope>provided</scope>
        </dependency>

        <dependency>
          <groupId>org.picketlink</groupId>
          <artifactId>picketlink-api</artifactId>
          <version>2.5.3.Final</version>
          <scope>provided</scope>
        </dependency>
   
        <dependency>
          <groupId>org.picketlink</groupId>
          <artifactId>picketlink-impl</artifactId>
          <version>2.5.3.Final</version>
          <scope>provided</scope>
        </dependency>

        <dependency>
            <groupId>org.picketlink</groupId>
            <artifactId>picketlink-federation</artifactId>
            <version>2.5.3.Final</version>
            <scope>provided</scope>
        </dependency>

        <dependency>
          <groupId>org.jboss.spec.javax.faces</groupId>
          <artifactId>jboss-jsf-api_2.1_spec</artifactId>
          <scope>provided</scope>
        </dependency>

        <dependency>
            <groupId>org.jboss.web</groupId>
            <artifactId>jbossweb</artifactId>
            <version>7.2.2.Final</version>
            <scope>provided</scope>
        </dependency>

        <dependency>
        <groupId>org.jboss.spec.javax.ejb</groupId>
        <artifactId>jboss-ejb-api_3.1_spec</artifactId>
        <scope>provided</scope>
        </dependency>
 

        <dependency>
        <groupId>org.hibernate.javax.persistence</groupId>
        <artifactId>hibernate-jpa-2.0-api</artifactId>
        <scope>provided</scope>
        </dependency>
 

        <dependency>
        <groupId>org.jboss.spec.javax.ws.rs</groupId>
        <artifactId>jboss-jaxrs-api_1.1_spec</artifactId>
        <scope>provided</scope>
        </dependency>
        <dependency>
        <groupId>javax.enterprise</groupId>
        <artifactId>cdi-api</artifactId>
        <scope>provided</scope>
        </dependency>
 

        <dependency>
        <groupId>org.jboss.spec.javax.security.jacc</groupId>
        <artifactId>jboss-jacc-api_1.4_spec</artifactId>
        <scope>provided</scope>
        </dependency>
 

        <dependency>
        <groupId>org.jboss.spec.javax.annotation</groupId>
        <artifactId>jboss-annotations-api_1.1_spec</artifactId>
        <scope>provided</scope>
        </dependency>
 

        <dependency>
        <groupId>org.jboss.spec.javax.servlet</groupId>
        <artifactId>jboss-servlet-api_3.0_spec</artifactId>
        <scope>provided</scope>
        </dependency>

      </dependencies>

    <build>
        <finalName>${project.artifactId}</finalName>
        <plugins>
            <plugin>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>${version.compiler.plugin}</version>
                <configuration>
                    <source>${maven.compiler.source}</source>
                    <target>${maven.compiler.target}</target>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>
 


1.b. Security IDP Domain
Now, we are going to define the security domain/constraints for JBoss standalone.xml or domain.xml (Security Subsystem)

 <security-domain name="idp" cache-type="default">
        <authentication>
            <login-module code="Remoting" flag="optional">
                <module-option name="password-stacking" value="useFirstPass"/>
            </login-module>
            <login-module code="RealmDirect" flag="required">
                <module-option name="password-stacking" value="useFirstPass"/>
            </login-module>
        </authentication>
 </security-domain>


Note: $JBOSS_HOME/bin/add_user.sh for adding users (user-properties file)


1.c. web.xml

<?xml version="1.0"?>
<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">

    <display-name>IDP</display-name>

    <description>
        IDP Web Application for the PicketLink project
    </description>

    <listener>
        <listener-class>org.picketlink.identity.federation.web.listeners.IDPHttpSessionListener</listener-class>
    </listener>

    <security-constraint>
        <web-resource-collection>
            <web-resource-name>Images</web-resource-name>
            <url-pattern>/images/*</url-pattern>
        </web-resource-collection>
        <web-resource-collection>
            <web-resource-name>CSS</web-resource-name>
            <url-pattern>/css/*</url-pattern>
        </web-resource-collection>
    </security-constraint>

    <security-constraint>
        <web-resource-collection>
            <web-resource-name>Manager command</web-resource-name>
            <url-pattern>/*</url-pattern>
        </web-resource-collection>
        <auth-constraint>
            <role-name>*</role-name>
        </auth-constraint>
    </security-constraint>

    <login-config>
        <auth-method>FORM</auth-method>
        <realm-name>PicketLink IDP Application</realm-name>
        <form-login-config>
            <form-login-page>/jsp/login.jsp</form-login-page>
            <form-error-page>/jsp/login.jsp</form-error-page>
        </form-login-config>
    </login-config>

    <security-role>
        <role-name>*</role-name>
    </security-role>
</web-app>
 

1.d. login.jsp

<html>
<head>
<title>IDP Login</title>
<link rel="StyleSheet" href="css/idp.css" type="text/css">
</head>

<body>
    <div  style="margin-bottom: 180px; border: 1px solid #000000; width: 380px; height: 250px; background-color: #F8F8F8; align: center;">
        <form id="login_form" name="login_form" method="post"
            action="j_security_check" enctype="application/x-www-form-urlencoded">
            <center>
                <p>
                    Welcome <b>IDP</b>
                </p>
                <p>Please, login...</p>
            </center>

            <div style="margin-left: 20px;">
                <p>
                    <label for="username">Username</label><br /> <input id="username"
                        type="text" name="j_username" size="20" />
                </p>
                <p>
                    <label for="password">Password</label><br /> <input id="password"
                        type="password" name="j_password" value="" size="20" />
                </p>

                <p>
                      <select id="selecionar" name="selecionar" size="1" style="display: initial; width:180px;">
                        <option value="1">param1</option>
                        <option value="2">param2</option>
                    </select>
               </p>

                <center>
                    <input id="submit" type="submit" name="submit" value="Login"
                        class="buttonmed" />
                </center>
            </div>
          
        </form>
    </div>
</body>
</html>



1.e. /hosted/index.jsp 
After authentication process (hosted page - welcome)...


<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">

<html>
<head>
    <title>Welcome to IDP</title>
</head>

<body>
    <p>
        IDP Home <b>Auth OK !</b>
    </p>

    <div>
        <p>
            <ul>
                <li>Go to...
                    <a href="xxxx">
                        Send
                    </a>
                </li>
            </ul>
        </p>
    </div>
</body>
</html>
 



1.e. /WEB-INF/jboss-web.xml
Now, I will demostrate how to configure picketlink (setup)...

<jboss-web>
    <context-root>idp</context-root>
    <!-- from security subsystem -->

    <security-domain>idp</security-domain>
    <valve>
        <!-- class-name>org.picketlink.identity.federation.bindings.tomcat.idp.IDPWebBrowserSSOValve</class-name-->

        <!-- My SP Valve class to control parameters ... -->
        <class-name>br.fred.picketlink.saml.sample.IDPSSOValve</class-name>
    </valve>
</jboss-web> 




1.f. /WEB-INF/picketlink.xml
Picketlink (setup)...

<PicketLink xmlns="urn:picketlink:identity-federation:config:2.1">
    <PicketLinkIDP xmlns="urn:picketlink:identity-federation:config:2.1"   AttributeManager="br.fred.picketlink.saml.sample.EngineAttributeManager">

        <IdentityURL>${idp.url::http://localhost:9080/idp/}</IdentityURL>
        <Trust>
            <Domains>locahost, localhost:9080</Domains>
        </Trust>
    </PicketLinkIDP>

    <PicketLinkSTS xmlns="urn:picketlink:identity-federation:config:1.0" TokenTimeout="30000" ClockSkew="0">
        <TokenProviders>
            <TokenProvider ProviderClass="org.picketlink.identity.federation.core.saml.v2.providers.SAML20AssertionTokenProvider"
                TokenType="urn:oasis:names:tc:SAML:2.0:assertion" TokenElement="Assertion"
                TokenElementNS="urn:oasis:names:tc:SAML:2.0:assertion" />
        </TokenProviders>
    </PicketLinkSTS>

    <Handlers xmlns="urn:picketlink:identity-federation:handler:config:2.1">
        <Handler class="org.picketlink.identity.federation.web.handlers.saml2.SAML2IssuerTrustHandler" />
        <Handler class="org.picketlink.identity.federation.web.handlers.saml2.SAML2LogOutHandler" />
        <Handler class="org.picketlink.identity.federation.web.handlers.saml2.SAML2AuthenticationHandler"/>

        <Handler class="org.picketlink.identity.federation.web.handlers.saml2.SAML2AttributeHandler">
            <Option Key="ATTRIBUTE_MANAGER" Value="br.fred.picketlink.saml.sample.EngineAttributeManager"/>
            <Option Key="ATTRIBUTE_KEYS" Value="selecionar" />
        </Handler>

        
         <!-- my specific handler -->
        <Handler class="br.fred.picketlink.saml.sample.IDPSAMLHandler"/>

        <Handler class="org.picketlink.identity.federation.web.handlers.saml2.RolesGenerationHandler" />
    </Handlers>

</PicketLink>




1.g. /WEB-INF/jboss-deployment-structure.xml
 Class loading...

<jboss-deployment-structure>
    <deployment>
        <exclusions>
        </exclusions>
   
        <dependencies>
            <module name="org.picketlink" />
            <module name="org.picketlink.config" />
            <module name="org.picketlink.common"/>
            <module name="org.picketlink.core"/>
            <module name="org.picketlink.core.api"/>
            <module name="org.picketlink.idm.api" />
            <module name="org.picketlink.federation" />
        </dependencies>
    </deployment>
</jboss-deployment-structure>



1.h. Attribute Manager Class
Class that is responsible for handling attributes. See picketlink.xml for class declaration...

 package br.fred.picketlink.saml.sample;

import java.security.Principal;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.security.jacc.PolicyContextException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import org.picketlink.identity.federation.core.interfaces.AttributeManager;
import org.picketlink.identity.federation.web.constants.GeneralConstants;

public class EngineAttributeManager implements AttributeManager {

    private static final String PARAM_SELECT = "selecionar";
    private static final Logger logger       = Logger.getLogger(EngineAttributeManager.class.getName());

    @Override
    public Map<String, Object> getAttributes(Principal userPrincipal, List<String> attributeKeys) {
        Map<String,Object> attributes = new HashMap<String, Object>();
        HttpServletRequest request    = null;

        try {
            request = (HttpServletRequest) javax.security.jacc.PolicyContext.getContext(
                    "javax.servlet.http.HttpServletRequest");

            HttpSession session = request.getSession();

            Object param = findAttributesSession(PARAM_SELECT, session);
            if (param == null) {
                param = findParametersRequest(PARAM_SELECT, request);
            }

            //  test !!!! please remove this line
            logger.info("Atributo contido nos parametros propagados ? " +
                    attributeKeys.contains(PARAM_SELECT));
          
               logger.info("Atributo definido pelo manager: " + PARAM_SELECT + " - valor: " + param);
               attributes.put(PARAM_SELECT, param);

        } catch (PolicyContextException e) {
            logger.log(Level.WARNING, "Error...", e);
        }

        logger.info("** ATTRIBUTES SIZE: " + attributes.size());
        return attributes;
    }

    @SuppressWarnings("unchecked")
    protected Object findAttributesSession(final String parameter, HttpSession session) {
        StringBuffer sb = new StringBuffer("\n\n ###############################################");

        Enumeration<String> enums = session.getAttributeNames();
        String keyn = null;
        while (enums.hasMoreElements()) {
            keyn = enums.nextElement();
            sb.append("\n Key: " + keyn + " - value: " + session.getAttribute(keyn));

            if (keyn.equalsIgnoreCase(parameter)) {
                  sb.append("\n Session Parameter found key: " + keyn + " - value: " + session.getAttribute(keyn));
                  sb.append("\n ###############################################");

                  logger.info(sb.toString());

               return session.getAttribute(keyn);
            }
        }

        Object customAttributes = session.getAttribute(GeneralConstants.ATTRIBUTES);
        if ( customAttributes != null ) {

           Map<String, Object> attributesMap = (Map<String, Object>) customAttributes;
         
           sb.append("\n\n IDP ATTRIBUTES (GeneralConstants.ATTRIBUTES): ");
         
           for ( String key : attributesMap.keySet() ) {

               Object attribute = attributesMap.get(key);

                  sb.append("\n Session Attribute Key: " + key + " - value: " + attribute);
        
                  if (key.equalsIgnoreCase(parameter)) {
                      sb.append("\n Session Attribute found key: " + key + " - value: " + attribute);
                   sb.append("\n ###############################################");
                   logger.info(sb.toString());

                   return attribute;
                  }
           }
        }

        sb.append("\n ###############################################");
        logger.info(sb.toString());

        return null;
    }

    protected Object findParametersRequest(final String parameter, HttpServletRequest request) {
        StringBuffer sb = new StringBuffer("\n\n ###############################################");

        Enumeration<String> enums = request.getParameterNames();
        String key = null;
        while (enums.hasMoreElements()) {
            key = enums.nextElement();
            sb.append("\n Request Parameter Key: " + key + " - value: " + request.getParameter(key));

            if (key.equalsIgnoreCase(parameter)) {
                sb.append("\n Request Parameter found key: " + key + " - value: " + request.getParameter(key));
                sb.append("\n ###############################################");
                logger.info(sb.toString());

                return request.getParameter(key);
            }
        }

       sb.append("\n ###############################################");
       logger.info(sb.toString());

       return null;
    }
}



1.i. IDP Handler Class 
After authentication, it will be possible handle saml informations...

package br.fred.picketlink.saml.sample;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import org.picketlink.common.exceptions.ProcessingException;
import org.picketlink.identity.federation.core.saml.v2.interfaces.SAML2HandlerRequest;
import org.picketlink.identity.federation.core.saml.v2.interfaces.SAML2HandlerResponse;
import org.picketlink.identity.federation.saml.v2.protocol.AuthnRequestType;
import org.picketlink.identity.federation.web.handlers.saml2.BaseSAML2Handler;

public class IDPSAMLHandler extends BaseSAML2Handler {

    @Override
    public void handleRequestType(SAML2HandlerRequest request,
            SAML2HandlerResponse response) throws ProcessingException {

        logger.info("IDP - handleRequestType");

        // protecao para o logout e fora do fluxo de sessao
        if (request.getSAML2Object() instanceof AuthnRequestType == false)
            return;

        if (response.getDestination() != null) {

               logger.info("who i am - url destination");
        }
    }
}


1.j. IDP Valve Class
To Handle parameters...

package br.fred.picketlink.saml.sample;

import java.io.IOException;
import java.util.logging.Logger;

import javax.servlet.ServletException;

import org.apache.catalina.connector.Request;
import org.apache.catalina.connector.Response;
import org.picketlink.identity.federation.bindings.tomcat.idp.IDPWebBrowserSSOValve;

public class IDPSSOValve extends IDPWebBrowserSSOValve {

    private static final String PARAM_SELECT = "selecionar";
    private static final Logger logger       = Logger.getLogger(IDPSSOValve.class.getName());

    @Override
    public void invoke(Request request, Response response) throws IOException, ServletException {
        logger.info("IDP Valve - inkoke");
       
        final String param = request.getParameter(PARAM_SELECT);
        if (param != null ) {
            logger.info("IDP Valve - inkoke - param: " + param);
            request.getSession().setAttribute(PARAM_SELECT, param);

            // now the engine manager take care of parameters...
        }
       
        super.invoke(request, response);
    }
}




1.k. That's it! IDP is working...
Deploy your IDP war file for JBoss AS 7 (EAP 6.3) or Wildfly




2 - SP (Service Provider)
An application that uses IDP for authentication...

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>br.fred.picketlink.saml.sample</groupId>
    <artifactId>saml-sp</artifactId>
    <version>1.0.0-SNAPSHOT</version>
    <packaging>war</packaging>
    <name>saml-sp</name>
    <description>SP: Projeto Service Provider (war)</description>

    <!-- <repositories> <repository> <id>jboss-picketlink</id> <url>http://....</url>
        <releases> <enabled>true</enabled> </releases> <snapshots> <enabled>false</enabled>
        </snapshots> </repository> </repositories> -->

    <properties>
        <version.picketlink>2.5.3.Final</version.picketlink>
        <version.picketlink.javaee.bom>2.5.3.Final</version.picketlink.javaee.bom>

        <version.junit>4.8.2</version.junit>

        <!-- Indicate the defaut server/binding version to package the applications -->
        <binding>jboss</binding>
        <binding-version>as7</binding-version>

        <project.build.sourceEncoding>ISO-8859-1</project.build.sourceEncoding>
        <version.compiler.plugin>2.3.1</version.compiler.plugin>

        <maven.compiler.target>1.7</maven.compiler.target>
        <maven.compiler.source>1.7</maven.compiler.source>

        <version.org.jboss.bom>1.0.7.Final</version.org.jboss.bom>
        <version.org.jboss.as.plugins.maven.plugin>7.3.Final</version.org.jboss.as.plugins.maven.plugin>
    </properties>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.jboss.bom</groupId>
                <artifactId>jboss-javaee-6.0-with-hibernate3</artifactId>
                <version>${version.org.jboss.bom}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <dependencies>

        <dependency>
            <groupId>org.picketlink.distribution</groupId>
            <artifactId>picketlink-jbas7</artifactId>
            <version>2.5.3.Final</version>
            <scope>provided</scope>
        </dependency>

        <dependency>
            <groupId>org.picketlink</groupId>
            <artifactId>picketlink-api</artifactId>
            <version>2.5.3.Final</version>
            <scope>provided</scope>
        </dependency>

        <dependency>
            <groupId>org.picketlink</groupId>
            <artifactId>picketlink-impl</artifactId>
            <version>2.5.3.Final</version>
            <scope>provided</scope>
        </dependency>

        <dependency>
            <groupId>org.picketlink</groupId>
            <artifactId>picketlink-federation</artifactId>
            <version>2.5.3.Final</version>
            <scope>provided</scope>
        </dependency>

        <dependency>
            <groupId>org.jboss.spec.javax.faces</groupId>
            <artifactId>jboss-jsf-api_2.1_spec</artifactId>
            <scope>provided</scope>
        </dependency>

        <dependency>
            <groupId>org.jboss.web</groupId>
            <artifactId>jbossweb</artifactId>
            <version>7.2.2.Final</version>
            <scope>provided</scope>
        </dependency>

        <dependency>
            <groupId>org.jboss.spec.javax.ejb</groupId>
            <artifactId>jboss-ejb-api_3.1_spec</artifactId>
            <scope>provided</scope>
        </dependency>
       
        <dependency>
            <groupId>org.hibernate.javax.persistence</groupId>
            <artifactId>hibernate-jpa-2.0-api</artifactId>
            <scope>provided</scope>
        </dependency>
       
        <dependency>
            <groupId>org.jboss.spec.javax.ws.rs</groupId>
            <artifactId>jboss-jaxrs-api_1.1_spec</artifactId>
            <scope>provided</scope>
        </dependency>
       
        <dependency>
            <groupId>javax.enterprise</groupId>
            <artifactId>cdi-api</artifactId>
            <scope>provided</scope>
        </dependency>
       
        <dependency>
            <groupId>org.jboss.spec.javax.security.jacc</groupId>
            <artifactId>jboss-jacc-api_1.4_spec</artifactId>
            <scope>provided</scope>
        </dependency>
       
        <dependency>
            <groupId>org.jboss.spec.javax.annotation</groupId>
            <artifactId>jboss-annotations-api_1.1_spec</artifactId>
            <scope>provided</scope>
        </dependency>
       
        <dependency>
            <groupId>org.jboss.spec.javax.servlet</groupId>
            <artifactId>jboss-servlet-api_3.0_spec</artifactId>
            <scope>provided</scope>
        </dependency>
       
        <dependency>
            <groupId>org.jboss.seam</groupId>
            <artifactId>jboss-seam</artifactId>
            <version>2.2.2.Final</version>
            <scope>compile</scope>
        </dependency>
    </dependencies>

    <build>
        <finalName>${project.artifactId}</finalName>
        <plugins>
            <plugin>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>${version.compiler.plugin}</version>
                <configuration>
                    <source>${maven.compiler.source}</source>
                    <target>${maven.compiler.target}</target>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>



2.a. Security Domain
It is necessary to define security domain to control SP Authentication over Picketlink SAML protocol


    <security-domain name="sp" cache-type="default">
        <authentication>
            <login-module code="org.picketlink.identity.federation.bindings.jboss.auth.SAML2LoginModule" flag="required"/>
        </authentication>
    </security-domain>




2.b. /WEB-INF/web.xml

<?xml version="1.0"?>
<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">
    <display-name>PicketLink SP Application</display-name>
    <description>
        SP Teste Application
    </description>

    <!-- Define a Security Constraint on this Application -->
    <security-constraint>
        <web-resource-collection>
            <web-resource-name>SP Application</web-resource-name>
            <url-pattern>/*</url-pattern>
        </web-resource-collection>
        <auth-constraint>
            <role-name>*</role-name>
        </auth-constraint>
    </security-constraint>

    <!-- Define a security constraint that gives unlimted access to freezone -->
    <security-constraint>
        <web-resource-collection>
            <web-resource-name>images</web-resource-name>
            <url-pattern>/images/*</url-pattern>
        </web-resource-collection>
        <web-resource-collection>
            <web-resource-name>css</web-resource-name>
            <url-pattern>/css/*</url-pattern>
        </web-resource-collection>
    </security-constraint>

    <!-- Define the Login Configuration for this Application -->
    <login-config>
        <auth-method>FORM</auth-method>
        <realm-name>SP Application</realm-name>
        <form-login-config>
            <form-login-page>/jsp/login.jsp</form-login-page>
            <form-error-page>/jsp/login.jsp</form-error-page>
        </form-login-config>
    </login-config>

    <!-- Security roles referenced by this web application -->
    <security-role>
        <description>
            The role that is required to log in to the SP Application
        </description>
        <role-name>*</role-name>
    </security-role>
</web-app>
 

2.c. /WEB-INF/picketlink.xml
Picketlink setup for SP...

<PicketLink xmlns="urn:picketlink:identity-federation:config:2.1">
    <PicketLinkSP xmlns="urn:picketlink:identity-federation:config:2.1"
        ServerEnvironment="tomcat" BindingType="REDIRECT" RelayState="someURL">
        <IdentityURL>${idp.url::http://localhost:9080/idp/}</IdentityURL>
        <ServiceURL>${sp.url::http://localhost:9080/sp/}</ServiceURL>
        <Trust>
            <Domains>localhost</Domains>
        </Trust>
    </PicketLinkSP>

    <Handlers xmlns="urn:picketlink:identity-federation:handler:config:2.1">
        <Handler class="org.picketlink.identity.federation.web.handlers.saml2.SAML2LogOutHandler" />
        <!-- Handler class="org.picketlink.identity.federation.web.handlers.saml2.SAML2AuthenticationHandler">
            <Option Key="CLOCK_SKEW_MILIS" Value="30000"/>
        </Handler-->

        <!-- my specific authentication handler -->
        <Handler class="br.fred.picketlink.saml.sample.SPSamlDynamicUrlAuthenticationHandler">
            <Option Key="CLOCK_SKEW_MILIS" Value="30000"/>
        </Handler>
        <Handler class="org.picketlink.identity.federation.web.handlers.saml2.RolesGenerationHandler" />
    </Handlers>
</PicketLink>




2.d. /WEB-INF/jboss-web.xml
Valve definition to SP...

<?xml version="1.0" encoding="UTF-8"?>
<jboss-web>
    <security-domain>sp</security-domain>
    <context-root>sp</context-root>
    <valve>
        <class-name>org.picketlink.identity.federation.bindings.tomcat.sp.ServiceProviderAuthenticator
        </class-name>
    </valve>
</jboss-web>


2.e. index.jsp
Home page after login...
 
<div align="center">
<h1>SP Saml Dashboard</h1>
<br/>
Welcome <b> <%= request.getUserPrincipal().getName()%> </b>.
<br/>
<a href="<%= request.getContextPath() %>/?GLO=true">LogOut</a>
</div>



2.f. Authentication  Handler Class
This is the handler class for authentication control between IDP and SP. I use this class to propagate the same url destination ip or hostname (dns)...

package br.fred.picketlink.saml.sample;

import static org.picketlink.common.util.StringUtil.isNotNull;

import java.net.URI;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import org.jboss.security.audit.AuditLevel;
import org.picketlink.common.constants.GeneralConstants;
import org.picketlink.common.constants.JBossSAMLURIConstants;
import org.picketlink.common.constants.SAMLAuthenticationContextClass;
import org.picketlink.common.exceptions.ProcessingException;
import org.picketlink.common.util.StringUtil;
import org.picketlink.config.federation.SPType;
import org.picketlink.identity.federation.api.saml.v2.request.SAML2Request;
import org.picketlink.identity.federation.core.audit.PicketLinkAuditEvent;
import org.picketlink.identity.federation.core.audit.PicketLinkAuditEventType;
import org.picketlink.identity.federation.core.audit.PicketLinkAuditHelper;
import org.picketlink.identity.federation.core.saml.v2.common.IDGenerator;
import org.picketlink.identity.federation.core.saml.v2.interfaces.SAML2Handler;
import org.picketlink.identity.federation.core.saml.v2.interfaces.SAML2HandlerRequest;
import org.picketlink.identity.federation.core.saml.v2.interfaces.SAML2HandlerResponse;
import org.picketlink.identity.federation.core.saml.v2.interfaces.SAML2HandlerRequest.GENERATE_REQUEST_TYPE;
import org.picketlink.identity.federation.saml.v2.protocol.AuthnContextComparisonType;
import org.picketlink.identity.federation.saml.v2.protocol.AuthnRequestType;
import org.picketlink.identity.federation.saml.v2.protocol.RequestedAuthnContextType;
import org.picketlink.identity.federation.web.core.HTTPContext;
import org.picketlink.identity.federation.web.handlers.saml2.SAML2AuthenticationHandler;

/**
 *
 * @author Frederico

 *
 * @See:
 *     https://github.com/pedroigor/picketlink-quickstarts/blob/master/picketlink-federation-saml-dynamic-idp-resolution/service-provider/src/main/java/org/picketlink/quickstarts/federation/saml/DynamicIdPSAML2AuthenticationHandler.java
 *  https://developer.jboss.org/thread/200615
 */
public class SPSamlDynamicUrlAuthenticationHandler extends SAML2AuthenticationHandler {

    private final SAMLSPAuthenticationHandler sp = new SAMLSPAuthenticationHandler();

/*
    public void handleRequestType(SAML2HandlerRequest request, SAML2HandlerResponse response) throws ProcessingException {
        super.handleRequestType(request, response);

        if (getType() != HANDLER_TYPE.IDP) {
            sp.handleRequestType(request, response);
        }
    }

    @Override
    public void handleStatusResponseType(SAML2HandlerRequest request, SAML2HandlerResponse response) throws ProcessingException {
        super.handleStatusResponseType(request, response);

        if (getType() != HANDLER_TYPE.IDP) {
            sp.handleStatusResponseType(request, response);
        }
    }
*/
    @Override
    public void generateSAMLRequest(SAML2HandlerRequest request, SAML2HandlerResponse response) throws ProcessingException {
        if (GENERATE_REQUEST_TYPE.AUTH != request.getTypeOfRequestToBeGenerated())
            return;

        super.generateSAMLRequest(request, response);

        if (getType() != HANDLER_TYPE.IDP) {
           
            logger.info("BEGIN - SP.generateSAMLRequest");
           
            sp.generateSAMLRequest(request, response);
            response.setSendRequest(true);

            logger.info("END - SP.generateSAMLRequest - setSendRequest TRUE");
        }
    }

    private class SAMLSPAuthenticationHandler {

        public void generateSAMLRequest(SAML2HandlerRequest request, SAML2HandlerResponse response) throws ProcessingException {
            String issuerValue = request.getIssuer().getValue();
            SAML2Request samlRequest = new SAML2Request();
            String id = IDGenerator.create("ID_");

            /* original...
            String assertionConsumerURL = (String) handlerConfig.getParameter(SAML2Handler.ASSERTION_CONSUMER_URL);
            if (StringUtil.isNullOrEmpty(assertionConsumerURL)) {
                assertionConsumerURL = issuerValue;
            }
            */
            // issue solved...
            HTTPContext httpContext = (HTTPContext) request.getContext();
            String assertionConsumerURL = httpContext.getRequest().getRequestURL().toString();

            if (StringUtil.isNullOrEmpty(assertionConsumerURL)) {
                assertionConsumerURL = (String) handlerConfig.getParameter(SAML2Handler.ASSERTION_CONSUMER_URL);
            }

            if (StringUtil.isNullOrEmpty(assertionConsumerURL)) {
                assertionConsumerURL = issuerValue;
            }
            logger.info("** SP-generateSAMLRequest - assertionConsumerURL: " + assertionConsumerURL);
            defineUrlDestinationSession(assertionConsumerURL, request);
            //----------------------

            // Check if there is a nameid policy
            String nameIDFormat = (String) handlerConfig.getParameter(GeneralConstants.NAMEID_FORMAT);
            if (isNotNull(nameIDFormat)) {
                samlRequest.setNameIDFormat(nameIDFormat);
            }
            try {
                AuthnRequestType authn = samlRequest.createAuthnRequestType(
                        id, assertionConsumerURL, response.getDestination(), issuerValue);

                createRequestedAuthnContext(authn);

                String bindingType = getSPConfiguration().getBindingType();
                boolean isIdpUsesPostBinding = getSPConfiguration().isIdpUsesPostBinding();

                if (bindingType != null) {
                    if (bindingType.equals("POST") || isIdpUsesPostBinding) {
                        authn.setProtocolBinding(URI.create(JBossSAMLURIConstants.SAML_HTTP_POST_BINDING.get()));
                    } else if (bindingType.equals("REDIRECT")) {
                        authn.setProtocolBinding(URI.create(JBossSAMLURIConstants.SAML_HTTP_REDIRECT_BINDING.get()));
                    } else {
                        throw logger.samlInvalidProtocolBinding();
                    }
                }

                response.setResultingDocument(samlRequest.convert(authn));
                response.setSendRequest(true);

                Map<String, Object> requestOptions = request.getOptions();
                PicketLinkAuditHelper auditHelper = (PicketLinkAuditHelper) requestOptions.get(GeneralConstants.AUDIT_HELPER);
                if (auditHelper != null) {
                    PicketLinkAuditEvent auditEvent = new PicketLinkAuditEvent(AuditLevel.INFO);
                    auditEvent.setWhoIsAuditing((String) requestOptions.get(GeneralConstants.CONTEXT_PATH));
                    auditEvent.setType(PicketLinkAuditEventType.CREATED_ASSERTION);
                    auditEvent.setAssertionID(id);
                    auditHelper.audit(auditEvent);
                }

                // Save AuthnRequest ID into sharedState, so that we can later process it by another handler
                request.addOption(GeneralConstants.AUTH_REQUEST_ID, id);
            } catch (Exception e) {
                throw logger.processingError(e);
            }
        }

        private void defineUrlDestinationSession(String urlDest, SAML2HandlerRequest request) {
            try {
                final String SP_DESTINATION_URL  = "sp_url_destination_url";
                HttpSession session = getHttpSession(request);

                // workaround!!!
                if (session == null) {
                    HttpServletRequest req =
                            (HttpServletRequest) javax.security.jacc.PolicyContext.getContext(
                            "javax.servlet.http.HttpServletRequest");

                    session = req.getSession(false);
                }
           
                session.setAttribute(
                    SP_DESTINATION_URL, urlDest);

            } catch (Exception ex) {
                throw new RuntimeException(ex);
            }
        }


        private SPType getSPConfiguration() {
            SPType spConfiguration = (SPType)     handlerChainConfig.getParameter(GeneralConstants.CONFIGURATION);

            if (spConfiguration == null) {
                throw logger.samlHandlerServiceProviderConfigNotFound();
            }

            return spConfiguration;
        }

        private void createRequestedAuthnContext(final AuthnRequestType authn) {
            String authnContextClasses = (String) handlerConfig.getParameter(GeneralConstants.AUTHN_CONTEXT_CLASSES);

            if (isNotNull(authnContextClasses)) {
                RequestedAuthnContextType requestAuthnContext = new RequestedAuthnContextType();

                for (String classFqn : authnContextClasses.split(",")) {
                    SAMLAuthenticationContextClass standardClass = SAMLAuthenticationContextClass.forAlias(classFqn);

                    if (standardClass != null) {
                        classFqn = standardClass.getFqn();
                    }

                    requestAuthnContext.addAuthnContextClassRef(classFqn);
                }

                if (!requestAuthnContext.getAuthnContextClassRef().isEmpty()) {
                    String comparison = (String) handlerConfig.getParameter(GeneralConstants.REQUESTED_AUTHN_CONTEXT_COMPARISON);

                    if (isNotNull(comparison)) {                     requestAuthnContext.setComparison(AuthnContextComparisonType.fromValue(comparison));
                    }
                    authn.setRequestedAuthnContext(requestAuthnContext);
                } else {
                    logger.debug("RequestedAuthnContext not set for AuthnRequest. No class was provided.");
                }
            }
        }
    }
}

 
2.g. Seam Observer Class
Now i will show how to get parameters and (user) principal after the authentication process, using the SEAM framework.
Imagine that you create a class XptoIdentity (that extends Identity - seam identity class).
For propagating the login information from IDP to the SP application is so simple:

- create a login method (override) on the XptoIdentity class.
- create an observer class as i posted below, and take care about security navigation (page.xml workflow)
 package br.fred.picketlink.saml.sample;

import java.io.IOException;
import java.io.Serializable;
import java.security.Principal;

import java.util.List;
import java.util.Map;

import javax.security.auth.login.LoginException;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.jboss.seam.Component;
import org.jboss.seam.ScopeType;
import org.jboss.seam.annotations.Logger;
import org.jboss.seam.annotations.Name;
import org.jboss.seam.annotations.Observer;
import org.jboss.seam.annotations.Scope;
import org.jboss.seam.log.Log;
import org.jboss.seam.security.Credentials;
import org.jboss.seam.security.Identity;

@Name("spAuthenticationFilter")
@Scope(ScopeType.SESSION)
public class SPSeamObserver implements Serializable {

    final static String SESSION_ATTRIBUTE_MAP = "SESSION_ATTRIBUTE_MAP";
    final static String PARAM_SELECT      = "selecionar";

    /**
     * serial
     */
    private static final long serialVersionUID = -7399762465116306988L;

    @Logger
    Log log;

    @Observer(Identity.EVENT_NOT_LOGGED_IN)
    public void notLoggedIn() {
        try {
            HttpServletRequest request = (HttpServletRequest) javax.security.jacc.PolicyContext.getContext(
                "javax.servlet.http.HttpServletRequest");
          
            processaSamlAuth(request, null, null);
          
        } catch (Exception ex) {
            ex.printStackTrace();
            throw new RuntimeException(ex);
        }

    }

    @Observer(Identity.EVENT_LOGGED_OUT)
    public void loggedOut() {
        try {
            HttpServletRequest request = (HttpServletRequest) javax.security.jacc.PolicyContext.getContext(
                "javax.servlet.http.HttpServletRequest");
          
            request.logout();

            Credentials credentials = (Credentials) Component.getInstance(org.jboss.seam.security.Credentials.class);
            credentials.clear();
            credentials.invalidate();
          
            org.jboss.seam.web.Session.instance().invalidate();

        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

    private void processaSamlAuth(HttpServletRequest request,
            HttpServletResponse response, FilterChain chain)
            throws IOException, ServletException {

        Principal userPrincipal = request.getUserPrincipal();
        if (userPrincipal != null && userPrincipal.getName() != null &&
                request.getSession().getAttribute("picketlink.principal") != null) {

            setupCredentialIdentity(request, userPrincipal);
        }
    }

    private void setupCredentialIdentity(final HttpServletRequest request,
            final Principal userPrincipal) throws ServletException, IOException {

        try {
            Identity identity = Identity.instance();

            identity.getCredentials().setUsername(userPrincipal.getName());

            setupParameter(identity, request);

        } catch (Exception ex) {
            throw new IOException(ex);
        }
    }

    @SuppressWarnings("unchecked")
    private void
setupParameter(Identity identity,
            HttpServletRequest request) {
        

        // map defined by IDP - Engine Manager...
        Map<String, List<Object>> sessionMap =
                (Map<String, List<Object>>) request.getSession(false).getAttribute(
                        SESSION_ATTRIBUTE_MAP);

        if (sessionMap != null && !sessionMap.isEmpty()) {

            if (sessionMap.get(PARAM_SELECT) != null) {
                Object param = sessionMap.get(PARAM_SELECT).get(0);
                request.getSession(false).setAttribute(PARAM_SELECT, param);
            }
        }
    }
}
 

2.h. SP Filter Class
If you just want to manager the parameters propagated by IDP, see the filter example below...

package br.fred.picketlink.saml.sample;

import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.logging.Logger;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;

@WebFilter("/*")
public class SPSSOFilter implements Filter {
   
    Logger logger = Logger.getLogger(SPSSOFilter.class.getName());

    @Override
    public void destroy() {
        // TODO Auto-generated method stub

    }

    @Override
    public void init(FilterConfig arg0) throws ServletException {
        // TODO Auto-generated method stub
    }

    @Override
    public void doFilter(ServletRequest req, ServletResponse rep,
            FilterChain chain) throws IOException, ServletException {

        setupParameter((HttpServletRequest)req);
        chain.doFilter(req, rep);
    }
   
    final static String SESSION_ATTRIBUTE_MAP = "SESSION_ATTRIBUTE_MAP";
    final static String PARAM_SELECT          = "selecionar";

    @SuppressWarnings("unchecked")
    private void
setupParameter(HttpServletRequest request) {
       
        Map<String, List<Object>> sessionMap =
                (Map<String, List<Object>>) request.getSession(false).getAttribute(
                        SESSION_ATTRIBUTE_MAP);

        if (sessionMap != null && !sessionMap.isEmpty()) {

            if (sessionMap.get(PARAM_SELECT) != null) {
                Object param = sessionMap.get(PARAM_SELECT).get(0);
                logger.info("** Parameter value: " + param);
            }
        }
    }
}
 


2.i. That's it! SP is working...
Deploy your SP war file for JBoss AS 7 (EAP 6.3) or Wildfly

Try to access localhost:<port>/sp/ directly...
After authentication process, the idp redirects to the original url (destination): http://localhost:<port>/sp
Try to use http://127.0.0.1:<port>/sp...the same url ip will be got...this issue was solved with section 2.f.

Thanks a lot!
See you on the next article...