tag:blogger.com,1999:blog-28169194107316631922024-03-13T23:08:18.173+01:00Open Source and SOA, ESB and SecurityOliver Wulffhttp://www.blogger.com/profile/07294415212532150140noreply@blogger.comBlogger26125tag:blogger.com,1999:blog-2816919410731663192.post-55261609182445861922014-01-27T10:46:00.001+01:002014-01-27T21:07:09.473+01:00Features coming in Fediz 1.2 - RESTThe work for Fediz 1.2 has started and introduces a bunch of new features for the IDP. This post shall introduce the new features to initiate the discussion (recommended in the <a href="http://cxf.apache.org/mailing-lists.html">CXF Dev Mailing list</a>) now. These features become available in the new minor release. Therefore, the branch trunk is has been changed to this version.
The new features are:
<ul>
<li><b>Single Logout</b><p>
The IDP supports to logout from all web applications in one click according the WS-Federation specification
</li>
<li><b>REST interface and JPA persistence store</b><p>
Configure your IDP, its relying parties (applications) and Trusted IDPs using a REST interface and make the configuration persistent in a database instead of using Spring configuration files.
</li>
</ul>
This blog focus on the new REST interface and the persistence layer using JPA.
<p>
The current release version of the IDP is configured with spring configuration files which is fine for static configurations. If you make a change to support new claims or register a new relying party (web application) you have to update the spring configuration file of the fediz-idp WAR and redeploy. Therefore, the IDP has been enhanced to provide a REST interface to manage the IDP(s), its trusted IDPs, the applications and the claims for each application as well as for the IDP. The data is persistet using JPA. The complexity of the IDP is increased due to the requirement of a database but you can also use a database like H2 or HSQL which supports to launch the database embedded.
</b>
The following picture illustrates the class diagram and its relationships:
<div class="separator" style="clear: both; text-align: center;"><a href="http://2.bp.blogspot.com/-iquUNbsBPJY/UuYm4zMA4-I/AAAAAAAAAHQ/9aRP3DeDWS0/s1600/fediz-idp.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://2.bp.blogspot.com/-iquUNbsBPJY/UuYm4zMA4-I/AAAAAAAAAHQ/9aRP3DeDWS0/s400/fediz-idp.png" /></a></div>
<p>
As you notice, all relationships are <i>aggregations</i> which means the lifecycle of application has no dependency to the claims. The relationship between application and claim is specical because depending on the relation an claim is optional or mandatory.
<p>
<h4>REST Interface</h4>
The classes in the above class diagram map to root level resources which are independently managed (create, read, update, <i>delete</i>).
<p>
Base URL: <code>https://<hostname>:<port>/fediz-idp/services/rs</code>
<h3>Resource Claim</h3>
<p>
<code>/claims</code>
<ul style="list-style: none;margin-top: 0px; margin-bottom: 0px;">
<li><b>GET</b><p style="margin-top: 0px; margin-bottom: 0px;">
<ul style="list-style: none;">
Returns all resources for <code>Claim</code>. This is a collection and can be filtered (see below)<p style="margin-top: 0px; margin-bottom: 0px;">
<i>Request</i><p style="margin-top: 0px; margin-bottom: 0px;">
<ul style="list-style: none;margin-top: 0px; margin-bottom: 0px;"><li>N.A.</li></ul>
<i>Response</i>
<ul style="margin-top: 0px; margin-bottom: 0px;">
<li>200 (OK)<p style="margin-top: 0px; margin-bottom: 0px;">
Response Body:
<pre style="margin-top: 0px; margin-bottom: 0px; font-size: medium;">
<ns2:claims xmlns:ns2="http://org.apache.cxf.fediz/">
<ns2:claim>
<claimType>http://schemas.xmlsoap.org/ws/2005/05/identity/claims/postal</claimType>
</ns2:claim>
<ns2:claim>
<claimType>http://schemas.xmlsoap.org/ws/2005/05/identity/claims/surename</claimType>
</ns2:claim>
</ns2:claims>
</pre>
</li>
<li>500 (Error)</li>
</ul>
</ul>
</li> <!-- GET -->
<li><b>POST</b><p style="margin-top: 0px; margin-bottom: 0px;">
<ul style="list-style: none;">
Create a new Claim resource<p style="margin-top: 0px; margin-bottom: 0px;">
<i>Request</i>
<pre style="margin-top: 0px; margin-bottom: 0px; font-size: medium;">
<ns2:claim xmlns:ns2="http://org.apache.cxf.fediz/">
<claimType>http://schemas.xmlsoap.org/ws/2005/05/identity/claims/postal</claimType>
</ns2:claim>
</pre>
<i>Response</i>
<ul style="margin-top: 0px; margin-bottom: 0px;">
<li>201 (Created)<p style="margin-top: 0px; margin-bottom: 0px;">
Response Body: The created resource.<p style="margin-top: 0px; margin-bottom: 0px;">
Response Header: <code>Location</code> contains the URL of the created resource.
</li>
<li>500 (Error)</li>
</ul>
</ul>
</li> <!-- POST -->
</ul>
<code>/claims/{claimType}</code>
<ul style="list-style: none;margin-top: 0px; margin-bottom: 0px;">
<li><b>GET</b><p style="margin-top: 0px; margin-bottom: 0px;">
<ul style="list-style: none;">
Get the claim with the requested <code>claimType</code><p style="margin-top: 0px; margin-bottom: 0px;">
<i>Request</i><p style="margin-top: 0px; margin-bottom: 0px;">
<ul style="list-style: none;margin-top: 0px; margin-bottom: 0px;"><li>N.A.</li></ul>
<i>Response</i>
<ul style="margin-top: 0px; margin-bottom: 0px;">
<li>200<p style="margin-top: 0px; margin-bottom: 0px;">
Response Body: The claim with the requested <code>claimType</code><p style="margin-top: 0px; margin-bottom: 0px;">
</li>
<li>500 (Error)</li>
<li>404 (Not found)</li>
</ul>
</ul>
</li> <!-- GET -->
<li><b>PUT</b><p style="margin-top: 0px; margin-bottom: 0px;">
<ul style="list-style: none;">
Update the claim with PathParam <code>claimType</code><p style="margin-top: 0px; margin-bottom: 0px;">
<i>Request</i>
<pre style="margin-top: 0px; margin-bottom: 0px; font-size: medium;">
<ns2:claim xmlns:ns2="http://org.apache.cxf.fediz/">
<claimType>http://schemas.xmlsoap.org/ws/2005/05/identity/claims/postal</claimType>
<displayName>Postal</displayName>
</ns2:claim>
</pre>
<i>Response</i>
<ul style="margin-top: 0px; margin-bottom: 0px;">
<li>204 (No Content)</li>
<li>500 (Error)</li>
</ul>
</ul>
</li> <!-- PUT -->
<li><b>DELETE</b><p style="margin-top: 0px; margin-bottom: 0px;">
<ul style="list-style: none;">
Delete the claim with the <code>claimType</code> passed as PathParam<p style="margin-top: 0px; margin-bottom: 0px;">
<i>Request</i><p style="margin-top: 0px; margin-bottom: 0px;">
<ul style="list-style: none;margin-top: 0px; margin-bottom: 0px;"><li>N.A.</li></ul>
<i>Response</i>
<ul style="margin-top: 0px; margin-bottom: 0px;">
<li>204 (NoContent)</li>
<li>500 (Error)</li>
</ul>
</ul>
</li> <!-- DELETE -->
</ul>
<h3>Resource Application</h3>
<p>
<code>/applications</code>
<ul style="list-style: none;margin-top: 0px; margin-bottom: 0px;">
<li><b>GET</b><p style="margin-top: 0px; margin-bottom: 0px;">
<ul style="list-style: none;">
Returns all resources for <code>Application</code>. This is a collection and can be filtered (see below)<p style="margin-top: 0px; margin-bottom: 0px;">
<i>Request</i><p style="margin-top: 0px; margin-bottom: 0px;">
<ul style="list-style: none;margin-top: 0px; margin-bottom: 0px;"><li>N.A.</li></ul>
<i>Response</i>
<ul style="margin-top: 0px; margin-bottom: 0px;">
<li>200 (OK)<p style="margin-top: 0px; margin-bottom: 0px;">
Response Body:
<pre style="margin-top: 0px; margin-bottom: 0px; font-size: medium;">
<applications xmlns:ns2="http://org.apache.cxf.fediz/">
<ns2:application id="100">
<realm>urn:org:apache:cxf:fediz:fedizhelloworld</realm>
<role>ApplicationServiceType</role>
<serviceDisplayName>Fedizhelloworld</serviceDisplayName>
...
</pre>
</li>
<li>500 (Error)</li>
</ul>
</ul>
</li> <!-- GET -->
<li><b>POST</b><p style="margin-top: 0px; margin-bottom: 0px;">
<ul style="list-style: none;">
Create a new Application resource<p style="margin-top: 0px; margin-bottom: 0px;">
<i>Request</i>
<pre style="margin-top: 0px; margin-bottom: 0px; font-size: medium;">
<ns2:application xmlns:ns2="http://org.apache.cxf.fediz/">
<realm>urn:org:apache:cxf:fediz:newapp</realm>
<role>ApplicationServiceType</role>
<serviceDisplayName>Fedizhelloworld new</serviceDisplayName>
</pre>
<i>Response</i>
<ul style="margin-top: 0px; margin-bottom: 0px;">
<li>201 (Created)<p style="margin-top: 0px; margin-bottom: 0px;">
Response Body: The created resource.<p style="margin-top: 0px; margin-bottom: 0px;">
Response Header: <code>Location</code> contains the URL of the created resource.
</li>
<li>500 (Error)</li>
</ul>
</ul>
</li> <!-- POST -->
</ul>
<code>/applications/{realm}</code>
<ul style="list-style: none;margin-top: 0px; margin-bottom: 0px;">
<li><b>GET</b><p style="margin-top: 0px; margin-bottom: 0px;">
<ul style="list-style: none;">
Get the application with the requested <code>realm</code><p style="margin-top: 0px; margin-bottom: 0px;">
<i>Request</i><p style="margin-top: 0px; margin-bottom: 0px;">
<ul style="list-style: none;margin-top: 0px; margin-bottom: 0px;"><li>N.A.</li></ul>
<i>Response</i>
<ul style="margin-top: 0px; margin-bottom: 0px;">
<li>200<p style="margin-top: 0px; margin-bottom: 0px;">
Response Body: The application with the requested <code>realm</code><p style="margin-top: 0px; margin-bottom: 0px;">
</li>
<li>500 (Error)</li>
<li>404 (Not found)</li>
</ul>
</ul>
</li> <!-- GET -->
<li><b>PUT</b><p style="margin-top: 0px; margin-bottom: 0px;">
<ul style="list-style: none;">
Update the application with PathParam <code>realm</code><p style="margin-top: 0px; margin-bottom: 0px;">
<i>Request</i>
<pre style="margin-top: 0px; margin-bottom: 0px; font-size: medium;">
<ns2:application xmlns:ns2="http://org.apache.cxf.fediz/">
<realm>urn:org:apache:cxf:fediz:newapp</realm>
<role>ApplicationServiceType</role>
<serviceDisplayName>Fedizhelloworld new</serviceDisplayName>
...
</pre>
<i>Response</i>
<ul style="margin-top: 0px; margin-bottom: 0px;">
<li>204 (No Content)</li>
<li>500 (Error)</li>
</ul>
</ul>
</li> <!-- PUT -->
<li><b>DELETE</b><p style="margin-top: 0px; margin-bottom: 0px;">
<ul style="list-style: none;">
Delete the application with the <code>realm</code> passed as PathParam<p style="margin-top: 0px; margin-bottom: 0px;">
<i>Request</i><p style="margin-top: 0px; margin-bottom: 0px;">
<ul style="list-style: none;margin-top: 0px; margin-bottom: 0px;"><li>N.A.</li></ul>
<i>Response</i>
<ul style="margin-top: 0px; margin-bottom: 0px;">
<li>204 (NoContent)</li>
<li>500 (Error)</li>
</ul>
</ul>
</li> <!-- DELETE -->
</ul>
<code>/applications/{realm}/claims</code>
<ul style="list-style: none;margin-top: 0px; margin-bottom: 0px;">
<li><b>POST</b><p style="margin-top: 0px; margin-bottom: 0px;">
<ul style="list-style: none;">
Add a relationship (aggregation) between the application <code>realm</code> to an existing claim<p style="margin-top: 0px; margin-bottom: 0px;">
<i>Request</i>
<pre style="margin-top: 0px; margin-bottom: 0px; font-size: medium;">
<ns2:requestClaim xmlns:ns2="http://org.apache.cxf.fediz/">
<claimType>http://schemas.xmlsoap.org/ws/2005/05/identity/claims/surname</claimType>
<optional>false</optional>
</ns2:requestClaim>
</pre>
<i>Response</i>
<ul style="margin-top: 0px; margin-bottom: 0px;">
<li>201 (No Content)</li>
<li>409 (Conflict)<p style="margin-top: 0px; margin-bottom: 0px;">If the claim is already added to the resource</li>
<li>500 (Error)</li>
</ul>
</ul>
</li> <!-- POST -->
</ul>
<code>/applications/{realm}/claims/{claimType}</code>
<ul style="list-style: none;margin-top: 0px; margin-bottom: 0px;">
<li><b>DELETE</b><p style="margin-top: 0px; margin-bottom: 0px;">
<ul style="list-style: none;">
Delete the relationship (aggregation) between resource <code>Application</code> with the <code>realm</code> and the Sub-Resource <code>claim</code><p style="margin-top: 0px; margin-bottom: 0px;">
<i>Request</i><p style="margin-top: 0px; margin-bottom: 0px;">
<ul style="list-style: none;margin-top: 0px; margin-bottom: 0px;"><li>N.A.</li></ul>
<i>Response</i>
<ul style="margin-top: 0px; margin-bottom: 0px;">
<li>204 (NoContent)</li>
<li>500 (Error)</li>
</ul>
</ul>
</li> <!-- DELETE -->
</ul>
<h3>Resource TrustedIdp</h3>
<p>
<code>/trusted-idps</code>
<ul style="list-style: none;margin-top: 0px; margin-bottom: 0px;">
<li>Trusted IDP has got the same methods like the Resource <code>Claim</code> and <code>Application</code></li>
</ul>
<code>/trusted-idps/{realm}</code>
<ul style="list-style: none;margin-top: 0px; margin-bottom: 0px;">
<li>Trusted IDP has got the same methods like the Resource <code>Claim</code> and <code>Application</code></li>
</ul>
<p>
<h3>Resource Idp</h3>
<p>
<code>/idps</code>
<ul style="list-style: none;margin-top: 0px; margin-bottom: 0px;">
<li>IDP has got the same methods like the other resources</li>
</ul>
<code>/idps/{realm}</code>
<ul style="list-style: none;margin-top: 0px; margin-bottom: 0px;">
<li>IDP has got the same methods like the other resources</li>
</ul>
<code>/idps/{realm}/claims</code>
<ul style="list-style: none;margin-top: 0px; margin-bottom: 0px;">
<li><b>POST</b><p style="margin-top: 0px; margin-bottom: 0px;">
<ul style="list-style: none;">
Add a relationship (aggregation) between the resource <code>Idp</code> with the <code>realm</code> to an existing claim<p style="margin-top: 0px; margin-bottom: 0px;">
<i>Request</i>
<pre style="margin-top: 0px; margin-bottom: 0px; font-size: medium;">
<ns2:Claim xmlns:ns2="http://org.apache.cxf.fediz/">
<claimType>http://schemas.xmlsoap.org/ws/2005/05/identity/claims/surname</claimType>
</ns2:Claim>
</pre>
<i>Response</i>
<ul style="margin-top: 0px; margin-bottom: 0px;">
<li>204 (No Content)</li>
<li>409 (Conflict)<p style="margin-top: 0px; margin-bottom: 0px;">If the claim is already added to the resource</li>
<li>500 (Error)</li>
</ul>
</ul>
</li> <!-- POST -->
</ul>
<code>/idps/{realm}/claims/{claimType}</code>
<ul style="list-style: none;margin-top: 0px; margin-bottom: 0px;">
<li><b>DELETE</b><p style="margin-top: 0px; margin-bottom: 0px;">
<ul style="list-style: none;">
Delete the relationship (aggregation) between resource <code>Idp</code> with the <code>realm</code> and the Sub-Resource <code>claim</code><p style="margin-top: 0px; margin-bottom: 0px;">
<i>Request</i><p style="margin-top: 0px; margin-bottom: 0px;">
<ul style="list-style: none;margin-top: 0px; margin-bottom: 0px;"><li>N.A.</li></ul>
<i>Response</i>
<ul style="margin-top: 0px; margin-bottom: 0px;">
<li>204 (NoContent)</li>
<li>500 (Error)</li>
</ul>
</ul>
</li> <!-- DELETE -->
</ul>
<code>/idps/{realm}/applications</code>
<ul style="list-style: none;margin-top: 0px; margin-bottom: 0px;">
<li><b>POST</b><p style="margin-top: 0px; margin-bottom: 0px;">
<ul style="list-style: none;">
Add a relationship (aggregation) between the resource <code>Idp</code> with the <code>realm</code> to an existing resource <code>Application</code><p style="margin-top: 0px; margin-bottom: 0px;">
<i>Request</i>
<pre style="margin-top: 0px; margin-bottom: 0px; font-size: medium;">
<ns2:Application xmlns:ns2="http://org.apache.cxf.fediz/">
<realm>urn:org:apache:cxf:fediz:newapp</realm>
</ns2:Application>
</pre>
<i>Response</i>
<ul style="margin-top: 0px; margin-bottom: 0px;">
<li>204 (No Content)</li>
<li>409 (Conflict)<p style="margin-top: 0px; margin-bottom: 0px;">If the application is already added to the resource</li>
<li>500 (Error)</li>
</ul>
</ul>
</li> <!-- POST -->
</ul>
<code>/idps/{realm}/applications/{applicationRealm}</code>
<ul style="list-style: none;margin-top: 0px; margin-bottom: 0px;">
<li><b>DELETE</b><p style="margin-top: 0px; margin-bottom: 0px;">
<ul style="list-style: none;">
Delete the relationship (aggregation) between resource <code>Idp</code> with the <code>realm</code> and the Sub-Resource <code>Application</code> passed in <code>applicationRealm</code><p style="margin-top: 0px; margin-bottom: 0px;">
<i>Request</i><p style="margin-top: 0px; margin-bottom: 0px;">
<ul style="list-style: none;margin-top: 0px; margin-bottom: 0px;"><li>N.A.</li></ul>
<i>Response</i>
<ul style="margin-top: 0px; margin-bottom: 0px;">
<li>204 (NoContent)</li>
<li>500 (Error)</li>
</ul>
</ul>
</li> <!-- DELETE -->
</ul>
<code>/idps/{realm}/trusted-idps</code>
<ul style="list-style: none;margin-top: 0px; margin-bottom: 0px;">
<li><b>POST</b><p style="margin-top: 0px; margin-bottom: 0px;">
<ul style="list-style: none;">
Add a relationship (aggregation) between the resource <code>Idp</code> with the <code>realm</code> to an existing resource <code>TrustedIdp</code><p style="margin-top: 0px; margin-bottom: 0px;">
<i>Request</i>
<pre style="margin-top: 0px; margin-bottom: 0px; font-size: medium;">
<ns2:TrustedIdp xmlns:ns2="http://org.apache.cxf.fediz/">
<realm>urn:org:apache:cxf:fediz:idp:realm-B</realm>
</ns2:TrustedIdp>
</pre>
<i>Response</i>
<ul style="margin-top: 0px; margin-bottom: 0px;">
<li>204 (No Content)</li>
<li>409 (Conflict)<p style="margin-top: 0px; margin-bottom: 0px;">If the trusted IDP is already added to the resource</li>
<li>500 (Error)</li>
</ul>
</ul>
</li> <!-- POST -->
</ul>
<code>/idps/{realm}/trusted-idps/{trustedIdpRealm}</code>
<ul style="list-style: none;margin-top: 0px; margin-bottom: 0px;">
<li><b>DELETE</b><p style="margin-top: 0px; margin-bottom: 0px;">
<ul style="list-style: none;">
Delete the relationship (aggregation) between resource <code>Idp</code> with the <code>realm</code> and the Sub-Resource <code>TrustedIdp</code> passed in <code>trustedIdpRealm</code><p style="margin-top: 0px; margin-bottom: 0px;">
<i>Request</i><p style="margin-top: 0px; margin-bottom: 0px;">
<ul style="list-style: none;margin-top: 0px; margin-bottom: 0px;"><li>N.A.</li></ul>
<i>Response</i>
<ul style="margin-top: 0px; margin-bottom: 0px;">
<li>204 (NoContent)</li>
<li>500 (Error)</li>
</ul>
</ul>
</li> <!-- DELETE -->
</ul>
<p>
<h3>Additional features of the REST interface</h3>
<ul>
<li>JSON Support<p>
By adding <code>.json</code> as a suffix to the URL you can enforce to get a JSON representation back instead of the default XML representation</li>
<li>Filter entries on collections (paging)<p>
The query parameters <code>start</code> and <code>size</code> allow you to define (default, 0, 5)
<li>Query parameter <code>expand</code><p>
As of now, sub-resources are embedded in the response by default. But I'm considering to not return all sub-resources by default when hypermedia support is added to the REST interface. Hypermedia will return link URLs where the sub-resources can be resolved</li>
</ul>
The following example illustrates how the sub-resource <code>Claim</code> is embedded in the resource <code>Application</code>.
<pre>
<ns2:application id="100" xmlns:ns2="http://org.apache.cxf.fediz/">
<realm>urn:org:apache:cxf:fediz:fedizhelloworld</realm>
...
<claims>
<ns2:requestClaim id="100">
<claimType>http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname</claimType>
<description>Description for firstname</description>
<displayName>firstname</displayName>
<optional>true</optional>
</ns2:requestClaim>
</pre>
The resource <code>Application</code> supports the values <i>claims</i> and <i>all</i> for the query parameter <code>expand</code> and the resource <code>Idp</code> supports the values <i>claims</i>, <i>trusted-idps</i> and <i>applications</i>. You can also send several values for the query parameter <code>expand</code> as illustrated in the following example:
<pre>
?expand=claims&expand=applications
</pre>
<h3>What is missing in the current SNAPSHOT version</h3>
The following features are missing in the current SNAPSHOT version:
<ul>
<li>Single Log Out (Patch applied to JIRA request)</lio>
<li>Authentication support for REST interface</li>
<li>Hypermedia support for REST interface</li>
</ul>
<p>
<h3>Note</h3>
As you noticed, the IDP supports a collection of IDPs. This is by intention even the current version doesn't support several realms in one IDP whereas the feature is already supported by the STS. This is planned in the next release.<p>
In smaller companies you might have only one Identity Store whereas in bigger companies you probably have more than one Identity Store. To avoid deploying each IDP realm in a different Servlet Contexts the Fediz IDP will support several IDPs in one deployment. The realms are differentiated by the URL which is addressed by property <code>uri</code> in the future.
<p>
<h4>Testing</h4>
You can either start the IDP standalone (Jetty Maven Plugin) or within a pre-configured Tomcat Container.<p>
<h3>Standalone deployment</h3>
The easiest approach to test the new IDP is checking out the sources as described in section <i>Building</i> <a href="http://cxf.apache.org/fediz.html">here</a> and build from the project root directory:
<pre>
mvn clean install
</pre>
Then run within the sub-directory <code>services/idp</code> the following Maven command:
<pre>
mvn jetty:run-war
</pre>
This command will start the Jetty container and deploy the IDP in there. The database used in HSQL and the default HTTPS port is 9443 and HTTP is 9080. You can overwrite the ports with the Maven properties <code>idp.https.port</code> and <code>idp.http.port</code> as illustrated here:
<pre>
mvn jetty:run-war -Didp.https.port=8443
</pre>
<h3>Tomcat Deployment</h3>
The <code>fediz-idp.war</code> does NOT ship the JDBC driver JAR. Be sure to deploy it under <code>$CATALINA_HOME/lib</code>. If you don't update the <code>persistence.properties</code> the default database is HSQL.
You can also define the datasource on the Container Level if you like under the JNDI name <code>java:comp/env/jdbc/fedizDataSource</code>.
<p>
<h3>soapUI Test</h3>
After you started the IDP you can import the WADL (WADL is the counterpart of a WDSL for Web Services) which can be accessed at the following URL (assumption: you started the IDP with the defaults):
<pre>
https://localhost:9443/fediz-idp/services/rs?_wadl
</pre>
<h4>Summary</h4>
The REST interface is in early stage and subject to change. It's very important to have a stable REST interface for future. As the current IDP doesn't provide a Web-UI yet, you can build your own Web-UI and use the REST interface to administer the behaviour of the Fediz IDP. Therefore, it's very important to get a stable REST interface without requiring changes in your Web-UI with each new Fediz IDP release.<p>
Please provide feedback to the <a href="http://cxf.apache.org/mailing-lists.html">CXF Dev Mailing list</a> to discuss the feedback in broader audience.Oliver Wulffhttp://www.blogger.com/profile/07294415212532150140noreply@blogger.com6tag:blogger.com,1999:blog-2816919410731663192.post-54835347383636040002013-11-11T20:08:00.000+01:002013-11-11T20:09:32.228+01:00Apache CXF FEDIZ 1.1.0 releasedThe CXF community has released the new Version of Apache CXF <a href="http://cxf.apache.org/fediz.html">Fediz</a>.
Fediz helps you to secure your web applications and delegate security context to the underlying application which can be used for impersonation when calling other Web Services. With Fediz, authentication is externalized from your web application to an identity provider installed as a dedicated server component. The supported standard is <a href="http://docs.oasis-open.org/wsfed/federation/v1.2/os/ws-federation-1.2-spec-os.html">WS-Federation</a> Passive Requestor Profile.
<p>
The following features has been added:
<ul>
<li>Fediz IDP supports Resource and Requestor IDP role, Home Realm Discovery Service, ...</li>
<li>SAML Holder-Of-Key supported</li>
<li>Encrypted SAML Tokens supported</li>
<li>Support for Jetty, Websphere and Spring Security 2.0/3.1</li>
<li>Publish WS-Federation Metadata document for RP and IDP</li>
</ul>
<p>
The major contribution is the refactoring of the IDP to leverage the functionality and flexibility provided by Spring Web Flow and Spring Security. I wrote about this new feature <a href="http://owulff.blogspot.ch/2013/09/fediz-11-introduces-federation-across_4.html">here</a>. More details to come like customizing the signin flow, etc.
<p>
Release notes are available <a href="http://svn.apache.org/viewvc/cxf/fediz/tags/fediz-1.1.0/release_notes.txt?view=markup">here</a>.
<p>
For more information see:
<ul>
<li>
Download: <a href="http://cxf.apache.org/fediz-downloads.html">http://cxf.apache.org/fediz-downloads.html</a></li>
<li>
Website: <a href="http://cxf.apache.org/fediz.html">http://cxf.apache.org/fediz.html</a></li>
<li>
Mailing lists: <a href="http://cxf.apache.org/mailing-lists.html">http://cxf.apache.org/mailing-lists.html</a></li>
</ul>
<br>
Features to come in the next release:
<ul>
<li>
Integration with CXF JAX-RS
</li>
<li>
SAML-P support
</li>
</ul>
Feel free to raise enhancement requests and issues in the <a href="https://issues.apache.org/jira/browse/FEDIZ">JIRA project</a>
<p>
Thank you for all support and feedback!Oliver Wulffhttp://www.blogger.com/profile/07294415212532150140noreply@blogger.com0tag:blogger.com,1999:blog-2816919410731663192.post-49632293942503414782013-09-04T23:12:00.001+02:002013-09-10T13:28:03.991+02:00Fediz 1.1 introduces Federation across Security Domains (Part 2)In the first <a href="http://owulff.blogspot.com/2013/09/fediz-11-introduces-federation-across.html">blog </a>on this topic I explained how to add security domains to the Fediz STS which is based on the Apache CXF STS. This blog focuses on how to set up the Fediz IDP thus you can access an application but authenticate either against the requestor IDP of realm A or realm B.<p>
I posted a blog some time back about WS-Federation across several companies and explained the benefits and key requirements <a href="http://owulff.blogspot.com/2012/03/ws-federation-across-several-companies.html">here</a>. I recommend to read that blog first.<p>
Here a quick summary of the goals and requirements by introducing WS-Federation for Web Application Single-Sign-On:
<ul>
<li>Application doesn't care about authentication</li>
<li>Application doesn't care against which authentication system the user has been authenticated</li>
<li>Application doesn't care where the user attributes are coming from</li>
<li>Application has got a trusted relationship with a single IDP/STS instance which ensures the user is authenticated and the user attributes are provided in one syntax and semantic independent from which source they are coming from</li>
<li>Application must be able to enforce certain authentication methods (ex. strong authentication)</li>
<li>Application must be able to enforce certain user attributes in the security token</li>
</ul>
<p>
In the last blog, we've prepared the STS which is responsible to issue tokens for the two realms <i>REALMA</i> and <i>REALMB</i>. Further, the STS is able to federate between the two realms by mapping the identities (attribute <i>type</i> of <code>Relationship</code> bean configuration. This means, a person must have an identity in realm A (ex. bob) and an identity in realm B (ex. BOB). To keep it simple, the mapping is based to lowercase the username. Another option is to federate/map the claims which doesn't require that a person must have an identity in both realms. This requires more effort to set up a demo and might be provided in the future for illustration purposes, but all required functionality and extension points are available.<p>
<i>Notes:</i>
<ul>
<li>The Fediz IDP doesn't support yet to host several realms in one WAR file. Therefore, two Servlet Containers must be set up to deploy the IDP war file.<p>In B2B scenarios this won't be required anyway as the B2B partner has got an IDP attached to its realm as well as the application service provider has got an IDP attached to its realm. It might make sense in scenarios where the company itself has got more than one authentication systems in place.</li>
<li>For ease of use, the Fediz IDP and Fediz STS are deployed into the same Serlvet Container and therefore accessed with the same TCP port. Due to the fact, that the Fediz STS supports both realms in one WAR file, the Fediz STS WAR <code>fediz-idp-sts.war</code> is just deployed twice.</li>
</ul>
<p>
<h2>Install Apache CXF Fediz IDP</h2>
The Fediz IDP is provided as part of the subproject Fediz in Apache CXF. The new version provides the Apache Maven profile <i>realm-a</i> (Default) and <i>realm-b</i> which packages the IDP either for security domain <i>REALM A</i> and <i>REALM B</i>.
<p>
You can either download the sources of the Fediz IDP from the following location<p>
<pre>
git clone git://git.apache.org/cxf-fediz.git
</pre>
<p>or<p>
<pre>
svn co https://svn.apache.org/repos/asf/cxf/fediz/trunk
</pre>
You can build the IDP for <b>realm A</b> with the following Maven command<p>
<pre>
mvn clean install -Prealm-a
</pre>
The IDP is packaged as a WAR file at <code>services/idp/target/fediz-idp.war</code>
<p>
You can build the IDP for <b>realm B</b> with the following Maven command<p>
<pre>
mvn clean install -Prealm-b
</pre>
The IDP is packaged as a WAR file at <code>services/idp/target/fediz-idp-remote.war</code>
<p>
<i>Note: </i>The WAR file and therefore the servlet context name is not <code>fediz-idp</code> but <code>fediz-idp-remote</code>. This is required because cookies are bound to the hostname (ex. localhost) and the path (ex. fediz-idp). If the servlet context is the same, cookies are overwritten between the two IDP instances. There are also other options to bound the WAR file with a specific servlet context name but this relies on the Servlet Container provider.
<p>
Last option is to download the archive from the <a href="https://repository.apache.org/content/groups/snapshots/org/apache/cxf/fediz/">snapshot</a> maven repository. Keep in mind that this IDP is built with the profile <i>realm-a</i>. Only the following files must be updated for realm B:
<ul>
<li><code>WEB-INF/applicationContext.xml</code><p>
Change
<pre><import resource="idp-config-realma.xml" /></pre><p>to<p><pre><import resource="idp-config-<b>realmb</b>.xml" /></pre></li>
<li><code>WEB-INF/classes/realm.properties</code><p>
Change
<pre>realm.STS_URI=REALMA</pre><p>to<p><pre>realm.STS_URI=<b>REALMB</b></pre></li>
<li><code>WEB-INF/web.xml</code><p>
Change
<pre><param-value>urn:org:apache:cxf:fediz:idp:realm-A</param-value></pre><p>to<p><pre><param-value>urn:org:apache:cxf:fediz:idp:<b>realm-B</b></param-value></pre></li>
</ul>
<p>
<i>Note: </i>The built WAR files require that IDP Realm A is deployed into a Servlet Container running on port <code>9443</code> and IDP Realm B is deployed into a Servlet Container running on port <code>12443</code>. If you want to change that then you must update the file <code>WEB-INF/classes/realm.properties</code> or at source location <code>services/idp/src/main/resources/</code>.
<p>
<h2>Update Relying Party (Application)</h2>
I assume you have installed <code>fedizhellworld</code> example into a supported Serlvet Container. If not, install the <code>fedizhellworld</code> example based on the <code>README.txt</code>.<p>
The following steps must be processed to establish the trust with the IDP Realm A:
<ul>
<li>Issuer URL must be <b>Realm A</b> (ex. <code>https://localhost:9443/fediz-idp/federation </code>)</li>
<li>Signer certificate of Realm A must be imported into the truststore because new certificates are used for realm A and realm B<br>You can either copy the file <code>stsstore.jks</code> from the STS archive within <code>WEB-INF/classes</code> or copy the file <code>realma.cert</code> from the STS archive from the same location.</li>
</ul>
<h2>Run the demo</h2>
You have now deployed the IDP realm A (fediz-idp.war) into a Servlet Container listening on port <code>9443</code> and IDP realm B (fediz-idp-remote.war) into a Servlet Container listening on port <code>12443</code>. Finally, the Relying Party has been updated to trust the IDP Realm A.<p>
When you now access the fedizhelloworld application (ex. https://localhost:8443/fedizhelloworld/secure/fedservlet) you get redirected to the IDP Realm A and the following web page is shown
<a href="http://2.bp.blogspot.com/-Hd2VqAIEPpc/Uici-IHVrdI/AAAAAAAAAGI/gvN0hSAd9Ho/s1600/Fediz-TrustedIDPList.png" imageanchor="1" ><img border="0" src="http://2.bp.blogspot.com/-Hd2VqAIEPpc/Uici-IHVrdI/AAAAAAAAAGI/gvN0hSAd9Ho/s640/Fediz-TrustedIDPList.png" /></a>
<p>
You can now choose in which domain you would like to authenticate. Choose the IDP in the list and click <i>Select Home Realm</i>. If you choose Realm B you get redirected to IDP Realm B and username/password popup is shown (use uppercase username and passwords) or IDP Realm A shows username/password popup (use lowercase username and passwords).
<p>
If you choose Realm B and enter the user <i>ALICE</i> and the password <i>ECILA</i> you finally see the user <i>alice</i> (lowercase) shown in the application. You know why? Exactly, the STS does the identity mapping when the REALM A is requested a SAML token for the application fedizhelloworld on-behalf-of the SAML token issued by Realm B.
<p>
<i>Notes</i>
<ul>
<li>The IDP will ask you only once to choose your home realm. The choice is stored in the cookie <code>FEDIZ_HOME_REALM</code></li>
<li>If your home realm is realm B and you're successfully authenticated, the IDP realm A won't redirect you to realm B the next time, as the original SAML token of realm B is cached in realm A.</li>
</ul>
<h2>IDP Configurations</h2>
The design of the IDP changed (Spring Web Flow and Spring Security), new features are implemented and thus the configuration is completely different to version 1.0. I don't want to go into too much details in this blog, instead I'll update the Apache CXF Fediz <a href="http://cxf.apache.org/fediz.html">Wiki</a> soon.
<h5>Use form based login</h5>
Change the spring security configuration in <code>WEB-INF/security-config.xml</code> and set the following configuration:
<pre>
<!--<security:http-basic />-->
<security:form-login />
</pre>
<h5>Configure an additional Relying Party</h5>
The main configuration file of the IDP is <code>idp-config-realma.xml</code>. This file contains configurations for the IDP, trusted IDPs and Relying Parties.
<p>If you want to configure an additional application add a <code>ServiceConfig</code> bean and add it to the map <code>services</code> in the IDP configuration bean.
<pre>
<bean id="idp-realmA" class="org.apache.cxf.fediz.service.idp.model.<b>IDPConfig</b>">
...
<property name="services">
<util:map>
<entry key="urn:org:apache:cxf:fediz:fedizhelloworld" value-ref="<b>srv-fedizhelloworld</b>" />
</util:map>
</property>
...
<bean id="<b>srv-fedizhelloworld</b>" class="org.apache.cxf.fediz.service.idp.model.<b>ServiceConfig</b>">
<property name="realm" value="urn:org:apache:cxf:fediz:fedizhelloworld" />
<property name="protocol" value="http://docs.oasis-open.org/wsfed/federation/200706" />
<property name="serviceDisplayName" value="Fedizhelloworld" />
<property name="serviceDescription" value="Web Application to illustrate WS-Federation" />
<property name="role" value="ApplicationServiceType" />
<property name="tokenType" value="http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV2.0" />
<property name="lifeTime" value="3600" />
<property name="requestedClaims">
<util:list>
<bean class="org.apache.cxf.fediz.service.idp.model.RequestClaim">
<property name="claimType" value="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname" />
<property name="optional" value="false" />
</bean>
<bean class="org.apache.cxf.fediz.service.idp.model.RequestClaim">
<property name="claimType" value="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/surname" />
<property name="optional" value="false" />
</bean>
<bean class="org.apache.cxf.fediz.service.idp.model.RequestClaim">
<property name="claimType" value="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress" />
<property name="optional" value="false" />
</bean>
<bean class="org.apache.cxf.fediz.service.idp.model.RequestClaim">
<property name="claimType" value="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/role" />
<property name="optional" value="true" />
</bean>
</util:list>
</property>
</bean>
</pre>
It's important that the attribute <code>realm</code> matches with the realm configured in the application (<code>fediz-config.xml</code>). The attributes <code>tokenType</code>, <code>lifeTime</code> and <code>requestedClaims</code> are optional. Only the protocol defined in the above bean is supported by the IDP and therefore the default value. The remaining attributes are ignored but used in the future like the Web GUI.
<h5>Configure an additional Trusted IDP</h5>
If you want to configure an additional trusted IDP add a <code>TrustedIDPConfig</code> bean and add it to the map <code>trustedIDPs</code> in the IDP configuration bean.
<pre>
<bean id="idp-realmA" class="org.apache.cxf.fediz.service.idp.model.IDPConfig">
...
<property name="trustedIDPs">
<util:map>
<entry key="urn:org:apache:cxf:fediz:idp:realm-B" value-ref="<b>trusted-idp-realmB</b>" />
</util:map>
</property>
...
<bean id="<b>trusted-idp-realmB</b>" class="org.apache.cxf.fediz.service.idp.model.<b>TrustedIDPConfig</b>">
<property name="realm" value="urn:org:apache:cxf:fediz:idp:realm-B" />
<property name="cacheTokens" value="true" />
<property name="url" value="https://localhost:${realmB.port}/fediz-idp-remote/federation" />
<property name="certificate" value="realmb.cert" />
<property name="trustType" value="PEER_TRUST" /> <!-- Required for Fediz Core, Process SignInResponse -->
<property name="protocol" value="http://docs.oasis-open.org/wsfed/federation/200706" />
<property name="federationType" value="FederateIdentity" /> <!-- Required for STS Relationship -->
<property name="name" value="REALM B" />
<property name="description" value="IDP of Realm B" />
</bean>
</pre>
It's important that the filename of the PEM encoded certificate is configured which has been used to sign the SAML token by the trusted IDP. The attribute <code>name</code> is required for informational purposes whereas the remaining attributes are ignored but used in the future like the Web GUI.
<p>
<br>
Even there is much more to say I finish this post and write about other features of the new Fediz IDP in the near future.
<p>
Please post feedback and ideas to the <a href="http://cxf.apache.org/mailing-lists.html">CXF mailing list</a>.
<p>
Thank you for all support and feedback!
Oliver Wulffhttp://www.blogger.com/profile/07294415212532150140noreply@blogger.com2tag:blogger.com,1999:blog-2816919410731663192.post-13894021989653056792013-09-03T10:59:00.001+02:002013-09-10T13:33:13.014+02:00Fediz 1.1 introduces Federation across Security Domains (Part 1)Fediz 1.1 introduces a bunch of new features like support for Jetty, Spring Security and Websphere. But a lot of effort has been put into the Fediz IDP. I'd like to thank Thierry Beucher for his valuable contributions to the new release of the Fediz IDP.
<p>The new features are:
<ul>
<li><b>Federation Metadata</b><p>The IDP supports publishing the WS-Federation Metadata document which allows to more easily integrate the IDP into platforms which support referencing a Metadata document. Metadata consists of the signing certificate, the provided claims, etc.</li>
<li><b>Spring Web Flow support</b><p>The IDP has been refactored to use Spring Web Flow to manage the federation flow. This provides flexibility to be able to customize the IDP to company's specific requirements. The IDP is secured by Spring Security to get the benefits and flexibility of Spring Security.</li>
<li><b>Resource IDP and Home Realm Discovery</b><p>This is the major new feature. The IDP is able to figure out from which security domain/realm the browser request is coming from to redirect the sign-in request to the requestor IDP which does the authentication and issues a token which is sent to the Resource IDP. The Resource IDP will then either map the principal from one security domain to the target security domain and get claims information of the mapped principal or transform the claims information and finally issue a new token for the relying party (application).
<p>More complex scenarios described in this <a href="http://owulff.blogspot.ch/2012/03/ws-federation-across-several-companies.html">blog</a> are now possible.
</ul>
<p>
In this post, I'd like to focus on the last feature which I splitted in two posts. The first one focuses on extending the STS to support more than one security domain/realm and the second on the IDP.
<p>
<h2>Install Apache CXF Fediz IDP</h2>
The Fediz STS is provided as part of the subproject Fediz in Apache CXF. The new version provides the Apache Maven profile <i>realms</i> which packages an STS with two security domains called <i>REALM A</i> and <i>REALM B</i>.
<p>
You can either download the sources of the Fediz STS from the following location<p>
<pre>
git clone git://git.apache.org/cxf-fediz.git
</pre>
<p>or<p>
<pre>
svn co https://svn.apache.org/repos/asf/cxf/fediz/trunk
</pre>
You can build the whole project with the following Maven command<p>
<pre>
mvn clean install
</pre>
The STS is packaged as a WAR file at <code>services/sts/target/fediz-idp-sts.war</code>
<p>
or download the archive from the <a href="https://repository.apache.org/content/groups/snapshots/org/apache/cxf/fediz/">snapshot</a> maven repository.
<p>
The URL of the STS has the following syntax depending on the hostname and port of your servlet engine.
<code>
https://localhost:port/fediz-idp-sts/?wsdl
</code>
The page will list the different URL's for the web service endpoints of the STS:
<ul>
<li><code>https://localhost:9443/fediz-idp-sts/REALMA/STSServiceTransportUT</code><br>STS endpoint for REALM A which requires username/password authentication</li>
<li><code>https://localhost:9443/fediz-idp-sts/REALMA/STSServiceTransport</code><br>STS endpoint for REALM A with requires on-behalf-of saml token (implicit identiy mapping is done)</li>
<li><code>https://localhost:9443/fediz-idp-sts/REALMB/STSServiceTransportUT</code><br>STS endpoint for REALM B which requires username/password authentication</li>
<li><code>https://localhost:9443/fediz-idp-sts/REALMB/STSServiceTransport</code><br>STS endpoint for REALM B with requires on-behalf-of saml token (implicit identiy mapping is done)</li>
</ul>
In the context of federation, you request a token from your requestor STS/IDP. In this example, either REALM-A or REALM-B with username/password <code>(.../fediz-idp-sts/<realm>/STSServiceTransportUT)</code>. After authentication, you request (implicitly as part of the federation protocol) a specific token of the security domain/realm where the application is conntected to. This use case makes use of the on-behalf-of feature of the STS <code>(.../fediz-idp-sts/<realm>/STSServiceTransport)</code>.
<p>
The following users are set up in realm A and realm B:
<table>
<tr><td>User</td><td>Password</td></tr>
<tr><td span=2><i>Realm A</i></td></tr>
<tr><td>alice</td><td>eclia</td></tr>
<tr><td>bob</td><td>bob</td></tr>
<tr><td>ted</td><td>det</td></tr>
<tr><td span=2><i>Realm B</i></td></tr>
<tr><td>ALICE</td><td>ECLIA</td></tr>
<tr><td>BOB</td><td>BOB</td></tr>
<tr><td>TED</td><td>DET</td></tr>
</table>
<p>
As you might imagine, the identity mapping implementation is fairly easy as you just lower- or uppercase the principal name. More information about how to plug in different identity mappings see below in <b>Identity Mapper</b>.
<p>
<h2>How to add a new security domain to the STS</h2>
If you customize the realms or add an additional realm, the following steps are required. You can either customize the deployed WAR <code>fediz-idp-sts.war</code> of the downloaded archive or make updates to the sources<br>
<i>Note: </i>You could also make use of the <a href="http://maven.apache.org/plugins/maven-war-plugin/overlays.html">Overlay</a> feature of Apache Maven.
<ul>
<li><b>Define a new realm C</b><p>
Some beans must be updated and added to the Spring configuration file <code>cxf-transport.xml</code>. The changes for a new realm are highlighted in bold.<p>
Source location: src/realms/webapps/WEB-INF/<br>
Deploy location: <war>/WEB-INF/
<pre>
<util:map id="realms">
<entry key="REALMA" value-ref="realmA"/>
<entry key="REALMB" value-ref="realmB"/>
<b><entry key="REALMC" value-ref="realmC"/></b>
</util:map>
<bean id="realmA" class="org.apache.cxf.sts.token.realm.SAMLRealm">
<property name="issuer" value="STS Realm A"/>
<property name="signaturePropertiesFile" value="stsKeystoreA.properties" />
<property name="callbackHandlerClass" value="org.apache.cxf.fediz.service.sts.PasswordCallbackHandler" />
</bean>
<bean id="realmB" class="org.apache.cxf.sts.token.realm.SAMLRealm">
<property name="issuer" value="STS Realm B"/>
<property name="signaturePropertiesFile" value="stsKeystoreB.properties" />
<property name="callbackHandlerClass" value="org.apache.cxf.fediz.service.sts.PasswordCallbackHandler" />
</bean>
<b>
<bean id="realmC" class="org.apache.cxf.sts.token.realm.SAMLRealm">
<property name="issuer" value="STS Realm C"/>
<property name="signaturePropertiesFile" value="stsKeystoreC.properties" />
<property name="callbackHandlerClass" value="org.apache.cxf.fediz.service.sts.PasswordCallbackHandler" />
</bean>
</b>
<util:list id="relationships">
<bean class="org.apache.cxf.sts.token.realm.Relationship">
<property name="sourceRealm" value="REALMA" />
<property name="targetRealm" value="REALMB"/>
<property name="identityMapper" ref="identityMapper" />
<property name="type" value="FederatedIdentity" />
</bean>
<bean class="org.apache.cxf.sts.token.realm.Relationship">
<property name="sourceRealm" value="REALMB" />
<property name="targetRealm" value="REALMA"/>
<property name="identityMapper" ref="identityMapper" />
<property name="type" value="FederatedIdentity" />
</bean>
<b>
<bean class="org.apache.cxf.sts.token.realm.Relationship">
<property name="sourceRealm" value="REALMA" />
<property name="targetRealm" value="REALMC"/>
<property name="identityMapper" ref="identityMapper" />
<property name="type" value="FederatedIdentity" />
</bean>
</b>
</util:list>
</pre>
In this case, only a trust relationship from realm A to realm C is established and it's based on identity mapping.
</li>
<li><b>Generate signing certificate</b><p>
The new realm signs the SAML assertion with a different signer certificate.
<pre>
keytool -genkeypair -keyalg RSA -validity 3600 -alias realmc -keystore stsrealm_c.jks -dname "cn=REALMC" -keypass realmc -storepass storepass
keytool -export -keystore stsrealm_c.jks -storepass storepass -export -alias realmc -file realmc.cert
</pre>
The keystore has to be added<br>
Source location: src/realms/resources<br>
Deploy location: <war>/WEB-INF/classes
</li>
<li><b>Import certificate into truststore <code>ststrust.jks</code></b><p>
The certificate must be added to the truststore thus another realm is able to validate the SAML assertion signed by realm C.
<p>
<i>Note: </i>The above federation relationship definitions do not cover the use case that another realm must trust realm C but I recommend to add the certificate for completeness reasons.
<pre>
keytool -import -trustcacerts -keystore ststrust.jks -storepass storepass -alias realmc -file realmc.cert -noprompt
</pre>
The truststore has to be updated at<br>
Source location: src/realms/resources<br>
Deploy location: <war>/WEB-INF/classes
</li>
<li><b>Configure signer certificate</b><p>
Above, the signer certificate is configured for the SAML Realm C in the attribute <code>signaturePropertiesFile</code> of the bean <code>realmC</code>. The properties file has to look like this:
<pre>
org.apache.ws.security.crypto.provider=org.apache.ws.security.components.crypto.Merlin
org.apache.ws.security.crypto.merlin.keystore.type=jks
org.apache.ws.security.crypto.merlin.keystore.password=storepass
org.apache.ws.security.crypto.merlin.keystore.alias=realmc
org.apache.ws.security.crypto.merlin.file=stsrealm_c.jks
</pre>
<i>Note: </i>Copy&paste an existing stsKeystore properties file.<p>
The properties file has to be added here:<br>
Source location: src/realms/resources<br>
Deploy location: <war>/WEB-INF/classes
</li>
<li><b>Define JAX-WS endpoint in STS</b><p>
Two JAX-WS endpoints are required depending on whether you need to support username/password authentication in the STS (WSDL Port <code>TransportUT_Port</code>) and/or issue a SAML token on-behalf-of another SAML token (WSDL Port <code>Transport_Port</code>).<p>
The former requires an authentication backend which is file based in the Fediz STS. The file based authentication backend relies on the <code>UsernamePasswordCallbackHandler</code> which uses a spring map with user name and password entries (see beans <code>upCallBackHandlerRealmC</code> and <code>REALMC</code>).
<pre>
<jaxws:endpoint id="<b>transportSTSRealmC</b>" implementor="#transportSTSProviderBean"
address="/<b>REALMC</b>/STSServiceTransport" wsdlLocation="/WEB-INF/wsdl/ws-trust-1.4-service.wsdl"
xmlns:ns1="http://docs.oasis-open.org/ws-sx/ws-trust/200512/"
serviceName="ns1:SecurityTokenService" endpointName="ns1:Transport_Port">
<jaxws:properties>
</jaxws:properties>
</jaxws:endpoint>
<jaxws:endpoint id="<b>transportSTSRealmCUT</b>" implementor="#transportSTSProviderBean"
address="/<b>REALMC</b>/STSServiceTransportUT" wsdlLocation="/WEB-INF/wsdl/ws-trust-1.4-service.wsdl"
xmlns:ns1="http://docs.oasis-open.org/ws-sx/ws-trust/200512/"
serviceName="ns1:SecurityTokenService" endpointName="ns1:TransportUT_Port">
<jaxws:properties>
<entry key="ws-security.callback-handler" value-ref="<b>upCallBackHandlerRealmC</b>" />
</jaxws:properties>
</jaxws:endpoint>
<bean id="upCallBackHandlerRealmC"
class="org.apache.cxf.fediz.service.sts.UsernamePasswordCallbackHandler">
<property name="passwords" ref="REALMC" />
</bean>
<util:map id="REALMC">
<entry key="user1"
value="pw1" />
</util:map>
</pre>
The bean which defines the username and passwords is defined in the imported spring configuration file <code>passwords.xml</code>. The claims of the users in the two realms are defined in <code>userClaims.xml</code>. You can find more information about managing the claims in an older <a href="http://owulff.blogspot.com/2011/10/configure-and-deploy-cxf-25-sts-part-i.html">blog</a>.
<p>
If you want to configure an LDAP backend check the following blog post:
<ul>
<li><a href="http://owulff.blogspot.com/2013/05/ldap-support-enhanced-for-cxf-sts-275.html">LDAP support enhanced in CXF 2.7.5</a></li>
<li><a href="http://owulff.blogspot.com/2011/10/configure-ldap-directory-for-cxf-sts.html">Configure LDAP backend in STS</a></li>
</ul>
</li>
<li><b>Identity mapper</b><p>
If you add a new realm, the Identity Mapper provided in <code>org.apache.cxf.fediz.service.sts.realms.IdentityMapperImpl</code> must be enhanced. In practise, you access a database, LDAP or web service to get the mapping. You must implement the interface <code>org.apache.cxf.sts.IdentityMapper</code> to customize the identity mapping to your needs.
</li>
</ul>
<h2>Customize realm concept</h2>
<ul>
<li>
The Fediz STS is based on the Apache CXF STS. The STS supports several realms where each realm is connected to an authentication server like LDAP, file (Testing), database or a custom authentication server. The service consumer must know from which STS realm he requests a token from by choosing the appropriate URL. The distinction is based on the syntax in the URL.
<p>
The syntax in the Fediz STS is <code>https://<fixed host>:<fixed port>/fediz-idp-sts/<REALM>/...</code>. The distinction is after the servlet context <code>fediz-idp-sts</code>. This behaviour is implemented in <code>org.apache.cxf.fediz.service.sts.realms.UriRealmParser</code> and configured in the bean <code>customRealmParser</code>.
<p>
You can implement a different distinction based on the machine name, http port or servlet context. Maybe you prefer to deploy the realms in different JVMs. You just have to implement the interface <code>org.apache.cxf.sts.RealmParser</code>.
</li>
<li>
When you request a token on-behalf-of another SAML token, the STS must be able to figure out from which realm the token has been issued. As above, the STS provides an interface which must be implement to change the default behaviour of the Fediz STS. The default behaviour is implemented in <code>org.apache.cxf.fediz.service.sts.realms.SamlRealmCodec</code> and expects the realm encoded in the CN (Common Name) of the signer certificate. This class implements the interface <code>org.apache.cxf.sts.token.realm.SAMLRealmCodec</code> and can be customized. You have to update the bean <code>samlRealmCodec</code> or update the bean which references this bean.
</li>
</ul>
<p>
Please post feedback and ideas to the <a href="http://cxf.apache.org/mailing-lists.html">CXF mailing list</a>.
<p>
Thank you for all support and feedback!Oliver Wulffhttp://www.blogger.com/profile/07294415212532150140noreply@blogger.com0tag:blogger.com,1999:blog-2816919410731663192.post-5586805364746673632013-05-21T15:00:00.000+02:002013-05-21T15:00:11.461+02:00Logging in Apache CXF STS enhanced<i>This extension will be available in CXF release 2.7.6 which is not yet available. But you can run tests with the SNAPSHOT build till this version is released. Please provide feedback to the <a href="http://cxf.apache.org/mailing-lists.html">CXF mailing list</a>.</i>
<p>
Different logging frameworks (SLF4J, Log4J, Logback, JUL) can be used to log events for Apache CXF STS. The configuration allows to define which logger should log messages till to which log level. That works fine to drill down generic issues but it doesn't help too much to know whether a certain user could successfully log in or had any specific issues. Further, the WS-Trust interface is very generic. Therefore, the same user can request tokens but for different applications using different credential types. If a log in error occurs some context information is required to easily drill down user specific issues.
<p>Based on the experience of a customer deployment, the following information is helpful to figure out how often a user requested a token and under which circumstances:
<ul>
<li>AppliesTo<br>For which application did the user request a token</li>
<li>Source IP<br>From which machine did the application request a token for a user</li>
<li>Claims<br>Which claims did the user request for an application</li>
<li>Security Header<br>How did the user try to log in (Username/password, Kerberos, X509, ...)</li>
<li>Realm<br>For which security domain did the user request a token</li>
<li>etc.</li>
</ul>
All this information are available within the core classes of the STS and thus not customizable without patching these classes. The next release of CXF will provide a customizable logging/auditing functionality to fulfill various requirements.
<h2>Spring Eventing</h2>
The Spring framework provides an eventing mechanism which is designed for simple communication between Spring beans. Instead of introducing a new eventing mechanism to push data to a class which processes the data and writes it to a log file the new feature leverages the usage of the Spring framework in the CXF STS. How Spring eventing works is described on the following <a href="http://learningviacode.blogspot.ch/2012/07/spring-and-events-and-listeners.html">blog</a>. If you don't want to delay STS related processing you can publish the events asynchronously which is described <a href="
http://learningviacode.blogspot.ch/2012/08/publishing-events-asynchronously.html">here</a>.
<h2>CXF STS custom Application Events</h2>
Depending on the STS operation called, a different object with context information is created in the CXF STS. The following table summarizes the defined bindings in the WS-Trust specification, the CXF related context object as well a link with more information about this binding:
<p>
<table border="1">
<tr><td><b><i>Binding</b></i></td><td><b><i>Context objcect</b></i></td><td><b><i>Spring Event</b></i></td><td><b><i>Documentation</b></i></td></tr>
<tr><td><i>Issue</i></td><td>TokenProviderParameters</td><td>STSIssueSuccessEvent<br>STSIssueFailureEvent</td><td><a href="http://coheigea.blogspot.ch/2011/10/apache-cxf-sts-documentation-part-iii.html">blog</a></td></tr>
<tr><td><i>Validate</i></td><td>TokenValidatorParameters</td><td>STSValidateSuccessEvent<br>STSValidateFailureEvent</td><td><a href="http://coheigea.blogspot.ch/2011/11/apache-cxf-sts-documentation-part-v.html">blog</a></td></tr>
<tr><td><i>Cancel</i></td><td>TokenCancellerParameters</td><td>STSCancelSuccessEvent<br>STSCancelFailureEvent</td><td><a href="http://coheigea.blogspot.ch/2011/11/apache-cxf-sts-documentation-part-vii.html">blog</a></td></tr>
<tr><td><i>Renew</i></td><td>TokenRenewerParameters</td><td>STSRenewSuccessEvent<br>STSRenewFailureEvent</td><td><a href="http://coheigea.blogspot.ch/2012/04/renewing-saml-tokens-in-apache-cxf-sts.html">blog</a></td></tr>
</table>
<p>
The different binding implementations support the interface <code>ApplicationEventPublisherAware</code> thus they can publish events about a successful or failed request. You have to provide an implementation of <code>ApplicationListener</code> to listen to Spring Application Events. Due to the usage of generics you can specify which events you want to listen to. All the above STS specific events inherit the abstract class <code>AbstractSTSEvent</code>. If you want to listen to all STS events then you must provide an implementation like this:
<pre>
public class AllSTSEventsListener implements ApplicationListener<AbstractSTSEvent> {
@Override
public void onApplicationEvent(AbstractSTSEvent event) {
// do whatever you want here
}
}
</pre>
If you want to listen to all successful issue events you must use the generic <code>STSIssueSuccessEvent</code>.
The STS provides the <code>LoggerListener</code> which listens to all STS events and uses the CXF Logging API to write the log message. All you have to do is configure the following bean in the STS application context configuration (ex. <code>cxf-transport.xml</code>):
<pre>
<bean id="loggerListener" class="org.apache.cxf.sts.event.LoggerListener" />
</pre>
<p>
If you want to configure another Application listeners, just add a bean configuration and you're done.
<p>
The <code>LoggerListener</code> is able to log the following context information:
<ul>
<li>TIME<br>Creation time of the event</li>
<li>OPERATION<br>STS binding/operation</li>
<li>WS_SEC_PRINCIPAL<br>Principal in WS-Security token</li>
<li>STATUS<br>Successful/failed request</li>
<li>DURATION<br>Processing time</li>
<li>TOKENTYPE<br>Token type requested (SAML 1.1, SAML 2.0, etc)</li>
<li>REALM<br>Security domain</li>
<li>APPLIESTO<br>Application for which token is requested</li>
<li>CLAIMS<br>Claims requested</li>
<li>ACTAS_PRINCIPAL<br>Principal of ActAs token</li>
<li>ONBEHALFOF_PRINCIPAL<br>Principal of On-Behalf-Of token</li>
<li>VALIDATE_PRINCIPAL<br>Principal of Validate token</li>
<li>CANCEL_PRINCIPAL<br>Principal of Cancel token</li>
<li>RENEW_PRINCIPAL<br>Principal of Renew token</li>
<li>REMOTE_HOST<br>Hostname/IP which requested the token</li>
<li>REMOTE_PORT<br>Source Port which requested the token</li>
<li>URL<br>STS URL used to request token</li>
</ul>
The <code>LoggerListener</code> provides the following properties to customize its behaviour:
<p>
<table border="1">
<tr><td><b><i>Name</b></i></td><td><b><i>Type</b></i></td><td><b><i>Mandatory</b></i></td><td><b><i>Default</b></i></td><td><b><i>Description</b></i></td></tr>
<tr><td><i>logFieldname</i></td><td>Boolean</td><td>No</td><td>No</td><td>Should the fieldname be logged, ex. OPERATION=issue</td></tr>
<tr><td><i>dateFormat</i></td><td>String</td><td>No</td><td>getDateTimeInstance(DateFormat.SHORT, DateFormat.MEDIUM)</td><td>Format of the date</td></tr>
<tr><td><i>logLevel</i></td><td>String</td><td>No</td><td>FINE</td><td>Which log level should be used?</td></tr>
<tr><td><i>logStacktrace</i></td><td>Boolean</td><td>No</td><td>No</td><td>In case of an error, shall the stacktrace be logged?</td></tr>
<tr><td><i>fieldOrder</i></td><td>List<String></td><td>No</td><td>TIME<br>STATUS<br>DURATION<br>REMOTE_HOST<br>REMOTE_PORT<br>OPERATION<br>URL<br>REALM<br>WS_SEC_PRINCIPAL<br>ONBEHALFOF_PRINCIPAL<br>ACTAS_PRINCIPAL<br>VALIDATE_PRINCIPAL<br>CANCEL_PRINCIPAL<br>RENEW_PRINCIPAL<br>TOKENTYPE<br>APPLIESTO<br>CLAIMS<br>EXCEPTION</td><td>Order of context fields to be logged</td></tr>
</table>
<p>
If you want that all LoggerListener related log messages are written into a different file (ex. audit.log) I highly recommend to not use Java Util Logging as it's not so easy to configure a dedicated handler/appender for one logger.
<ol>
<li>Configure Log4J as the logging framework in CXF (see <a href="http://cxf.apache.org/docs/debugging-and-logging.html#DebuggingandLogging-UsingLog4jInsteadofjava.util.logging">here</a>)</li>
<li>Add the log4j dependency to your POM</li>
<li>Configure the logger and appender<br>
<pre>
log4j.rootLogger=INFO, CONSOLE, LOGFILE
<b>log4j.logger.org.apache.cxf.sts.event.LoggerListener=DEBUG, AUDIT</b>
# CONSOLE is set to be a ConsoleAppender using a PatternLayout.
log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
log4j.appender.CONSOLE.Threshold=INFO
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
log4j.appender.CONSOLE.layout.ConversionPattern=%d [%t] %-5p %c %x - %m%n
# AUDIT is set to be a File appender using a PatternLayout.
<b>log4j.appender.AUDIT=org.apache.log4j.FileAppender</b>
log4j.appender.AUDIT.File=${catalina.base}/logs/audit.log
log4j.appender.AUDIT.Append=true
log4j.appender.AUDIT.Threshold=DEBUG
log4j.appender.AUDIT.layout=org.apache.log4j.PatternLayout
<b>log4j.appender.AUDIT.layout.ConversionPattern=%m%n</b>
</pre>
</li>
</ol>
The audit log file looks like this if configured as above:
<pre>
5/10/13 8:59:59 AM;SUCCESS;2839ms;127.0.0.1;57378;Issue;https://localhost:9443/fediz-idp-sts/STSService;null;alice;null;null;http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV2.0;https://localhost:8081/doubleit/services/doubleittransportsaml1claims;null;null;
</pre>
<p>
Enjoy.
Oliver Wulffhttp://www.blogger.com/profile/07294415212532150140noreply@blogger.com0tag:blogger.com,1999:blog-2816919410731663192.post-73686579263142173182013-05-14T22:45:00.001+02:002013-05-14T22:48:09.293+02:00LDAP support enhanced for CXF STS 2.7.5I described in a previous <a href="http://owulff.blogspot.ch/2011/10/configure-ldap-directory-for-cxf-sts.html">blog</a> how to configure the CXF STS for an LDAP directory for authentication and to retrieve user claims (attributes). The <a href="">new release 2.7.5</a> of CXF provides extended support for roles managed in a LDAP directory. In previous versions, the <code>LdapClaimsHandler</code> added groups as roles if the groups were assigned to a multi-value attribute of the user.
The new release provides an <code>LdapGroupClaimsHandler</code> which supports the case where an attribute of the groups lists the users who belong to this group. Further, it introduces the semantic of an application role. A user might have the role "User" for application X and role "Manager" and "User" for application Y.
<p>
The STS provides the semantic of an application with the AppliesTo parameter which is a URI. If you request a SAML token which includes the roles for a specific application (ex. MyApp), you get User and Manager back. A mapping is required in the STS to map the AppliesTo URI (URL or URN) to a String value like MyApp.
<p>
The sub-project <a href="http://cxf.apache.org/fediz.html">Fediz</a> provides in 1.1 (not released yet) a Maven profile to build the STS with an LDAP backend (instead of managing users/claims in a file). You can have a look at the <code>ldap.xml</code><a href="http://svn.apache.org/viewvc/cxf/fediz/trunk/services/sts/src/main/webapp/WEB-INF/ldap.xml?view=markup">here</a>.
The following configuration configures the <code>LdapClaimsHandler</code> and <code>LdapGroupClaimsHandler</code>. There is nothing special for the LdapClaimsHandler. The LdapGroupClaimsHandler also uses the Spring <code>LdapContextSource</code> and <code>LdapTemplate</code>.
<pre>
<util:list id="claimHandlerList">
<ref bean="userClaimsHandler" />
<ref bean="<b>groupClaimsHandler</b>" />
</util:list>
<bean id="contextSource" class="org.springframework.ldap.core.support.LdapContextSource">
<property name="url" value="ldap://localhost:389/" />
<property name="userDn" value="uid=admin,ou=system" />
<property name="password" value="secret" />
</bean>
<bean id="ldapTemplate" class="org.springframework.ldap.core.LdapTemplate">
<constructor-arg ref="contextSource" />
</bean>
<util:map id="claimsToLdapAttributeMapping">
<entry key="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname"
value="givenName" />
<entry key="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/surname"
value="sn" />
<entry key="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress"
value="mail" />
<entry key="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/country"
value="c" />
<entry key="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/postalcode"
value="postalCode" />
<entry key="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/streetaddress"
value="postalAddress" />
<entry key="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/locality"
value="town" />
<entry key="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/stateorprovince"
value="st" />
<entry key="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/gender"
value="gender" />
<entry key="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/dateofbirth"
value="dateofbirth" />
<entry key="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/role"
value="member" />
</util:map>
<bean id="userClaimsHandler" class="org.apache.cxf.sts.claims.LdapClaimsHandler">
<property name="ldapTemplate" ref="ldapTemplate" />
<property name="claimsLdapAttributeMapping" ref="claimsToLdapAttributeMapping" />
<property name="userBaseDN" value="ou=users,dc=fediz,dc=org" />
<property name="userNameAttribute" value="uid" />
</bean>
<util:map id="<b>appliesToScopeMapping</b>">
<entry key="urn:org:apache:cxf:fediz:fedizhelloworld"
value="Example" />
</util:map>
<bean id="<b>groupClaimsHandler</b>" class="org.apache.cxf.sts.claims.LdapGroupClaimsHandler">
<property name="ldapTemplate" ref="ldapTemplate" />
<property name="userBaseDN" value="ou=users,dc=fediz,dc=org" />
<property name="userNameAttribute" value="uid" />
<property name="groupBaseDN" value="ou=groups,dc=fediz,dc=org" />
<property name="appliesToScopeMapping" ref="appliesToScopeMapping" />
</bean>
<jaxws:endpoint id="transportSTS1" implementor="#transportSTSProviderBean"
address="/STSService" wsdlLocation="/WEB-INF/wsdl/ws-trust-1.4-service.wsdl"
xmlns:ns1="http://docs.oasis-open.org/ws-sx/ws-trust/200512/"
serviceName="ns1:SecurityTokenService" endpointName="ns1:TransportUT_Port">
<jaxws:properties>
<entry key="ws-security.ut.validator">
<bean class="org.apache.ws.security.validate.JAASUsernameTokenValidator">
<property name="contextName" value="LDAP" />
</bean>
</entry>
</jaxws:properties>
</jaxws:endpoint>
</pre>
I've highlighted the important beans to support the mapping of groups to (application) roles. The bean <b>LdapGroupClaimsHandler</b> has got the following attributes:
<p>
<table border="1">
<tr><td><b><i>Name</b></i></td><td><b><i>Mandatory</b></i></td><td><b><i>Default</b></i></td><td><b><i>Description</b></i></td></tr>
<tr><td><i>ldapTemplate</i></td><td>Yes</td><td>N.A.</td><td>The Spring LDAP template</td></tr>
<tr><td><i>groupBaseDN</i></td><td>Yes</td><td>N.A.</td><td>The base group context where the search starts</td></tr>
<tr><td><i>groupObjectClass</i></td><td>No</td><td>groupOfNames</td><td>Object class for groups. Used for search filter.</td></tr>
<tr><td><i>groupMemeberAttribute</i></td><td>No</td><td>member</td><td>The group attribute where the list of users are stored</td></tr>
<tr><td><i>groupURI</i></td><td>No</td><td>http://schemas.xmlsoap.org/ws/2005/05/identity/claims/role</td><td>The SAML attribute name where the roles should be stored</td></tr>
<tr><td><i>groupNameGlobalFilter</i></td><td>No</td><td>ROLE</td><td>Default uses the CN of the group as role name</td></tr>
<tr><td><i>groupNameScopedFilter</i></td><td>No</td><td>SCOPE_ROLE</td><td>Default cuts the SCOPE and the underscore of the CN of the group</td></tr>
<tr><td><i>appliesToScopeMapping</i></td><td>No</td><td>N.A.</td><td>The mapping is required if application specific roles must be supported</td></tr>
<tr><td><i>userNameAttribute</i></td><td>No</td><td>cn</td><td>User id attribute. Only required if LDAP is not used for authentication and thus the DN of the user must be resolved first. Used for search filter.</td></tr>
<tr><td><i>userObjectClass</i></td><td>No</td><td>person</td><td>Object class for users. Only required if LDAP is not used for authentication and thus the DN of the user must be resolved first. Used for search filter.</td></tr>
</table>
<p>
The bean <b>appliesToScopeMapping</b> defines the mapping of the URI in the AppliesTo variable to a Name as URI's are not valid within a CN of an LDAP group.
<p>
One example for the usage of <code>groupNameScopedFilter</code>. One more example. Let's assume you use the same LDAP directory for the application environemnt <i>development</i> and <i>pre-production</i> and defines the following naming convention for application roles:<br><code>DEV_<Application>_<ROLE>_Group</code> and <code>UAT_<Application>_<ROLE>_Group</code>
The groupNameScopedFilter will look like this <code>DEV_SCOPE_ROLE_Group</code> (assumption: Different STS instances are deployed for development and pre-production).
<p>
The following table lists a few group examples and how the role value will look like in the SAML attribute. The assumption is that the AppliesTo element is <code>urn:org:apache:cxf:fediz:fedizhelloworld</code> which maps to the scope <code>Example</code> (see configuration example above) and the <code>groupNameScopedFilter</code> is configured like <code>DEV_SCOPE_ROLE_Group</code>:
<p>
<table>
<tr><td><b><i>Group CN</b></i></td><td><b><i>Role name</b></i></td></tr>
<tr><td>DEV_Example_User_Group</td><td>User</td></tr>
<tr><td>DEV_Example_Admin_Group</td><td>Admin</td></tr>
<tr><td>DEV_Example2_User_Group</td><td><i>ignored</i></td></tr>
<tr><td>UAT_Example_User_Group</td><td><i>ignored</i></td></tr>
<tr><td>INFR_Citrix_Access</td><td><i>ignored</i></td></tr>
</table>
<p>
Last but not least I'd like to comment the default value of <code>userNameAttribute</code> which is <code>CN</code>. As per <a href="">recommendation (5.4)</a> the CN is typically the person's fullname and therefore doesn't fit for the user id (login name). Due to the reason that the LdapClaimsHandler had the cn as default value I wanted to keep that in sync and change it in the next non-patch release of CXF.
<p>
If you face issues or like more functionality send a message to the <a href="http://cxf.apache.org/mailing-lists.html">CXF mailing list</a> or open a <a href="https://issues.apache.org/jira/browse/CXF">JIRA issue</a>.
Oliver Wulffhttp://www.blogger.com/profile/07294415212532150140noreply@blogger.com0tag:blogger.com,1999:blog-2816919410731663192.post-82336173332361435182013-04-22T13:39:00.002+02:002013-04-22T13:39:41.811+02:00Full Spring Security Support in Apache CXF Fediz<h3>Full Spring Security Support in Apache CXF Fediz</h3>
<p>
New features are going to be added in the next version 1.1 of Fediz. I described <a href="http://owulff.blogspot.ch/2013/02/spring-security-support-added-in-apache.html">here</a> how to configure the new Fediz plugin for Spring Security with Container Managed Security (Pre-Authentication in Spring Security terms). The current snapshot version of Fediz 1.1 provides also full/native Spring Security support which means the Servlet Container runs unauthenticated (no security constraints defined in web.xml) and Spring Security enforces authentication.
<p>
You can either download the sources here:<p>
<code>
git clone git://git.apache.org/cxf-fediz.git
</code>
<p>or<p>
<code>
svn co https://svn.apache.org/repos/asf/cxf/fediz/trunk
</code>
<p>
or download it from the <a href="https://repository.apache.org/content/groups/snapshots/org/apache/cxf/fediz/">snapshot</a> maven repository.
<p>
<p>A new example <b>springWebapp</b> has been added to the distribution to show this.</p>
As in the Pre-Authentication case, the application can get access to the Spring Security Context like this:
<code>
SecurityContextHolder.getContext().getAuthentication();
</code>
The Authentication object is of instance <code>FederationAuthenticationToken</code> provides the following methods.<p></p>
<table border="1">
<tr><td>Method</td><td>Class</td><td>Description</td></tr>
<tr><td>getCredentials</td><td>Element</td><td>Issues Security Token (ex. SAML Assertion)</td></tr>
<tr><td>getDetails</td><td>WebAuthenticationDetails</td>><td>Authentication details like IP, Session ID</td></tr>
<tr><td>getName</td><td>String</td><td>Authenticated user name</td></tr>
<tr><td>getAuthorities</td><td>Collection<? extends GrantedAuthority></td><td>List of roles</td></tr>
<tr><td>getUserDetails</td><td>FederationUser</td><td>Extends the standard Spring User class with method getClaims()</td></tr>
</table>
<p>
You can get more information from the <a href="http://cxf.apache.org/fediz-spring.html">Fediz Wiki</a> how to configure Spring Security or have a look at the example <a href="https://svn.apache.org/repos/asf/cxf/fediz/trunk/examples/springWebapp/">here</a>. The example shows how to <a href="https://svn.apache.org/repos/asf/cxf/fediz/trunk/examples/springWebapp/src/main/webapp/WEB-INF/applicationContext-security.xml">configure Fediz</a> for Spring Security and how to use the Spring Security API in your <a href="https://svn.apache.org/repos/asf/cxf/fediz/trunk/examples/springWebapp/src/main/java/org/apache/cxf/fediz/example/FederationServlet.java">application code</a>.
Please post feedback and ideas to the <a href="http://cxf.apache.org/mailing-lists.html">CXF mailing list</a> or the JIRA task <a href="https://issues.apache.org/jira/browse/FEDIZ-39">FEDIZ-39</a>.
<p>
Apache CXF <a href="http://cxf.apache.org/fediz.html">Fediz</a> is a subproject of Apache <a href="http://cxf.apache.org/">CXF</a>. Fediz helps you to secure your web applications and delegate security enforcement to the underlying application server. With Fediz, authentication is externalized from your web application to an identity provider installed as a dedicated server component. The supported standard is <a href="http://docs.oasis-open.org/wsfed/federation/v1.2/os/ws-federation-1.2-spec-os.html">WS-Federation</a> Passive Requestor Profile.
<p>
Thank you for all support and feedback!Oliver Wulffhttp://www.blogger.com/profile/07294415212532150140noreply@blogger.com4tag:blogger.com,1999:blog-2816919410731663192.post-9093412557444997352013-03-04T15:27:00.000+01:002013-03-04T15:27:10.738+01:00SSO and Fine Grained Authorization in the CloudIn February 2013, I was at <a href="http://na.apachecon.com/">ApacheCon NA 2013</a> in Portland, Oregon, US where I learned a lot about several Apache projects.
<p>
My presentation was about <b>SSO and Fine Grained Authorization in the Cloud</b>. I gave an introduction about application security 10-15 years ago and how to address challanges with Cloud deployment using <a href="http://cxf.apache.org/fediz.html">Apache CXF Fediz</a>.
<p>
Here are the slides from my talk:
<p>
<iframe src="http://de.slideshare.net/slideshow/embed_code/16919281" width="427" height="356" frameborder="0" marginwidth="0" marginheight="0" scrolling="no" style="border:1px solid #CCC;border-width:1px 1px 0;margin-bottom:5px" allowfullscreen webkitallowfullscreen mozallowfullscreen> </iframe> <div style="margin-bottom:5px"> <strong> <a href="http://de.slideshare.net/OliverWulff/apachecon-2013-sso-and-fine-grained-authorization-in-the-cloud" title="ApacheCon 2013 SSO and Fine Grained Authorization in the Cloud" target="_blank">ApacheCon 2013 SSO and Fine Grained Authorization in the Cloud</a> </strong> from <strong><a href="http://de.slideshare.net/OliverWulff" target="_blank">Oliver Wulff</a></strong> </div>
<p>
Oliver Wulffhttp://www.blogger.com/profile/07294415212532150140noreply@blogger.com0tag:blogger.com,1999:blog-2816919410731663192.post-6913098995881127282013-02-13T21:35:00.000+01:002013-02-13T21:35:11.052+01:00Spring Security support added in Apache CXF Fediz<h3>Initial support for Spring Security in Apache CXF Fediz added</h3>
<p>
New features are going to be added in the next version 1.1. The next feature ready for testing is the support for <a href="http://static.springsource.org/spring-security/site/">Spring Security</a> for version 3.1
<p>
You can either download the sources here:<p>
<code>
git clone git://git.apache.org/cxf-fediz.git
</code>
<p>or<p>
<code>
svn co https://svn.apache.org/repos/asf/cxf/fediz/trunk
</code>
<p>
or download it from the <a href="https://repository.apache.org/content/groups/snapshots/org/apache/cxf/fediz/">snapshot</a> maven repository.
<p>
The Fediz Spring Plugin supports integration with the Spring Pre-Authentication scenario as described <a href="http://static.springsource.org/spring-security/site/docs/3.2.x/reference/preauth.html">here</a>.
<p>A new example <b>springPreauthWebapp</b> has been added to the distribution to show this.</p>
I'd like to highlight two things.
<p>
1) You can get access to the Spring Security Context like this:
<code>
SecurityContextHolder.getContext().getAuthentication();
</code>
The Authentication interfaces provides the following methods.
<p>
<table border="1">
<tr><td>Method</td><td>Class</td><td>Description</td></tr>
<tr><td>getCredentials</td><td>Element</td><td>Issues Security Token (ex. SAML Assertion)</td></tr>
<tr><td>getDetails</td><td>PreAuthenticatedGrantedAuthoritiesWebAuthenticationDetails</td>><td>Authentication details like IP, Session ID</td></tr>
<tr><td>getName</td><td>String</td><td>Authenticated user name</td></tr>
<tr><td>getAuthorities</td><td>Collection<? extends GrantedAuthority></td><td>List of roles</td></tr>
<tr><td>getPrincipal</td><td>FederationUser</td><td>Extends the standard Spring User class with method getClaims()</td></tr>
</table>
<p>
Here is an example where the information of the Authentication object is logged:
<p>
<code>
getCredentials: [saml2:Assertion: null]
getDetails: org.springframework.security.web.authentication.preauth.PreAuthenticatedGrantedAuthoritiesWebAuthenticationDetails@1c07a: RemoteIpAddress: 127.0.0.1; SessionId: go3xw6sxzqr5w02gn85elfgv; [ROLE_USER]
getName: alice
getAuthorities: [ROLE_USER]
getPrincipal: org.apache.cxf.fediz.spring.FederationUser@5899680: Username: alice; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; credentialsNonExpired: true; AccountNonLocked: true; Granted Authorities: ROLE_USER
</code>
<p>
2) You can define rules who can access which resource as illustrated in the following snippet of applicationContext-security.xml of the new example <b>springPreauthWebapp</b>
<code>
<bean id="fsi" class="org.springframework.security.web.access.intercept.FilterSecurityInterceptor">
<property name="authenticationManager" ref="authenticationManager"/>
<property name="accessDecisionManager" ref="httpRequestAccessDecisionManager"/>
<property name="securityMetadataSource">
<sec:filter-invocation-definition-source>
<sec:intercept-url pattern="/secure/manager/**" access="ROLE_MANAGER"/>
<sec:intercept-url pattern="/secure/admin/**" access="ROLE_ADMIN"/>
<sec:intercept-url pattern="/secure/user/**" access="ROLE_USER,ROLE_ADMIN,ROLE_MANAGER"/>
<sec:intercept-url pattern="/secure/fedservlet" access="ROLE_USER,ROLE_ADMIN,ROLE_MANAGER,ROLE_AUTHENTICATED"/>
</sec:filter-invocation-definition-source>
</property>
</bean>
</code>
Please post feedback and ideas to the <a href="http://cxf.apache.org/mailing-lists.html">CXF mailing list</a> or the JIRA task <a href="https://issues.apache.org/jira/browse/FEDIZ-38">FEDIZ-38</a> and <a href="https://issues.apache.org/jira/browse/FEDIZ-39">FEDIZ-39</a>.
<p>
Apache CXF <a href="http://cxf.apache.org/fediz.html">Fediz</a> is a subproject of Apache <a href="http://cxf.apache.org/">CXF</a>. Fediz helps you to secure your web applications and delegate security enforcement to the underlying application server. With Fediz, authentication is externalized from your web application to an identity provider installed as a dedicated server component. The supported standard is <a href="http://docs.oasis-open.org/wsfed/federation/v1.2/os/ws-federation-1.2-spec-os.html">WS-Federation</a> Passive Requestor Profile.
<p>
Thank you for all support and feedback!Oliver Wulffhttp://www.blogger.com/profile/07294415212532150140noreply@blogger.com5tag:blogger.com,1999:blog-2816919410731663192.post-46569404652301625572012-11-26T20:51:00.000+01:002013-01-20T19:59:43.924+01:00Jetty support added in Apache CXF Fediz<h3>Initial support for Jetty in Apache CXF Fediz added</h3>
<p>
Apache CXF <a href="http://cxf.apache.org/fediz.html">Fediz</a> is a subproject of Apache <a href="http://cxf.apache.org/">CXF</a>. Fediz helps you to secure your web applications and delegate security enforcement to the underlying application server. With Fediz, authentication is externalized from your web application to an identity provider installed as a dedicated server component. The supported standard is <a href="http://docs.oasis-open.org/wsfed/federation/v1.2/os/ws-federation-1.2-spec-os.html">WS-Federation</a> Passive Requestor Profile.
<p>
Fediz 1.0.2 supports the following <b>features</b>:
<ul>
<li>WS-Federation 1.0/1.1/1.2</li>
<li>SAML 1.1/2.0 Tokens</li>
<li>Custom token support</li>
<li>Publish WS-Federation Metadata document</li>
<li>Role information encoded as AttributeStatement in SAML 1.1/2.0 tokens</li>
<li>Claims information provided by FederationPrincipal interface</li>
</ul>
<p>
New features are going to be added in the next version 1.1. The first feature ready for testing is the support for the Open Source Servlet Container <a href="http://wiki.eclipse.org/Jetty/">Jetty</a> for version 7 and 8.
<p>
You can either download the sources here:<p>
<code>
git clone git://git.apache.org/cxf-fediz.git
</code>
<p>or<p>
<code>
svn co https://svn.apache.org/repos/asf/cxf/fediz/trunk
</code>
<p>
or download it from the <a href="https://repository.apache.org/content/groups/snapshots/org/apache/cxf/fediz/">snapshot</a> maven repository.
<p>
As Jetty can easily be embedded in your application you might be interested to look at the <a href="http://svn.apache.org/viewvc/cxf/fediz/trunk/plugins/jetty/src/test/java/org/apache/cxf/fediz/jetty/BrowserTest.java?view=markup">Unit test</a> for the Jetty module how to configure the FederationAuthenticator.
If you download the Jetty distribution the configuration for Fediz is described <a href="http://cxf.apache.org/fediz-jetty.html">here</a>.
Please post feedback and ideas to the <a href="http://cxf.apache.org/mailing-lists.html">CXF mailing list</a> or the <a href="https://issues.apache.org/jira/browse/FEDIZ-5">Jira task FEDIZ-5</a>.
<p>
Thank you for all support and feedback!Oliver Wulffhttp://www.blogger.com/profile/07294415212532150140noreply@blogger.com0tag:blogger.com,1999:blog-2816919410731663192.post-39357825129121802612012-07-31T10:03:00.000+02:002012-07-31T10:03:28.453+02:00Add End-To-End monitoring to Your CXF application with Open SourceThis is the second blog I mentioned <a href="http://owulff.blogspot.ch/2012/07/add-failover-and-load-balancing-to-your.html">here</a>.
<p>
I'd like to show how to add <b>end-to-end monitoring</b> to your CXF based applications. End-to-end monitoring means that you can follow the message flow which has been triggered by a user across several web services nodes (consumer/provider). Context information of a message and its content are pushed by every web service node to a central server component. The communication style is asynchronous to not delay message processing.
<p>
To show how this can be achieved I'll also use the example <i>wsclientWebapp</i> of the Apache CXF <a href="http://cxf.apache.org/fediz.html">Fediz</a> project which I already used to illustrate how to add load balancing and failover. Further information is available <a href="http://owulff.blogspot.ch/2012/07/add-failover-and-load-balancing-to-your.html">here</a>.
<p>
This example already supports Web SSO (IDP), WS-Security and STS. The architecture is described in a previous <a href="http://owulff.blogspot.ch/2012/04/sso-across-web-applications-and-web.html">blog</a>.
<p>
A web appliation is federation enabled with Fediz to support SSO. As part of the login of the browser user, a SAML token is issued which contains the claims information which are relevant to the web application. The web application calls a web service on behalf of the logged in user. This is accomplished by the CXF STS which is shipped as part of the Fediz in the <a href="https://cwiki.apache.org/CXF/fediz-idp.html">IDP/STS</a> component. The Web Service Consumer (Web Application) requests a new token based on the WS-SecurityPolicy of the Web Service Provider on behalfof of the security token issued as part of the Web Login. In this example, the security tokens are SAML tokens.
<p>
More information on how to build, deploy and test the demo are described in the <a href="http://svn.apache.org/repos/asf/cxf/fediz/trunk/examples/wsclientWebapp/README.txt">README</a>.
<p>
This example has the following gaps to be deployed in a distributed environment:
<ul>
<li>URL's of the web service provider is configured on the service consumer side which is difficult to manage across the environments and for all web service consumers</li>
<li>If an error occurs you have to analyze log files of all involved nodes in the message flow to drill down the root cause of the issue. Usually, the log files of all involved applications are distributed in the network. It's difficult to correlate the messages in the different log files.</li>
</ul>
These issues might be manageable within the scope of a project but not on the enterprise level as your application might consume several services which are used by other applications as well. As mentioned at the beginning, the first gap is addressed in the <a href="http://owulff.blogspot.ch/2012/07/add-failover-and-load-balancing-to-your.html">previous blog</a>. This blog will address how to add end-to-end monitoring.
<p>
Talend built Apache licensed open source components to add load balancing, failover and end-to-end monitoring to your CXF/Camel based applications. This blog shows you how easily you can integrate this component into your application.
<p>
<h2>Update your CXF application</h2>
Talend built a SAM (Service Activity Monitoring) server component where service participants (consumer/provider) can send information about incoming and outgoing messages. The SAM server is Apache licensed. Besides the server component, the SAM agent is deployed as part of the CXF application which hooks into the interceptor chain to collect all required information about the message and pushes it to the SAM server asynchronously.
<p>
<i>What do you have to do in your application?</i>
<p>
<b>A) Web Service Provider</b>
<p>
Make the following changes in the maven project <code>wsclientWebapp/webservice/service</code>
<p>
1) add POM dependency for the Talend SAM agent library
<p>
This library hooks into the CXF interceptor chain to send service activity information to the SAM server.
<pre>
<dependency>
<groupId>org.talend.esb</groupId>
<artifactId>sam-agent</artifactId>
<version>5.1.1</version>
</dependency>
</pre>
2) add a file <code>agent.properties</code> to your maven project <code>src/main/resources</code>
<p>
This file contains information where the SAM agent is running and what kind of information should be sent.
<pre>
collector.scheduler.interval=500
collector.maxEventsPerCall=10
collector.lifecycleEvent=false
log.messageContent=true
log.maxContentLength=-1
log.enforceMessageIDTransfer=false
service.url=http://localhost:8040/services/MonitoringServiceSOAP
service.retry.number=3
service.retry.delay=5000
</pre>
3) Update Spring configuration file <code>applicationContext.xml</code>
<p>
The highlighted lines must be added to the example application.
<pre>
...
<import resource="classpath:META-INF/cxf/cxf.xml" />
<import resource="classpath:META-INF/tesb/locator/beans.xml" />
<b><import resource="classpath:META-INF/tesb/agent-context.xml" /> </b>
...
<!-- GreeterService -->
<jaxws:endpoint id="GreeterService"
implementor="org.apache.cxf.fediz.examples.service.GreeterImpl"
wsdlLocation="WEB-INF/wsdl/hello_world.wsdl"
serviceName="svc:GreeterService"
xmlns:svc="http://apache.org/hello_world_soap_http"
address="/GreeterService">
<jaxws:properties>
<entry key="ws-security.signature.properties" value="stsKeystore.properties" />
<entry key="org.talend.tesb.endpoint.secured" value="true"/>
</jaxws:properties>
<!-- Talend feature -->
<jaxws:features>
<bean class="org.talend.esb.servicelocator.cxf.LocatorFeature" />
<b><ref bean="eventFeature"/></b>
</jaxws:features>
</jaxws:endpoint>
</pre>
4) Run "mvn clean install"
<p>
Maven builds a new WAR package. This package is now able to send service activity information to the SAM server.
<p>
<b>B) Web Service Consumer</b>
<p>
Make the following changes in the maven project <code>wsclientWebapp/webapp</code>
<p>
1) add POM dependency for the Talend SAM agent library
<p>
This library hooks into the CXF interceptor chain to send service activity information to the SAM server.
<pre>
<dependency>
<groupId>org.talend.esb</groupId>
<artifactId>sam-agent</artifactId>
<version>5.1.1</version>
</dependency>
</pre>
2) add a file <code>agent.properties</code> to your maven project <code>src/main/resources</code>
<p>
This file contains information where the SAM agent is running and what kind of information should be sent.
<pre>
collector.scheduler.interval=500
collector.maxEventsPerCall=10
collector.lifecycleEvent=false
log.messageContent=true
log.maxContentLength=-1
log.enforceMessageIDTransfer=false
service.url=http://localhost:8040/services/MonitoringServiceSOAP
service.retry.number=3
service.retry.delay=5000
</pre>
There are different options to configure what kind of information should be pushed to the SAM server. Please check the <a href="http://www.talend.com/download.php#ESB">Talend_ESB_InfrastructureServices</a> manual for all configuration options like:
<ul>
<li>Send message content</li>
<li>Configure maximum length of content to be sent</li>
<li>filters to find/replace in message content</li>
<li>add custom context information</li>
<li>...</li>
</ul>
3) Update Spring configuration file <code>applicationContext.xml</code>
<p>
The highlighted lines must be added to the example application.
<pre>
...
<import resource="classpath:META-INF/cxf/cxf.xml" />
<import resource="classpath:META-INF/tesb/locator/beans.xml" />
<b><import resource="classpath:META-INF/tesb/agent-context.xml" /> </b>
...
<jaxws:client id="HelloServiceClient" serviceName="svc:GreeterService"
xmlns:svc="http://apache.org/hello_world_soap_http"
serviceClass="org.apache.hello_world_soap_http.Greeter"
address="locator://whatever"
wsdlLocation="WEB-INF/wsdl/hello_world.wsdl">
<jaxws:properties>
<entry key="ws-security.sts.client">
<bean class="org.apache.cxf.ws.security.trust.STSClient">
<constructor-arg ref="cxf" />
<property name="wsdlLocation" value="https://localhost:9443/fedizidpsts/STSServiceTransport?wsdl" />
<property name="serviceName"
value="{http://docs.oasis-open.org/ws-sx/ws-trust/200512/}SecurityTokenService" />
<property name="endpointName"
value="{http://docs.oasis-open.org/ws-sx/ws-trust/200512/}Transport_Port" />
<property name="onBehalfOf" ref="delegationCallbackHandler" />
<property name="enableAppliesTo" value="true" />
</bean>
</entry>
<entry key="ws-security.cache.issued.token.in.endpoint" value="false" />
</jaxws:properties>
<jaxws:features>
<bean class="org.talend.esb.servicelocator.cxf.LocatorFeature" />
<b><ref bean="eventFeature"/></b>
</jaxws:features>
</jaxws:client>
</pre>
4) Run "mvn clean install"
<p>
Maven builds a new WAR package. This package is now able to send service activity information to the SAM server.
<h2>Deploy SAM server</h2>
Last but not least, the Talend SAM server must be deployed and started which is shipped as part of the Talend ESB.
Follow these steps to start the SAM server (if you have run already the demo for the Service Locator you only have to run <code>tesb:start-all</code>):
<ol>
<li>Download the Talend ESB Standard Edition (SE) <a href="">here</a>. The Standard Edition has full functionality and is Apache licensed.</li>
<li>Unzip the file</li>
<li>Run <code><install-dir>/container/trun</code></li>
<li>Execute the following command in the console<p>
<code>tesb:start-all</code></li>
<li>You can log the most recent logs with the command<p>
<code>log:display</code>
</ol>
<p>
The SAM server (and Service Locator) are running now.
<p>
More information about the Talend ESB is available here:
<ul>
<li><a href="http://www.talend.com/download.php#ESB">Software and documentation</a></li>
<li><a href="http://www.talend.com/webinar/archive/index.php#anchor_esb">Webinars</a></li>
<li><a href="http://www.talend.com/library/reflibrary.php#Application_Integration">Whitepapers, etc.</a></li>
</ul>
<h2>Test the application</h2>
You can test the application as described in the <a href="http://svn.apache.org/repos/asf/cxf/fediz/trunk/examples/wsclientWebapp/README.txt">README</a> of the Fediz example <i>wsclientWebapp</i>.
<p>Enter the URL <code>https://localhost:8443/fedizhelloworld/secure/service.jsp</code> and click on the button <i>Call Service</i> after login (User: alice, Password: ecila). This triggers a web service call.
<p>
You will also see that messages are sent to the SAM server from the service consumer and service provider:
<pre>
...
Jul 5, 2012 11:21:09 PM org.talend.esb.sam.agent.collector.EventCollector sendEvents
INFO: Put events(2) to Monitoring Server.
...
</pre>
<p>
You can use any DB Visualizer Tool to show the data of the messages exchanged in the web services network. In this example, the data is written to Apache Derby.
<p>You find more information where this DB is located in <a href="http://www.talend.com/download.php#ESB">Talend_ESB_InfrastructureServices</a> in chapter 4.3.
<p>
This is not a very nice UI to see which messages are part of a flow triggered by a user. In my next blog I'll describe the Talend Administration Console (TAC) which allows to see the messages exchanged and the registered service in a graphical way.
<p>
<i><b>This blog showed how easy it is to add end-to-end monitoring capabilities to your CXF application with open source components and without changing a single line of code.</b></i>Oliver Wulffhttp://www.blogger.com/profile/07294415212532150140noreply@blogger.com0tag:blogger.com,1999:blog-2816919410731663192.post-74715976697477825252012-07-12T22:07:00.000+02:002012-07-12T22:20:59.842+02:00Add Failover and Load balancing to Your CXF application with Open SourceIn the next blogs I'd like to describe how easy it is to add other enterprise features to your existing CXF based applications. My previous blogs were always very focused on security. The enterprise features I'd like to talk are:
<ul>
<li>load-balancing</li>
<li>failover</li>
<li>end-to-end monitoring</li>
</ul>
In this blog, I'll address <b>load-balancing</b> and <b>failover</b> whereas end-to-end monitoring is addressed in the next blog.
<p>
The assumption is that the web services are deployed on several machines. You want to either load balance the requests among the deployed services dynamically or failover in case a service is not reachable anymore.
<p>
To show how this can be implemented I'll use the example <i>wsclientWebapp</i> of the Apache CXF <a href="http://cxf.apache.org/fediz.html">Fediz</a> project which has been <a href="http://owulff.blogspot.ch/2012/07/apache-cxf-fediz.html">released</a> recently.
<p>
This example already supports Web SSO (IDP), WS-Security and STS. The architecture is described in a previous <a href="http://owulff.blogspot.ch/2012/04/sso-across-web-applications-and-web.html">blog</a>. More information on how to build, deploy and test the <i>wsclientWebapp</i> example are described in its <a href="http://svn.apache.org/repos/asf/cxf/fediz/trunk/examples/wsclientWebapp/README.txt">README</a>.
<p>
This example has the following gaps to be deployed in a distributed environment:
<ul>
<li>URL's of the web service is configured on the service consumer side which is difficult to manage across the environments and for all web service consumers</li>
<li>If an error occurs you have to analyze log files to drill down the root cause of the issue. Usually, the log files of all involved applications are distributed in the network. It's difficult to correlate the messages in the different log files.</li>
</ul>
These issues might be manageable within the scope of a project but not on the enterprise level as your application might consume several services which are used by other applications as well. As mentioned at the beginning, the second gap will be addressed by implementing end-to-end monitoring which is described in the next blog.
<p>
Talend built Apache licensed open source components which address the previously mentioned gaps and add load balancing and failover capabilities to your CXF application.
<p>
<p>
<h2>Update your CXF application</h2>
Service Providers register its endpoints (URL) at the <b>Talend Service Locator</b> and service consumer can lookup for an service endpoint (compare to DNS or UDDI). The Service Locator is Apache licensed and re-uses other proven open source projects like <a href="http://zookeeper.apache.org/">Zookeeper</a>. Besides the server component, the CXF Failover/Clustering feature has been extended to integrate with the Service Locator.
<p>
<i>What do you have to do in your application?</i>
<p>
<b>A) Web Service Provider</b>
<p>
Make the following changes in the maven project <code>wsclientWebapp/webservice/service</code>
<p>
1) add POM dependency to Talend Locator library
<p>
This library hooks into the CXF Failover/Load Balancing functionality to integrate with the Service Locator server.
<pre>
<dependency>
<groupId>org.talend.esb</groupId>
<artifactId>locator</artifactId>
<version>5.1.1</version>
</dependency>
</pre>
<p>
2) add a file <code>locator.properties</code> to your maven project <code>src/main/resources</code>
<p>
This file contains information where the Service Locator server is running.
<pre>
# Configured zookeeper instances (divided by a comma if several instances uses).
# The service locator client will pick an instance
# to connect to the service locator until a connection is established.
locator.endpoints=localhost:2181
# Endpoint prefix property is needed because the services
# in a container where the endpoints
# are relative to the container.
endpoint.https.prefix=https://localhost:10443/fedizservice
connection.timeout=5000
session.timeout=5000
</pre>
3) Update Spring configuration file <code>applicationContext.xml</code>
<p>
The highlighted lines must be added to the example application.
<pre>
...
<import resource="classpath:META-INF/cxf/cxf.xml" />
<b><import resource="classpath:META-INF/tesb/locator/beans.xml" /></b>
...
<!-- GreeterService -->
<jaxws:endpoint id="GreeterService"
implementor="org.apache.cxf.fediz.examples.service.GreeterImpl"
wsdlLocation="WEB-INF/wsdl/hello_world.wsdl"
serviceName="svc:GreeterService"
xmlns:svc="http://apache.org/hello_world_soap_http"
address="/GreeterService">
<jaxws:properties>
<entry key="ws-security.signature.properties" value="stsKeystore.properties" />
<b><entry key="org.talend.tesb.endpoint.secured" value="true"/></b>
</jaxws:properties>
<!-- Talend feature -->
<jaxws:features>
<b><bean class="org.talend.esb.servicelocator.cxf.LocatorFeature" /></b>
</jaxws:features>
</jaxws:endpoint>
</pre>
4) Run "mvn clean install"
<p>
Maven builds a new WAR package. This package is now able to register its endpoint at the service locator.
<p>
<b>B) Web Service Consumer</b>
<p>
Make the following changes in the maven project <code>wsclientWebapp/webapp</code>
<p>
1) add POM dependency to Talend Locator library
<p>
This library hooks into the CXF Failover/Load Balancing functionality to integrate with the Service Locator server.
<p>Some transitive dependencies have to be excluded as they are already part of the fediz package which is available in the parent classloader of tomcat.
<pre>
<dependency>
<groupId>org.talend.esb</groupId>
<artifactId>locator</artifactId>
<version>5.1.1</version>
<exclusions>
<exclusion>
<artifactId>xmlsec</artifactId>
<groupId>org.apache.santuario</groupId>
</exclusion>
<exclusion>
<artifactId>wss4j</artifactId>
<groupId>org.apache.ws.security</groupId>
</exclusion>
<exclusion>
<artifactId>ehcache-core</artifactId>
<groupId>net.sf.ehcache</groupId>
</exclusion>
</exclusions>
</dependency>
</pre>
2) add a file <code>locator.properties</code> to your maven project <code>src/main/resources</code>
<p>
This file contains the network address where the Service Locator server is running.
<pre>
# Configured zookeeper instances (divided by a comma if several instances uses).
# The service locator client will pick an instance
# to connect to the service locator until a connection is established.
locator.endpoints=localhost:2181
connection.timeout=5000
session.timeout=5000
</pre>
There are different options to configure the cache of endpoints. Please check the <a href="http://www.talend.com/download.php#ESB">Talend_ESB_InfrastructureServices</a> manual for all configuration options.
<p>
3) Update Spring configuration file <code>applicationContext.xml</code>
<p>
The highlighted lines must be added to the example application.
<pre>
...
<import resource="classpath:META-INF/cxf/cxf.xml" />
<b><import resource="classpath:META-INF/tesb/locator/beans.xml" /></b>
...
<jaxws:client id="HelloServiceClient" serviceName="svc:GreeterService"
xmlns:svc="http://apache.org/hello_world_soap_http"
serviceClass="org.apache.hello_world_soap_http.Greeter"
address="locator://whatever"
wsdlLocation="WEB-INF/wsdl/hello_world.wsdl">
<jaxws:properties>
<entry key="ws-security.sts.client">
<bean class="org.apache.cxf.ws.security.trust.STSClient">
<constructor-arg ref="cxf" />
<property name="wsdlLocation" value="https://localhost:9443/fedizidpsts/STSServiceTransport?wsdl" />
<property name="serviceName"
value="{http://docs.oasis-open.org/ws-sx/ws-trust/200512/}SecurityTokenService" />
<property name="endpointName"
value="{http://docs.oasis-open.org/ws-sx/ws-trust/200512/}Transport_Port" />
<property name="onBehalfOf" ref="delegationCallbackHandler" />
<property name="enableAppliesTo" value="true" />
</bean>
</entry>
<entry key="ws-security.cache.issued.token.in.endpoint" value="false" />
</jaxws:properties>
<jaxws:features>
<b><bean class="org.talend.esb.servicelocator.cxf.LocatorFeature" /></b>
</jaxws:features>
</jaxws:client>
</pre>
4) Run "mvn clean install"
<p>
Maven builds a new WAR package. This package is now able to lookup the endpoint at the service locator.
<p>
<p>
<i>
You can also apply the following <a href="https://docs.google.com/open?id=0B39bWm6JgpkfcHpJYzRNakJ2QXM">patch</a> to the sources of the fediz example which enables the integration with the Talend Service Locator.
</i>
<h2>Deploy Service Locator</h2>
Last but not least, the Talend Service Locator must be deployed and started which is shipped as part of the Talend ESB.
Follow these steps to start the Service Locator:
<ol>
<li>Download the Talend ESB Standard Edition (SE) <a href="">here</a>. The Standard Edition is Apache licensed.</li>
<li>Unzip the file</li>
<li>Run <code><install-dir>/container/trun</code></li>
<li>Execute the following command in the console<p>
<code>tesb:start-all</code></li>
<li>You can log the most recent logs with the command<p>
<code>log:display</code>
</ol>
<p>
The Service Locator is running now.
<p>
More information about the Talend ESB is available here:
<ul>
<li><a href="http://www.talend.com/download.php#ESB">Software and documentation</a></li>
<li><a href="http://www.talend.com/webinar/archive/index.php#anchor_esb">Webinars</a></li>
<li><a href="http://www.talend.com/library/reflibrary.php#Application_Integration">Whitepapers, etc.</a></li>
</ul>
<h2>Test the application</h2>
You can test the application as described in the <a href="http://svn.apache.org/repos/asf/cxf/fediz/trunk/examples/wsclientWebapp/README.txt">README</a> of the Fediz example <i>wsclientWebapp</i>.
<p>Enter the URL <code>https://localhost:8443/fedizhelloworld/secure/service.jsp</code> and click on the button <i>Call Service</i> after login (User: alice, Password: ecila). This triggers a web service call where the web service consumer will lookup the service provider URL at the Talend Service Locator (and caches this information). You will see log statements like this:
<pre>
...
Jul 5, 2012 11:21:08 PM org.apache.cxf.clustering.FailoverTargetSelector setStrategy
INFO: Using failover strategy org.talend.esb.servicelocator.cxf.internal.EvenDistributionSelectionStrategy@9235c2
Jul 5, 2012 11:21:08 PM org.talend.esb.servicelocator.cxf.internal.LocatorClientEnabler enable
INFO: Client enabled with strategy org.talend.esb.servicelocator.cxf.internal.EvenDistributionSelectionStrategy.
Jul 5, 2012 11:21:08 PM org.talend.esb.servicelocator.cxf.internal.LocatorTargetSelector prepare
INFO: Found address with locator protocol, mapping it to physical address.
Jul 5, 2012 11:21:08 PM org.talend.esb.servicelocator.cxf.internal.LocatorTargetSelector prepare
INFO: Using strategy org.talend.esb.servicelocator.cxf.internal.EvenDistributionSelectionStrategy.
Jul 5, 2012 11:21:08 PM org.talend.esb.servicelocator.cxf.internal.ReloadSelectionStrategy getPrimaryAddress
INFO: Get address for service {http://apache.org/hello_world_soap_http}GreeterService using strategy org.talend.esb.servicelocator.cxf.internal.EvenDistributionSelectionStrategy selecting from [https://localhost:10443/fedizservice/GreeterService] selected = https://localhost:10443/fedizservice/GreeterService
...
</pre>
We removed the endpoint URL <code>https://localhost:10443/fedizservice/GreeterService</code> in the configuration of the service consumer. Instead a lookup at the Service Locator resolves this URL.
<h2>How can you see which services are registered at the Service Locator</h2>
You can use the Zookeeper Client shipped with the Talend ESB to access the Service Locator (Zookeeper Service) which is illustrated next:
<pre>
/projects/talend/TESB_SE-V5.1.1/zookeeper/bin$ ./zkCli.sh
[zk: localhost:2181(CONNECTED) 0] ls /
[cxf-locator, zookeeper]
[zk: localhost:2181(CONNECTED) 1] ls /cxf-locator
[{http:%2F%2Fapache.org%2Fhello_world_soap_http}GreeterService]
[zk: localhost:2181(CONNECTED) 2] ls /cxf-locator/{http:%2F%2Fapache.org%2Fhello_world_soap_http}GreeterService
[https:%2F%2Flocalhost:10443%2Ffedizservice%2FGreeterService]
[zk: localhost:2181(CONNECTED) 3]
</pre>
<p>
This is not a very nice UI to see the registered services. After the blog about End-to-End monitoring I'll describe the Talend Administration Console (TAC) which allows to see the registered service and the messages exchanged in a graphical way.
<p>
<i><b>This blog showed how easy it is to add failover and load-balancing capabilities to your CXF application with open source components and without changing a single line of code. I very much like the approach convention over configuration.</b></i>Oliver Wulffhttp://www.blogger.com/profile/07294415212532150140noreply@blogger.com3tag:blogger.com,1999:blog-2816919410731663192.post-31873031748565880292012-07-02T08:12:00.001+02:002012-07-02T08:12:06.173+02:00Apache CXF Fediz<h3>First release of Apache CXF Fediz available</h3>
<p>
Apache CXF <a href="http://cxf.apache.org/fediz.html">Fediz</a> is a subproject of Apache <a href="http://cxf.apache.org/">CXF</a>. Fediz helps you to secure your web applications and delegate security enforcement to the underlying application server. With Fediz, authentication is externalized from your web application to an identity provider installed as a dedicated server component. The supported standard is <a href="http://docs.oasis-open.org/wsfed/federation/v1.2/os/ws-federation-1.2-spec-os.html">WS-Federation</a> Passive Requestor Profile.
<p>
Fediz supports Claims Based Access Control beyond Role Based Access Control (RBAC).
<p>
Fediz supports the following <b>features</b>:
<ul>
<li>WS-Federation 1.0/1.1/1.2</li>
<li>SAML 1.1/2.0 Tokens</li>
<li>Custom token support</li>
<li>Publish WS-Federation Metadata document</li>
<li>Role information encoded as AttributeStatement in SAML 1.1/2.0 tokens</li>
<li>Claims information provided by FederationPrincipal interface</li>
</ul>
<p>
Release notes are available <a href="http://cxf.apache.org/fediz-100-release-notes.html">here</a>.
<p>
For more information see:
<ul>
<li>
Download: <a href="http://cxf.apache.org/fediz-downloads.html">http://cxf.apache.org/fediz-downloads.html</a></li>
<li>
Website: <a href="http://cxf.apache.org/fediz.html">http://cxf.apache.org/fediz.html</a></li>
<li>
Mailing lists: <a href="http://cxf.apache.org/mailing-lists.html">http://cxf.apache.org/mailing-lists.html</a></li>
</ul>
<br>
Features to come in the upcoming releases:
<ul>
<li>
Fediz IDP supports RP IDP use case
</li>
<li>
SAML Holder-Of-Key support
</li>
<li>
Support for encrypted SAML tokens
</li>
<li>
Support for Jetty Container
</li>
<li>
Integration with Spring Security
</li>
<li>
Integration with CXF JAX-RS
</li>
<li>
SAML-P support
</li>
</ul>
Feel free to raise enhancement requests and issues <a href="https://issues.apache.org/jira/browse/FEDIZ">here</a>
<p>
Thank you for all support and feedback!Oliver Wulffhttp://www.blogger.com/profile/07294415212532150140noreply@blogger.com2tag:blogger.com,1999:blog-2816919410731663192.post-6062231394726690282012-04-16T14:21:00.000+02:002012-07-04T07:52:40.947+02:00SSO across Web Applications and Web Services - Part IV bThis blog describes how to implement the solution described in my previous <a href="http://owulff.blogspot.com/2012/04/sso-across-web-applications-and-web.html">blog</a> which you must have read before.<br />
<p>I'd like to structure the blog into the following sections:<br />
<ul><li><a href="#first">Extend the STS to support Issue requests OnBehalfOf without authenticating the requesting party</a></li>
<li><a href="#second">Protect the Web Services provider using SAML 2.0</a></li>
<li><a href="#third">Integrate Web SSO and the Web Services stack in the Web Application</a></li>
</ul><br />
<p>I've prepared this demo to run the different components in three tomcat instances. The reason is to get closer to a real scenario.<br />
<ol><li><b>tomcat-idp</b><br />
<p>This tomcat instance hosts the security infrastructure components which are the IDP and the STS.<p>HTTPS: 9443, HTTP: 9080</li>
<li><b>tomcat-rp</b><br />
<p>This tomcat instance hosts the Web Application.<p>HTTPS: 8443, HTTP: 8080</li>
<li><b>tomcat-svc</b><br />
<p>This tomcat instance hosts the Web Services provider which is usually not hosted on the same instance as the frontend.<p>HTTPS: 10443, HTTP: 10080</li>
</ol>All three tomcat instances use the same certificate <code>tomcatkeystore.jks</code>for HTTPS which can be downloaded <a href="https://docs.google.com/open?id=0B39bWm6JgpkfM2Y5NmVkMzEtM2Q5OS00ZTcyLWFkYTItOWZmZGJjNjZkOWZm">here</a>.<br />
<br />
The Tomcat HTTPS connector is configured in <code>conf/server.xml</code>. Deploy the <code>tomcatkeystore.jks</code> of the example project to the Tomcat root directory if the Connector is configured as illustrated:<br />
<pre> <Connector port="<b>10443</b>" protocol="HTTP/1.1"
SSLEnabled="true"
maxThreads="150" scheme="https" secure="true"
keystoreFile="tomcatKeystore.jks"
keystorePass="tompass" sslProtocol="TLS"
/>
</pre><a name="first"></a><br />
<h3>Extend the STS...</h3><p>We use the same STS instance prepared for the Web SSO. The initial set up of this STS is described in my first blog. You can find the updated sources <a href="http://svn.apache.org/viewvc/cxf/fediz/trunk/services/sts/">here</a>.<br />
<p>The previous STS supported only one policy which says the communication with the STS must be secured on the transport level using HTTPS (TransportBinding) and UsernameToken is used as a "SupportingToken".<br />
<p>We have to configure a new policy which supports the TransportBinding but doesn't enforce a UsernameToken (SupportingToken assertion is missing). The new policy is added to the wsdl file <code>ws-trust-1.4-service.wsdl</code>.<br />
<em><br />
Right now, everybody who gets into the possession of a signed SAML token could request a new security token from the STS. This risk is mitigated using HTTPS (You could authenticate the requestor also who requests a token on behalf of someone else).<br />
</em><br />
<br />
The new endpoint is configured in <code>WEB-INF/cxf-transport.xml</code> as illustrated here:<br />
<pre><jaxws:endpoint id="transportSTS2"
implementor="#transportSTSProviderBean"
address="/STSServiceTransport"
wsdlLocation="/WEB-INF/wsdl/ws-trust-1.4-service.wsdl"
xmlns:ns1="http://docs.oasis-open.org/ws-sx/ws-trust/200512/"
serviceName="ns1:SecurityTokenService"
endpointName="ns1:Transport_Port">
</jaxws:endpoint>
</pre>You can see all updates <a href="http://svn.apache.org/viewvc?view=revision&revision=1325637">here</a>.<br />
<br />
<a name="second"></a><br />
<h3>Protect the Web Services provider...</h3><br />
The Web Service provider is a new component. You can find the sources of this example <a href="http://svn.apache.org/viewvc/cxf/fediz/trunk/examples/wsclientWebapp/webservice/">here</a>. It supports a basic Web Services operation called "greetMe" with no input parameters but one output parameter. The response contains the authenticated user id which is retrieved from the JAX-WS WebServiceContext. In this use case, the authenticated user id must be the same as the one used by the browser user when login to the Web Application.<br />
<p>The following code snippet shows the implementation of the operation <i>greetMe</i>:<br />
<br />
<pre>@Resource
WebServiceContext context = null;
public String greetMe() {
LOG.info("Executing operation greetMe");
System.out.println("Executing operation greetMe");
if (context == null) {
return "Unknown user";
}
else {
Principal p = context.getUserPrincipal();
if (p == null) {
return "Principal null";
}
return p.getName();
}
}
</pre><br />
The WSDL of the service provider contains a WS-SecurityPolicy which defines that:<br />
<ul><li>HTTPS must be used</li>
<li>a SAML token must be sent issued by an STS</li>
<li>the SAML token is a SupportingToken</li>
</ul><pre><sp:TransportBinding
xmlns:sp="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702">
<wsp:Policy>
<sp:TransportToken>
<wsp:Policy>
<sp:HttpsToken RequireClientCertificate="false" />
</wsp:Policy>
</sp:TransportToken>
...
</wsp:Policy>
</sp:TransportBinding>
<sp:SupportingTokens
xmlns:sp="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702">
<wsp:Policy>
<sp:IssuedToken
sp:IncludeToken="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702/IncludeToken/AlwaysToRecipient">
<sp:RequestSecurityTokenTemplate>
<t:TokenType>http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV2.0</t:TokenType>
<t:KeyType>http://docs.oasis-open.org/ws-sx/ws-trust/200512/Bearer</t:KeyType>
</sp:RequestSecurityTokenTemplate>
...
</sp:IssuedToken>
</wsp:Policy>
</sp:SupportingTokens>
</pre><p>The service provider trusts an STS which means that it accepts every SAML token which has been signed/issued by its trusted STS. This trust is established based on the certificate (<code>stsstore.jks</code>) which must be configured in the service provider in the JAX-WS property <code>ws-security.signature.properties</code>.<br />
<pre><jaxws:endpoint id="GreeterService"
implementor="org.apache.cxf.fediz.examples.service.GreeterImpl"
wsdlLocation="WEB-INF/wsdl/hello_world.wsdl"
serviceName="svc:GreeterService"
xmlns:svc="http://apache.org/hello_world_soap_http"
address="/GreeterService">
<jaxws:properties>
<entry key="ws-security.signature.properties" value="stsKeystore.properties" />
</jaxws:properties>
</jaxws:endpoint>
</pre><br />
You must ensure to add the Maven dependencies for security and policy because the policy engine is not initialized otherwise.<br />
<pre><dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-ws-policy</artifactId>
<version>${cxf.version}</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-ws-security</artifactId>
<version>${cxf.version}</version>
</dependency>
</pre><p>The demo is prepared to deploy the Web Service to Tomcat instance <b>tomcat-svc</b> using Maven.<br />
<p>You don't have to change the tomcat URL if you have set up a Tomcat instance with HTTP port 10080 and HTTPS port 10443. Otherwise you must update the tomcat plugin in the POM:<br />
<pre><plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>tomcat-maven-plugin</artifactId>
<version>1.1</version>
<configuration>
<server>myTomcat</server>
<url>http://localhost:10080/manager</url>
<path>/${project.build.finalName}</path>
</configuration>
</plugin>
</pre><p>Add the server with username and password to your Maven settings.xml<br />
Ensure that this user has the role "manager-script" in Tomcat as described <a href="http://tomcat.apache.org/tomcat-7.0-doc/manager-howto.html#Configuring_Manager_Application_Access">here</a><br />
<p>Run... <pre>mvn clean install tomcat:redeploy</pre><i>I recommend to use redeploy as deploy works the first time only</i> <br />
<p>You can download the published WSDL with the following url:<br />
https://localhost:10443/fedizservice/GreeterService?wsdl<br />
<br />
<a name="third"></a><br />
<h3>Integrate the Web SSO and Web Services stack...</h3><p>The Web Application <code>fediz-tomcat-example</code> has been extended and slightly changed. You can find the new version <a href="http://svn.apache.org/viewvc/cxf/fediz/trunk/examples/wsclientWebapp/webapp/">here</a>. A key change is the URL used to access the FederationServlet.<br />
old: https://localhost:8443/fedizhelloworld/secureservlet/fed<br />
new: https://localhost:8443/fedizhelloworld/secure/fedservlet<br />
<p>A simple JSP page has been added which shows the authenticated user and provides a button to call the Web Service. The Web Services is protected by the WS-SecurityPolicy which enforces a SAML token issued by its trusted STS. If the call was successfull a similar page is shown as for the federation servlet but it shows the response of the Web Services provider. The response contains the authenticated username which must be the same as the one for the authenticated user in the Web Application.<br />
<p>The following code snippet shows the code used to call the service provider securely. The JAX-WS proxy is instantiated by Spring and thus just read from the ApplicationContext.<br />
<pre>Greeter service = (Greeter)ApplicationContextProvider.getContext().getBean("HelloServiceClient");
String reply = service.greetMe();
out.println("<br><b>Greeter Service Response: " + reply + "</b><p>");
</pre>There is no security related code required.<br />
<p>The spring configuration <code>beans.xml</code> contains the bean configuration for the service consumer:<br />
<pre><jaxws:client id="HelloServiceClient" serviceName="svc:GreeterService"
xmlns:svc="http://apache.org/hello_world_soap_http"
serviceClass="org.apache.hello_world_soap_http.Greeter"
address="https://localhost:10443/fedizservice/GreeterService"
wsdlLocation="WEB-INF/wsdl/hello_world.wsdl">
<jaxws:properties>
<entry key="ws-security.sts.client">
<bean class="org.apache.cxf.ws.security.trust.STSClient">
<constructor-arg ref="cxf" />
<property name="wsdlLocation" value="https://localhost:9443/fedizidpsts/STSServiceTransport?wsdl" />
<property name="serviceName"
value="{http://docs.oasis-open.org/ws-sx/ws-trust/200512/}SecurityTokenService" />
<property name="endpointName"
value="{http://docs.oasis-open.org/ws-sx/ws-trust/200512/}Transport_Port" />
<property name="onBehalfOf" ref="delegationCallbackHandler" />
<property name="enableAppliesTo" value="true" />
</bean>
</entry>
<entry key="ws-security.cache.issued.token.in.endpoint" value="false" />
</jaxws:properties>
</jaxws:client>
<bean id="delegationCallbackHandler" class="org.apache.cxf.fediz.example.ThreadLocalCallbackHandler" />
</pre><p>The Web Application must have access to the WSDL which includes the WS-SecurityPolicy assertion. Either you have deployed this WSDL within your Web Application (see configuration <code>wsdlLocation</code> attribute) or you download it from the service provider at runtime (see configuration for <code>wsdlLocation</code> of the <code>ws-security.sts.client</code>). The SecurityPolicy contains an IssuedToken assertion which indicates CXF to call the STS to request a token. The STS configuration is shown above where the STSClient bean is configured at entry <code>ws-security.sts.client</code>.<br />
<p>The information in the SecurityPolicy element <code>RequestSecurityTokenTemplate</code> are added to the <code>SecondaryParameters</code> element in the request to the STS. The service consumer doesn't care about its content. Our example looks like this:<br />
<pre><sp:RequestSecurityTokenTemplate>
<t:TokenType>http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV2.0</t:TokenType>
<t:KeyType>http://docs.oasis-open.org/ws-sx/ws-trust/200512/Bearer</t:KeyType>
</sp:RequestSecurityTokenTemplate>
</pre><br />
You can find more information about the correlation of STS parameters and SAML tokens <a href="http://owulff.blogspot.com/2012/02/saml-tokens-and-ws-trust-security-token.html">here</a>.<br />
<p><em>If you have deployed the service provider to a Tomcat instance with another port than 10443 you must update the attribute <code>address</code> of the bean <code>jaxws:client</code>.<br />
</em><br />
<p>The key thing to <b>bridge Web SSO and Web Services stack CXF</b> is the property <code>onbehalfof</code> in the STSClient bean configuration. This property references a Java <b>CallbackHandler</b> implementation which provides the on-behalf-of token as a DOM element. More information about the CallbackHandler for onbehalfof can be found <a href="http://coheigea.blogspot.com/2011/08/ws-trust-14-support-in-cxf.html">here</a>.<br />
CXF ships some out-of-the-box CallbackHandler implementations. This demo provides a custom CallbackHandler implementation called <code>ThreadLocalCallbackHandler</code> which provides the SAML token which has been issued by the IDP/STS during the Web login. The following additional classes are required:<br />
<ul><li>SecurityTokenThreadLocal<p>This is the thread local which contains the SAML token as a DOM element. The <code>ThreadLocalCallbackHandler</code> gets the SAML token from this class.</li>
<li>FederationFilter<p>This servlet filter reads the SAML token from the session and adds it to SecurityTokenThreadLocal and cleans it after request processing finished</li>
</ul>You must also ensure to add the Maven dependencies for security and policy because the policy engine is not initialized otherwise.<br />
<pre><dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-ws-policy</artifactId>
<version>${cxf.version}</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-ws-security</artifactId>
<version>${cxf.version}</version>
</dependency>
</pre><p>You can deploy this demo with Maven to Tomcat instance <b>tomcat-rp</b> in the same way as for the service provider described above.<br />
<p>You got a bunch of information in the last two blogs and I'd say a great example to illustrate how to SSO enable your Web Applications and Web Services with only a few open source components.
<p><b>Update: </b>This example is part of the <a href="http://owulff.blogspot.ch/2012/07/apache-cxf-fediz.html">Fediz</a> distribution.Oliver Wulffhttp://www.blogger.com/profile/07294415212532150140noreply@blogger.com6tag:blogger.com,1999:blog-2816919410731663192.post-27954483755685896142012-04-12T16:50:00.012+02:002012-04-16T18:30:23.209+02:00SSO across Web Applications and Web Services - Part IV aAs promised in my first <a href="http://owulff.blogspot.com/2011/10/configure-and-deploy-cxf-25-sts-part-i.html">blog</a> I talk now about Part IV where an Single Sign On (SSO) enabled Web Application integrates with Web Services in the back office. I've splitted this topic into two blogs. This one describes the design of the solution and the next one describes how to implement it.<br />
<p>This is a list of requirements for this application:<br />
<ul><li>Web Application must be SSO enabled using WS-Federation</li>
<li>Role Based Access Control (RBAC) required for Web Application</li>
<li>users are managed in an LDAP directory</li>
<li>security solution integrated without programming</li>
<li>industry standards should be used (WS-SecurityPolicy, Servlet- and JAX-WS Security API)</li>
<li>Web Services are secured with SAML 2.0 to authenticate the browser user</li>
<li>Web Services trust a WS-Trust Security Token Service (STS)</li>
<li>SAML token for authentication only (SupportingToken, WS-SecurityPolicy)</li>
<li>RBAC might be required for Web services in a future release</li>
<li>Confidentiality and Integrity on transport level (HTTPS)</li>
<li>prevent man-in-the-middle attack</li>
</ul><p>You might think this are a bunch of very sophisticated requirements and will cost a lot of money to implement. The answer is no. In this blog I'll introduce the architecture and design and in the next blog how to realize that with <a href="http://cxf.apache.org">Apache CXF</a> and Tomcat.<br />
<br />
<p>The following diagram illustrate the overall architecture:<br />
<div class="separator" style="clear: both; text-align: center;"><a href="http://4.bp.blogspot.com/-QEoPdRhGzWk/T4bslkO5miI/AAAAAAAAADs/vQV7Cc_VH20/s1600/sso.png" imageanchor="1" style="margin-left:1em; margin-right:1em"><img border="0" src="http://4.bp.blogspot.com/-QEoPdRhGzWk/T4bslkO5miI/AAAAAAAAADs/vQV7Cc_VH20/s400/sso.png" /></a></div><br />
<p>The key components are the WS-Trust Security Token Service (STS) and the Identity Provider (IDP) which is part of the WS-Federation Passive Requestor Profile. If you are familiar with my previous blogs about Web SSO...<br />
<ul><li><a href="http://owulff.blogspot.com/2011/10/configure-and-deploy-identity-provider.html">IDP</a></li>
<li><a href="http://owulff.blogspot.com/2011/11/configure-tomcat-for-federation-part.html">Enable federation in Tomcat</a></li>
</ul>... there are no new infrastructure components required to integrate SSO with Web Services. Because the STS is used for both Web SSO and Web Services Security.<br />
<p>The sequence of steps can be splitted into two parts the <b>Web login</b> and the <b>security for the Web Services</b>.<br />
The <b>Web login</b> starts when the user access the Web Application the first time. The Web Application redirects the browser to the IDP for authentication. The IDP transforms and delegates the request to the STS. The STS validates the user against the LDAP directory and issues a signed SAML token. The browser posts the SAML token to the Web Application which validates the token and creates the security context. This part is described in more details in the above mentioned blogs.<br />
<p>Role information can be accessed using standard security constraints in web.xml or using the Java Servlet API without worrying about the underlying SAML security token or accessing the LDAP directory explicitly.<br />
<p>The second part is the <b>security for Web Services</b> when the user does a step in the application which requires a call to a Web Services. The Web Services stack processes the WS-SecurityPolicy of the service provider where it is described to send a token issued by the STS. The Web Services stack sends an Issue request to the STS on behalf of the browser user. The STS validates the incoming credentials and issues the requested signed SAML token for the target Web Service. The Web Services stack caches the token and attachs it to the outgoing Web Services call. The service provider trusts the STS and can therefore validate the signed SAML token on its own.<br />
<p>I'd like to describe the second request to the STS in more details where the Web Services stack requests a token <b>on behalf of</b> the browser user. You must be in the possession of the credentials (ex. password) to request a token for the browser user - otherwise, anybody could request a token for someone else without knowing the passwort using a took like SOAPUI. The Web Application itself doesn't know the password because the authentication is externalized to the IDP. Even if the authentication had been done by the Web Application the password wouldn't have been cached by the application server for security reasons. OK, you don't possess the password but you got the signed SAML token which you can only get if you provided the credentials to the STS initially. This token must be protected on the wire when exchanged between browser and IDP, the browser and the Web Application and the Web Application and the STS. The option with the best performance is SSL/TLS.<br />
<em>For further confidentiality protection you could encrypt the token with the certificate of the application thus only the application is able to process the token. This is a supported feature of the CXF STS.</em><br />
<p>The <b>SAML token is cached</b> by the application server and is <b>provided to the Web Services stack</b> to request a new token when required. This use case is covered by the WS-Trust specification with the OnBehalfOf element (or ActAs) in the request to the STS. The STS validates the SAML token in the OnBehalfOf element and issues a new token based on the requirements of the Web Services which are described in its WS-SecurityPolicy document and send to the STS in the <b>SecondaryParameters</b> element.<br />
<p>There are some service calls before a request is sent to the service provider. The request to the STS is the most expensive as it might require to access some ID stores to read user attributes, roles (so called claims) to add it to the SAML token. Usually, a security token has some sort of lifetime either described in the security token itself (SAML condition) or some out-of-band agreement and known by the STS only. The WS-Trust specifiction defines the Lifetime element in the response to tell the token requestor the lifetime in a security token agnostic way. Thus, the Web Services stack just have to cache the returned security token (XML element) and the LifeTime element to prevent sending an issue request for every outgoing Web Service call.<br />
<p>Going through the requirements above... the solution above covers all of them.<br />
<p>How to <b>implement</b> this <b>solution</b> is described <a href="http://owulff.blogspot.com/2012/04/sso-across-web-applications-and-web_16.html"><b>here</b></a>Oliver Wulffhttp://www.blogger.com/profile/07294415212532150140noreply@blogger.com4tag:blogger.com,1999:blog-2816919410731663192.post-84297030786097313272012-03-08T21:44:00.000+01:002012-03-08T21:44:08.950+01:00Packaged Tomcat Instances for Federation/SSO<p>I've created a ZIP archive which contains two tomcat setups for the replying party (secured web application) and the identity provider (IDP). It's much easier to start with this approach and make the experience how easily a web application can be SSO enabled using SAML tokens according to the Passive Requestor Profile of WS-Federation specification.<br />
</p><p>You can download the package <a href="https://docs.google.com/open?id=0B39bWm6JgpkfMDZDVkFZemdTX202YlVWM2xMUjEwdw">here.</a><br />
</p><h3>Installation</h3><p>Unzip the downloaded archive which contains in each sub-directory a dedicated tomcat instance. The two tomcat instances are described below.<br />
</p><br />
<b>tomcat-idp</b><br />
<p>Start the Tomcat container:<br />
<code>tomcat-idp/bin/startup.sh</code> (or startup.bat for windows)<br />
<code><br />
Mar 8, 2012 8:59:13 PM org.apache.coyote.AbstractProtocol start<br />
INFO: Starting ProtocolHandler ["http-bio-9080"]<br />
Mar 8, 2012 8:59:13 PM org.apache.coyote.AbstractProtocol start<br />
INFO: Starting ProtocolHandler ["http-bio-9443"]<br />
Mar 8, 2012 8:59:13 PM org.apache.catalina.startup.Catalina start<br />
INFO: Server startup in 4245 ms<br />
</code><br />
</p><p>The Tomcat IDP instance creates an HTTPS listener (9443) and HTTP listener (9080). The insecure port is used for remote deployment during the maven build.<br />
</p><p>This tomcat instance has got two WAR files deployed: <b>fedizidp</b> and <b>fedizidpsts</b>.<br />
You can find more information how to build and deploy the corresponding package here:<br />
<ul><li><a href="http://owulff.blogspot.com/2011/10/configure-and-deploy-cxf-25-sts-part-i.html">fedizidpsts</a></li>
<li><a href="http://owulff.blogspot.com/2011/10/configure-and-deploy-identity-provider.html">fedizidp</a></li>
</ul></p><br />
<b>tomcat-rp</b><br />
<p>start the Tomcat container:<br />
<code>tomcat-rp/bin/startup.sh</code> (or startup.bat for windows)<br />
<code><br />
Mar 8, 2012 9:00:05 PM org.apache.coyote.AbstractProtocol start<br />
INFO: Starting ProtocolHandler ["http-bio-8080"]<br />
Mar 8, 2012 9:00:05 PM org.apache.coyote.AbstractProtocol start<br />
INFO: Starting ProtocolHandler ["http-bio-8443"]<br />
Mar 8, 2012 9:00:05 PM org.apache.catalina.startup.Catalina start<br />
INFO: Server startup in 2840 ms<br />
</code><br />
</p><p>The Tomcat RP instance creates an HTTPS listener (8443) and HTTP listener (8080). The insecure port is used for remote deployment during the maven build.<br />
</p><p>This tomcat instance has got one WAR file deployed: <b>fedizhelloworld</b><br />
You can find more information how to build and deploy the package here:<br />
<ul><li><a href="http://owulff.blogspot.com/2011/11/configure-tomcat-for-federation-part.html">fedizhelloworld</a></li>
</ul></p><br><br />
<h3>Test</h3><p>Enter the following URL in the browser:</p><code>https://localhost:8443/fedizhelloworld/secureservlet/fed</code><br />
<p>to access the web application which redirects to the IDP component. The IDP challenges the browser to enter username/password. Next, the IDP/STS issues the SAML token which contains all requested claims information and "redirects" the browser back to the application.<br />
</p><p>This <a href="http://owulff.blogspot.com/2011/11/configure-tomcat-for-federation-part.html">post</a> describes how to test the <b>fedizhelloworld</b> application. The configured users and their claims are described <a href="http://owulff.blogspot.com/2011/10/configure-and-deploy-cxf-25-sts-part-i.html">here</a>.<br />
</p><br><br />
<h3>Secure your own web application</h3><p>Follow these steps to secure your own web application:<br />
<p><ul><li>If it is another Tomcat instance than tomcat-rp ensure to deploy the federation plugin into this tomcat instance as described <a href="http://owulff.blogspot.com/2011/11/configure-tomcat-for-federation-part.html">here</a></li>
<li>Configure the Tomcat Valve <b>FederationAuthenticator</b> in your META-INF/context.xml or Tomcat server.xml as described <a href="http://owulff.blogspot.com/2011/11/configure-tomcat-for-federation-part.html">here</a></li>
<li>Configure the URL of your web application (including the servlet context name) in the RPClaims.xml (bean realm2ClaimsMap) in <code><tomcat-idp>/webapps/fedizidp/WEB-INF/RPClaims.xml</code> and update the claims if required</li>
<li>You can manage the claims of the users in <code><tomcat-idp>/webapps/fedizidpsts/WEB-INF/userClaims.xml</code></li>
</ul>Oliver Wulffhttp://www.blogger.com/profile/07294415212532150140noreply@blogger.com0tag:blogger.com,1999:blog-2816919410731663192.post-61765915378676592492012-03-07T21:32:00.000+01:002012-03-07T21:32:51.466+01:00WS-Federation across several companies<span style="font-family: Arial,Helvetica,sans-serif;">I described a simple scenario about the WS-Federation Passive Requestor Profile </span><span style="font-family: Arial,Helvetica,sans-serif;">in my previous blogs:</span><br />
<ul><li><a href="http://owulff.blogspot.com/2011/10/configure-and-deploy-identity-provider.html"><span style="font-family: Arial,Helvetica,sans-serif;">Configure and deploy Identity Provider (IdP) - Part II</span></a></li>
<li><span style="font-family: Arial,Helvetica,sans-serif;"><a href="http://owulff.blogspot.com/2011/11/configure-tomcat-for-federation-part.html">Configure Tomcat for federation - Part III </a></span></li>
</ul><span style="font-family: Arial,Helvetica,sans-serif;">Before I describe a more complex scenario, I'd like to summerize the benefits of the simple scenario:</span><br />
<ul><li><span style="font-family: Arial,Helvetica,sans-serif;">Authentication is externalized to IdP/STS</span></li>
<li><span style="font-family: Arial,Helvetica,sans-serif;">New IdP authentication mechanism can be used by all applications</span></li>
<li><span style="font-family: Arial,Helvetica,sans-serif;">Role Based Access control (RBAC) supported in applications</span></li>
<li><span style="font-family: Arial,Helvetica,sans-serif;">Claims/Attrribute based acess control (ABAC) supported in applications</span></li>
<li><span style="font-family: Arial,Helvetica,sans-serif;">IDP and applications deployable in different networks (ex. on-premise and cloud)</span></li>
<li><span style="font-family: Arial,Helvetica,sans-serif;">Easy testing with Mock IdP</span></li>
</ul><span style="font-family: Arial,Helvetica,sans-serif;"></span><br />
<span style="font-family: Arial,Helvetica,sans-serif;"> </span><br />
<span style="font-family: Arial,Helvetica,sans-serif;"><span style="font-size: large;">Federation with B2B partners in the internet</span></span><br />
<br />
<span style="font-family: Arial,Helvetica,sans-serif;">In most cases, a web application is built for a single user group like internal users with some basic authentication mechanism like username/password against an LDAP system. Over time, the business see some potential to grow in providing this solution to partners. The application is enhanced to support a new kind of authentication mechanism for the users of the partner. The next partner has again a different kind of approach for authentication which must be extended in your application. Very often, the userids of the partner's employees have to be managed within your ID system also. What happens of an employee of the partner leaves the company? Usually, a manual process must be triggered to deprovision the user in your ID system.</span><br />
<span style="font-family: Arial,Helvetica,sans-serif;"><br />
</span><br />
<span style="font-family: Arial,Helvetica,sans-serif;"></span><br />
<span style="font-family: Arial,Helvetica,sans-serif;">How can federation and claims based authorization help here. The simple scenario doesn't support different kind of "user groups". But it's very important to highlight that the authentication mechanism is not tight into the application but instead into the IDP component. The benefit of federation is that you can integrate new partners without having an impact on your application. Just imagine how agile your application is to generate new business with new B2B partners without building a new authentication mechanism within all your applications.</span><br />
<span style="font-family: Arial,Helvetica,sans-serif;"><br />
</span><br />
<span style="font-family: Arial,Helvetica,sans-serif;">How does this work? Let's look at a concrete example.</span><br />
<span style="font-family: Arial,Helvetica,sans-serif;"><br />
</span><br />
<span style="font-family: Arial,Helvetica,sans-serif;">Our federation enabled web application should be provided to two new partners (fabrikam.com and adatam.com).</span><br />
<span style="font-family: Arial,Helvetica,sans-serif;"><br />
</span><br />
<span style="font-family: Arial,Helvetica,sans-serif;">The users of fabrikam.com and adatam.com are managed within their own identity store. The following list provides more context information of the companies:</span><br />
<ul><li><span style="font-family: Arial,Helvetica,sans-serif;">mycompany.com</span><span style="font-family: Arial,Helvetica,sans-serif;"><br />
- 10000 users</span><span style="font-family: Arial,Helvetica,sans-serif;"><br />
- five roles (user, manager, sales, accountmanager, admin)</span><br />
</li>
<li><span style="font-family: Arial,Helvetica,sans-serif;">adatam.com</span><span style="font-family: Arial,Helvetica,sans-serif;"><br />
- IDP supported</span><span style="font-family: Arial,Helvetica,sans-serif;"><br />
- 2000 users</span><span style="font-family: Arial,Helvetica,sans-serif;"><br />
- three roles (employee, manager, administrator)</span><span style="font-family: Arial,Helvetica,sans-serif;"> <br />
</span></li>
<li><span style="font-family: Arial,Helvetica,sans-serif;">fabrikam.com</span><span style="font-family: Arial,Helvetica,sans-serif;"><br />
- IDP supported</span><span style="font-family: Arial,Helvetica,sans-serif;"> with restrictions (SAML token contains user only)<br />
- 50 users</span><span style="font-family: Arial,Helvetica,sans-serif;"> <br />
- two roles (user, accountmanager)</span><span style="font-family: Arial,Helvetica,sans-serif;"> </span></li>
</ul><span style="font-family: Arial,Helvetica,sans-serif;">The three companies have their own kind of naming for roles but the application must not differentiate between the different kind of role semantic.</span><br />
<span style="font-family: Arial,Helvetica,sans-serif;">fabrikam.com supports an IDP but can't provide the role information. mycompany.com decides to manage the 50 users and its roles within a dedicated ID store within their network (another option would have been to choose a more advanced IDM solution in the cloud). The usernames are different within the ID store at fabrikam.com and the dedicated ID store of mycompany.com due to different naming conventions in place.</span><br />
<span style="font-family: Arial,Helvetica,sans-serif;"><br />
</span><br />
<span style="font-family: Arial,Helvetica,sans-serif;">The following deployment diagram illustrates the solution:</span><br />
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="http://1.bp.blogspot.com/-rf170FpRhOU/T1YHMT6lCII/AAAAAAAAADM/9w8GIbgc1aA/s1600/federation.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="529" src="http://1.bp.blogspot.com/-rf170FpRhOU/T1YHMT6lCII/AAAAAAAAADM/9w8GIbgc1aA/s640/federation.png" width="640" /></a></div><div class="separator" style="clear: both; text-align: center;"><a href="http://4.bp.blogspot.com/-Oy7bVZA95Qs/T1X9xBWfzsI/AAAAAAAAADE/h_z36uJDZWQ/s1600/federation.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><br />
</a></div><span style="font-family: Arial,Helvetica,sans-serif;"><br />
</span><br />
<span style="font-family: Arial,Helvetica,sans-serif;">I haven't drawn any lines between the browser and the relying party which is the first component the browser accesses. The relying party redirects the browser to the RP-IDP (resource IDP) where the home realm discovery mechanism redirects the browser to its (requestor) IDP. The requestor IDP authenticates the browser and issues a SAML token with claims information. The browser sends the SAML token to the RP-IDP which transforms the SAML token into a format which can be validated and processed by the application (RP). This SAML token has the exact same structure independent who the requestor IDP was.</span><br />
<span style="font-family: Arial,Helvetica,sans-serif;"><br />
</span><br />
<span style="font-family: Arial,Helvetica,sans-serif;"><b>adatam.com</b></span><span style="font-family: Arial,Helvetica,sans-serif;"> </span><br />
<span style="font-family: Arial,Helvetica,sans-serif;">What happens with the different kind of syntax of the roles?</span><br />
<span style="font-family: Arial,Helvetica,sans-serif;">The RP-IDP transforms the roles from the requestor IDP to the internal set of roles.</span><br />
<ul><li><span style="font-family: Arial,Helvetica,sans-serif;">employee -> user</span></li>
<li><span style="font-family: Arial,Helvetica,sans-serif;">manager -> manager</span></li>
<li><span style="font-family: Arial,Helvetica,sans-serif;">administrator -> admin</span></li>
</ul><span style="font-family: Arial,Helvetica,sans-serif;"><b>fabrikam.com </b></span><br />
<span style="font-family: Arial,Helvetica,sans-serif;">How can the RP-IDP get the roles of the users?</span><br />
<span style="font-family: Arial,Helvetica,sans-serif;">The RP-IDP maps the userid of fabrikam.com to an internal userid in mycompany.com. The mapped userid is used to retrieve the role information. The roles/claims are not transformed.</span><br />
<span style="font-family: Arial,Helvetica,sans-serif;"><br />
</span><br />
<b><span style="font-family: Arial,Helvetica,sans-serif;">mycompany.com</span></b><br />
<span style="font-family: Arial,Helvetica,sans-serif;">Nothing changes.</span><br />
<span style="font-family: Arial,Helvetica,sans-serif;"><br />
</span><br />
<span style="font-family: Arial,Helvetica,sans-serif;">Finally, the issued tokens by the RP-IDP have the same syntax and semantic independent whether a user from fabrikam.com, adatam.com or an internal user accesses the application.</span><br />
<span style="font-family: Arial,Helvetica,sans-serif;"><br />
</span><br />
<span style="font-family: Arial,Helvetica,sans-serif;">There are different kind of relationships between mycompany.com and the partner adatam.com and fabrikam.com. The former relies on federating the claims information whereas the latter federates/maps the userid/identity.</span><br />
<span style="font-family: Arial,Helvetica,sans-serif;"><br />
</span><br />
<span style="font-family: Arial,Helvetica,sans-serif;"><br />
</span><br />
<span style="font-family: Arial,Helvetica,sans-serif;"><span style="font-size: large;">Support for identity mapping and claims transformation in STS</span></span><br />
<span style="font-family: Arial,Helvetica,sans-serif;"><br />
</span><br />
<span style="font-family: Arial,Helvetica,sans-serif;">The STS is the key component in the WS-Federation based solution who issues the security tokens. The <a href="http://coheigea.blogspot.com/2011/09/talend-donate-security-token-service.html">CXF STS</a> supports identity mapping in the release 2.5.x.</span><br />
<span style="font-family: Arial,Helvetica,sans-serif;"><br />
</span><br />
<span style="font-family: Arial,Helvetica,sans-serif;">I've finished my work to add support for claims transformation in the <a href="https://issues.apache.org/jira/browse/CXF-3882">CXF STS</a>.</span><br />
<br />
<span style="font-family: Arial,Helvetica,sans-serif;">Soon, I'll provide more details how to configure an STS with several realms (security domains) and different federation relationships among them.</span>Oliver Wulffhttp://www.blogger.com/profile/07294415212532150140noreply@blogger.com7tag:blogger.com,1999:blog-2816919410731663192.post-7721980453161215462012-03-06T07:45:00.010+01:002012-03-12T07:30:54.385+01:00SAML sender-vouches use case<span style="font-family: Arial,Helvetica,sans-serif;">In my previous blog here I described the different SAML subject confirmation methods (SCM) and how they integrate with an STS. This blog describes the use case for the Sender-Vouches (SV) SCM. As this use case can be solved with an STS also, I compare the two approaches finally.</span><br />
<span style="font-family: Arial,Helvetica,sans-serif;"><br />
</span><br />
<span style="font-family: Arial,Helvetica,sans-serif;"><span style="font-size: large;">Use case for SAML Sender-Vouches</span></span><br />
<br />
<span style="font-family: Arial,Helvetica,sans-serif;"></span><br />
<br />
<span style="font-family: Arial,Helvetica,sans-serif;">The SAML token profile states that the attesting entity is different from the subject. You have such kind of a scenario where a web service proxy/gateway (intermediary) is deployed between your service consumer and service provider. The proxy is the attesting entity and vouches for verification (or authentication) of the subject (service consumer). The proxy signs the SAML token and the soap body to protect against modification by another party.</span><br />
<br />
<span style="font-family: Arial,Helvetica,sans-serif;">The following picture illustrate the deployment diagram of this intermediary pattern:</span><br />
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="http://3.bp.blogspot.com/-bMe_0MvH554/T1Wu581GaEI/AAAAAAAAAC8/aPAsAwpuAa4/s1600/Intermediary.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="142" src="http://3.bp.blogspot.com/-bMe_0MvH554/T1Wu581GaEI/AAAAAAAAAC8/aPAsAwpuAa4/s320/Intermediary.png" width="320" /></a></div><br />
<span style="font-family: Arial,Helvetica,sans-serif;"><i>(This kind of intermediary pattern is often referred to as an ESB)</i> </span><br />
<br />
<span style="font-family: Arial,Helvetica,sans-serif;">The characteristic of the intermediary is that TCP connections (HTTP) are terminated and new connections are established between the intermediary and the service providers (the term proxy is widely used for settings in your OS or browser which support HTTP tunneling).</span><br />
<span style="font-family: Arial,Helvetica,sans-serif;"><br />
</span><br />
<span style="font-family: Arial,Helvetica,sans-serif;">The service provider must not accept a SAML SV token unless the token and the SOAP message content being vouched for are protected by the intermediary (attesting entity) who is trusted by the service provider. The protection can be achieved by using XML signature in the WS-Security header by signing the SAML token and the SOAP body. A direct trust is established between service provider and intermediary (service consumer).</span><br />
<span style="font-family: Arial,Helvetica,sans-serif;"><br />
</span><br />
<span style="font-family: Arial,Helvetica,sans-serif;">The usage of XML Signature has a significant performance impact as most XML security libraries are DOM dependent which means you need an full in-memory representation of the SOAP message. This breaks streaming (StAX parser) and increases memory usage by factors of the original message size. Another issue to consider is the potential lack of support for the STR Dereference transform algorithm to build the signature (this was not supported two years ago in .NET). This algorithm is described in section 3.4.3 in the <a href="http://docs.oasis-open.org/wss/v1.1/wss-v1.1-spec-os-SAMLTokenProfile.pdf">SAML Token Profile specification</a>.</span><br />
<span style="font-family: Arial,Helvetica,sans-serif;"><i>(Apache CXF/WSS4J 2.0 is going to support streaming based XML signature and encryption in the near future) </i></span><br />
<span style="font-family: Arial,Helvetica,sans-serif;"><br />
</span><br />
<span style="font-family: Arial,Helvetica,sans-serif;">The <a href="http://docs.oasis-open.org/ws-sx/security-policy/examples/ws-sp-usecases-examples.html">OASIS WS-SecurityPolicy Examples</a> document describes in 2.3.1.2 a more performant approach. Instead of signing the SOAP message on the XML level it uses a mutual SSL handshake where the service provider requires that the intermediary has configured a client certificate for the HTTPS communication he trusts. The side effect is that this won't be supported by all web service stacks and so you can run into interoperability issues.</span><br />
<span style="font-family: Arial,Helvetica,sans-serif;"><br />
</span><br />
<span style="font-family: Arial,Helvetica,sans-serif;">SAML SV works fine if the service provider, the intermediary and service consumer are in the same security domain which means that the principal name "jdoe" is processable in all of them. </span><br />
<ul><li><span style="font-family: Arial,Helvetica,sans-serif;">If the service providers are in different security domains how shall the intermediary map/federate the identity?</span><span style="font-family: Arial,Helvetica,sans-serif;"> </span></li>
<li><span style="font-family: Arial,Helvetica,sans-serif;">If the service provider should support more than one security domain how should the intermediary encode the security domain information into the SAML token?</span><span style="font-family: Arial,Helvetica,sans-serif;"> </span></li>
<li><span style="font-family: Arial,Helvetica,sans-serif;">Do the different web service stacks of your service providers support the same kind of mechanism to decode security domain information or do you have to write code for all your stacks to support that?</span><span style="font-family: Arial,Helvetica,sans-serif;"> </span></li>
<li><span style="font-family: Arial,Helvetica,sans-serif;">If the service provider requires role information in the SAML token how should the intermediary retrieve that and encode it within the SAML token?</span></li>
<li><span style="font-family: Arial,Helvetica,sans-serif;">Do the web service stacks of your service providers support the same kind of mechanism to decode role information thus you can use container managed role based access control?</span></li>
<li><span style="font-family: Arial,Helvetica,sans-serif;">Are the issued security tokens/retrieved authorization information cached? </span></li>
<li><span style="font-family: Arial,Helvetica,sans-serif;">If the service provider requires specific claims information in the SAML token ...</span></li>
</ul><span style="font-family: Arial,Helvetica,sans-serif;">As you can see, you have to consider a few things before deciding to go with the SAML Sender-Vouches subject confirmation method.</span><br />
<br />
<span style="font-family: Arial,Helvetica,sans-serif;">If your enviroment can fulfill the following requirements you can consider using SAML Sender-Vouches:</span><br />
<ul><li><span style="font-family: Arial,Helvetica,sans-serif;">there is only one security domain</span></li>
<li><span style="font-family: Arial,Helvetica,sans-serif;">you don't have to authorize your web services and thus don't need additional claims in the token</span></li>
<li><span style="font-family: Arial,Helvetica,sans-serif;">you're using only one Java or .NET web service stack</span></li>
<li><span style="font-family: Arial,Helvetica,sans-serif;">soap message size is small</span></li>
<li><span style="font-family: Arial,Helvetica,sans-serif;">performance is not critical or business logic related processing time is </span> <style type="text/css">
<!--
@page { margin: 0.79in }
P { margin-bottom: 0.08in }
-->
</style> <span style="font-family: Arial,Helvetica,sans-serif;">comparatively</span><span style="font-family: Arial,Helvetica,sans-serif;"> higher</span></li>
</ul><span style="font-family: Arial,Helvetica,sans-serif;">By now it should be apparent that SAML Sender-Vouches is not my favourite subject confirmation method. The main reasons are the underlying pattern of a direct trust (resulting in more administration effort, comparable to the usage of self-signed certificates without a certificate authority) and lots of functionality</span><span style="font-family: Arial,Helvetica,sans-serif;"> that should instead be handled by an IDM solution which can be integrated into different kind of contexts</span> <span style="font-family: Arial,Helvetica,sans-serif;"> (Web Services, Web SSO, B2B gateway, ...).</span><br />
<span style="font-family: Arial,Helvetica,sans-serif;">Is there another solution to address the intermediary case? <br />
</span><br />
<span style="font-family: Arial,Helvetica,sans-serif;"><br />
</span><br />
<span style="font-family: Arial,Helvetica,sans-serif;"><span style="font-size: large;">Use case "Intermediary" for WS-Trust Security Token Service</span></span><br />
<br />
<span style="font-family: Arial,Helvetica,sans-serif;">The answer to the question in my last paragraph is <b>yes</b>. </span><br />
<span style="font-family: Arial,Helvetica,sans-serif;"><br />
</span><br />
<span style="font-family: Arial,Helvetica,sans-serif;">The WS-Trust specification defines two ways to address it:</span><br />
<ul><li><span style="font-family: Arial,Helvetica,sans-serif;">OnBehalfOf</span></li>
<li><span style="font-family: Arial,Helvetica,sans-serif;">ActAs<br />
</span></li>
</ul><span style="font-family: Arial,Helvetica,sans-serif;">The following <a href="http://coheigea.blogspot.com/2011/08/ws-trust-14-support-in-cxf.html">blog post</a> provides more information about the differences of OnBehalfOf and ActAs. In both cases, the security token received by the intermediary is sent within one of these elements in the request (RST) to the STS. The STS validates the security token and issues a new one with the information of the original principal.</span><br />
<span style="font-family: Arial,Helvetica,sans-serif;"><br />
</span><br />
<span style="font-family: Arial,Helvetica,sans-serif;"><i>Is there a standard mechanism to tell the intermediary that the service provider requires a token issued by an STS?</i><br />
Yes, the service provider's WS-SecurityPolicy defines an <b>IssuedToken </b>assertion.</span><br />
<br />
<span style="font-family: Arial,Helvetica,sans-serif;"><i>Is there a standard mechanism to tell the intermediary what kind of security token (saml1, saml2, other) the service provider requires?</i><br />
Yes, </span><span style="font-family: Arial,Helvetica,sans-serif;">the service provider's WS-SecurityPolicy defines the <b>TokenType </b>in the RequestSecurityTokenTemplate of the IssuedToken assertion.</span><br />
<br />
<i><span style="font-family: Arial,Helvetica,sans-serif;">Is there a standard mechanism to tell the intermediary from which security domain the service provider requires a token issued?</span></i><br />
<span style="font-family: Arial,Helvetica,sans-serif;">Yes, </span><span style="font-family: Arial,Helvetica,sans-serif;">the service provider's WS-SecurityPolicy defines the <b>Issuer </b>element in the IssuedToken assertion.</span><br />
<br />
<span style="font-family: Arial,Helvetica,sans-serif;"><i>Is there a standard mechanism to tell the intermediary which claims information the service provider requires in the issued token?</i><br />
Yes, </span><span style="font-family: Arial,Helvetica,sans-serif;">the service provider's WS-SecurityPolicy defines the <b>Claims </b>element in the IssuedToken assertion.</span><br />
<br />
<span style="font-family: Arial,Helvetica,sans-serif;">This logic doesn't have to be coded and managed statically within the intermediary in a non-standard compliant way. It's very flexible by just changing the policy information of the service provider.</span><br />
<br />
<span style="font-family: Arial,Helvetica,sans-serif;">In both intermediary solutions (with and without STS), if the intermediary has to communicate with a remote component (ID system or STS) it's recommended to cache issued security tokens for the duration of their lifetimes. This avoids needing to obain a new security token for each web service request issued by the intermediary on behalf of a particular subject.</span><br />
<br />
<span style="font-family: Arial,Helvetica,sans-serif;">How does the intermediary know how long should a token be cached?</span><br />
<span style="font-family: Arial,Helvetica,sans-serif;">How should the intermediary know if a security token has been issued for a specific service only?</span><br />
<span style="font-family: Arial,Helvetica,sans-serif;">This is fairly easy, the response of an STS usually returns a Lifetime and AppliesTo element. The cache can be built around the incoming security token id, the subject the token is for, the lifetime and AppliesTo information to build a flexible and token agnostic cache.</span><br />
<br />
<span style="font-family: Arial,Helvetica,sans-serif;">Last but not least, is there a web services stack which supports this functionality without having to write a single line of code?</span><br />
<span style="font-family: Arial,Helvetica,sans-serif;">Yes, it's <a href="http://cxf.apache.org/">Apache CXF</a>. The intermediary use case is described in the above mentioned blog post. A <a href="http://svn.apache.org/viewvc/cxf/trunk/services/sts/systests/basic/src/test/java/org/apache/cxf/systest/sts/intermediary_transformation/">system test</a> and its <a href="http://svn.apache.org/viewvc/cxf/trunk/services/sts/systests/basic/src/test/resources/org/apache/cxf/systest/sts/intermediary_transformation/">configuration </a>for the CXF STS is available too.</span><br />
<span style="font-family: Arial,Helvetica,sans-serif;"><br />
</span><br />
<span style="font-family: Arial,Helvetica,sans-serif;">CXF is not the only web services stack supporting the intermediary case with an STS as the following article shows:</span><br />
<ul><li><span style="font-family: Arial,Helvetica,sans-serif;"><a href="http://www.ibm.com/developerworks/websphere/library/techarticles/1003_chades/1003_chades.html?ca=drs-">Using WS-Trust for token transformation</a><br />
</span></li>
</ul><span style="font-family: Arial,Helvetica,sans-serif;"> </span><br />
<span style="font-family: Arial,Helvetica,sans-serif;"> </span><br />
<span style="font-family: Arial,Helvetica,sans-serif;"> </span><br />
<span style="font-family: Arial,Helvetica,sans-serif;">One question remains: How can the service provider process claims information like roles, etc. which are encoded as an AttributeStatement in the SAML token? Do I have to implement and maintain this for Websphere, Weblogic, Tomcat, JBoss, etc.<br />
</span><br />
<span style="font-family: Arial,Helvetica,sans-serif;">This answer is <b>no</b>.</span><br />
<span style="font-family: Arial,Helvetica,sans-serif;">In one of my next posts I will explain how to reduce the complexity and increase interoperability of your web services deployment even you've got different application server stacks in house.</span><br />
<span style="font-family: Arial,Helvetica,sans-serif;"><br />
</span><br />
<span style="font-family: Arial,Helvetica,sans-serif;"><br />
</span>Oliver Wulffhttp://www.blogger.com/profile/07294415212532150140noreply@blogger.com0tag:blogger.com,1999:blog-2816919410731663192.post-88234878209296612632012-02-27T19:53:00.017+01:002012-08-02T09:14:33.589+02:00SAML tokens and WS-Trust Security Token Service (STS)<span style="font-family: Arial,Helvetica,sans-serif;">I've been working actively in the Apache <a href="http://cxf.apache.org/">CXF </a>community with respect to SAML tokens and the WS-Trust SecurityTokenService (STS) since Talend's <a href="http://coheigea.blogspot.com/2011/09/talend-donate-security-token-service.html">donation </a>of the STS to the community. I've noticed in various WS-Trust projects that there is a lack of documentation about the different use cases for SAML tokens and the WS-Trust STS.</span><br />
<br />
<span style="font-family: Arial,Helvetica,sans-serif;">I'll give a brief introduction into SAML and STS before bringing the two together.</span><br />
<span style="font-family: Arial,Helvetica,sans-serif;"><br />
</span><br />
<span style="font-family: Arial,Helvetica,sans-serif;"><span style="font-size: large;">SAML</span></span><br />
<span style="font-family: Arial,Helvetica,sans-serif;"> </span><br />
<br />
<span style="font-family: Arial,Helvetica,sans-serif;">SAML is an OASIS standard and consists of several specifications. A SAML token is issued by an identity provider. A service provider relies on the identity provider to authenticate a principal (a user). The SAML assertion is provided to the service provider allowing it to make an access control decision. </span><span style="font-family: Arial,Helvetica,sans-serif;">The main problem SAML tries to solve is Web Single Sign On.</span><br />
<br />
<span style="font-family: Arial,Helvetica,sans-serif;">There is a clear layering between the SAML specifications thus they can be fairly easy reused in other contexts. Another context besides Web SSO is Web Services communication - which I'll be covering here. Therefore, we only need to look into the SAML Core specification as it describes the syntax and semantics of SAML assertions. The SAML protocols are covered by SAML core too but there are not relevant for Web Services communication. This is also the case for the SAML bindings (how SAML messages are transmitted from one system entity to another) as well as for SAML profile which describes use cases for Web application Single Sign On.</span><br />
<br />
<span style="font-family: Arial,Helvetica,sans-serif;">A SAML assertion (also known as SAML security token) contains different kinds of statements: authentication-, attribute- and authorization decision statements. The "authorization decision statement" became deprecated in SAML 2.0 specification as it is covered in XACML and in claims based authorization based on standard SAML attribute statements. The former is quite complex whereas the latter provides already good options for fine grained authorization at less complexity. You can find more information about the latter <a href="http://owulff.blogspot.com/2011/10/configure-and-deploy-identity-provider.html">here</a>.</span><br />
<span style="font-family: Arial,Helvetica,sans-serif;"><br />
</span><br />
<span style="font-family: Arial,Helvetica,sans-serif;">A SAML assertion contains a subject which identifies the principal. The subject can also contain additional information like key material and the subject confirmation method. One of the main topics in this blog are the different kind of subject confirmation methods and how they correlate to an STS.</span><br />
<span style="font-family: Arial,Helvetica,sans-serif;"><br />
</span><br />
<span style="font-family: Arial,Helvetica,sans-serif;">As a side note, the subject confirmation method is not defined in the SAML core. Instead, the <a href="http://www.oasis-open.org/committees/download.php/35389/sstc-saml-profiles-errata-2.0-wd-06-diff.pdf">SAML profile</a> specification defines the following three subject confirmation methods:</span><br />
<ul><li><span style="font-family: Arial,Helvetica,sans-serif;">Holder of Key (HOK)<br />
The subject must contain key material so the service provider is able to validate that the requestor is in the possession of the key(s)</span></li>
<li><span style="font-family: Arial,Helvetica,sans-serif;">Bearer<br />
The subject doesn't contain key material and it is up to the service provider to accept the assertion or not</span></li>
<li><span style="font-family: Arial,Helvetica,sans-serif;">Sender vouches (SV)<br />
The subject doesn't contain key material and it is up to the service provider to accept the assertion or not. The requestor and the identity provider are usually the same.<br />
</span></li>
</ul><span style="font-family: Arial,Helvetica,sans-serif;"></span><br />
<span style="font-family: Arial,Helvetica,sans-serif;">For more information about SAML I recommend <a href="http://en.wikipedia.org/wiki/Security_Assertion_Markup_Language">Wikipedia</a> and the documentation at the OASIS <a href="http://www.oasis-open.org/committees/tc_home.php?wg_abbrev=security&sig2=wfBb1IHvHLMgCohMVzbgNw">committee</a>.</span><br />
<br />
<span style="font-family: Arial,Helvetica,sans-serif; font-size: large;">Web Services and SAML</span><br />
<br />
<span style="font-family: Arial,Helvetica,sans-serif;">SAML in the context of Web Services is standardized in the SAML token profile <a href="http://www.oasis-open.org/committees/download.php/16768/wss-v1.1-spec-os-SAMLTokenProfile.pdf">here</a>. It describes on the one hand how a SAML token is embedded in a SOAP message and on the other hand what kind of requirements must be met dependent on the SAML version and subject confirmation method.</span><br />
<span style="font-family: Arial,Helvetica,sans-serif;"><br />
</span><br />
<span style="font-family: Arial,Helvetica,sans-serif;">I can highly recommend the following <a href="http://docs.oasis-open.org/ws-sx/security-policy/examples/ws-sp-usecases-examples.html">web services security usecases</a> from OASIS as it describes very interesting use cases by combining transport level and message level security (ex. SAML HOK is very complex and has a performance impact as XML signature is required. This document describes how to use mutual SSL handshake for the proof-of-possession processing)</span><br />
<br />
<span style="font-family: Arial,Helvetica,sans-serif;">In 2011, many new security features have been added to CXF. Check the following <a href="http://coheigea.blogspot.com/2011/12/ws-securitypolicy-examples-in-apache.html">blog </a>for more information.</span><br />
<span style="font-family: Arial,Helvetica,sans-serif;"></span><br />
<br />
<br />
<span style="font-family: Arial,Helvetica,sans-serif;"><span style="font-size: large;">WS-Trust STS</span></span><br />
<span style="font-family: Arial,Helvetica,sans-serif;"><br />
</span><br />
<span style="font-family: Arial,Helvetica,sans-serif;">The WS-Trust standard introduces a runtime component called Security Token Service (STS). A service consumer requests a security token from the STS which is sent to the service provider. Either the service provider can validate the security token on its own or sends a request to the STS for validation. This pattern is based on an indirect trust relationship between the service provider and the STS instead of between the service provider and service consumer. As long as the service consumer is in the possession of a security token issued by a trusted STS, the service provider accepts the token sent by the service consumer. This is the same pattern as for certificates and certificate authorities. This approach has significant advantages compared to a direct (brokered) trust established between a service provider and service consumer. The specification is an OASIS standard and can be downloaded <a href="http://docs.oasis-open.org/ws-sx/ws-trust/200802">here</a>.</span><br />
<br />
<span style="font-family: Arial,Helvetica,sans-serif;">The STS can issue security tokens based on requirements provided by the service consumer and/or service provider. The requirements of the service provider are either expressed in a WS-Policy document according to WS-SecurityPolicy or out-of-band agreement.</span><br />
<span style="font-family: Arial,Helvetica,sans-serif;"><br />
</span><br />
<span style="font-family: Arial,Helvetica,sans-serif;">A key benefit of the STS is the reduced complexity for web service consumer. A web service consumer doesn't have to know how to create the various types of security tokens its service providers require. Instead, it sends a request to the STS containing the requirements of the client and the service provider and attaches the returned security token to the outgoing SOAP message to the service provider. One service provider could require a SAML 1.1 token, another a SAML 2.0 token and another a custom binary security token. The service consumer doesn't have to understand SAML 1.1, SAML 2.0 or the custom binary security token. All he has to do is grab the returned token from the STS and attach it to the message. Thus, you can reduce the complexity in your application and move it to a centralized component.</span><br />
<span style="font-family: Arial,Helvetica,sans-serif;"><br />
</span><br />
<span style="font-family: Arial,Helvetica,sans-serif;">How does a web service consumer know whether it has to go to an STS to request a token? The policy of the service provider contains an IssuedToken assertion with some additional information like the address of the STS, token type, claims, etc.</span><br />
<span style="font-family: Arial,Helvetica,sans-serif;"><br />
</span><br />
<span style="font-family: Arial,Helvetica,sans-serif;">Now, it's time to explain a few parameters of the request (RST) to the STS.</span><br />
<span style="font-family: Arial,Helvetica,sans-serif;"><br />
</span><br />
<b><span style="font-family: Arial,Helvetica,sans-serif;">TokenType</span></b><br />
<span style="font-family: Arial,Helvetica,sans-serif;">specifies the type of security token requested (ex. SAML 1.1, 2.0, X.509, ...). URIs are defined for all standard security tokens.</span><br />
<br />
<b><span style="font-family: Arial,Helvetica,sans-serif;">KeyType</span></b><br />
<span style="font-family: Arial,Helvetica,sans-serif;">specifies the type of key desired in the security token. There are three URIs defined:</span><br />
<ul><li><span style="font-family: Arial,Helvetica,sans-serif;">PublicKey</span></li>
<li><span style="font-family: Arial,Helvetica,sans-serif;">SymmetricKey</span></li>
<li><span style="font-family: Arial,Helvetica,sans-serif;">Bearer</span></li>
</ul><br />
<b><span style="font-family: Arial,Helvetica,sans-serif;">Claims</span></b><br />
<span style="font-family: Arial,Helvetica,sans-serif;">specifies the required and optional claims in the security token. A claim can be the email address, role information, country, etc.</span><br />
<span style="font-family: Arial,Helvetica,sans-serif;"></span><br />
<br />
<b><span style="font-family: Arial,Helvetica,sans-serif;">AppliesTo</span></b><br />
<span style="font-family: Arial,Helvetica,sans-serif;">specifies the scope for which the security token is required. This can be the URL of the service provider.</span><br />
<span style="font-family: Arial,Helvetica,sans-serif;"><br />
</span><br />
<span style="font-family: Arial,Helvetica,sans-serif;"><b>Lifetime</b></span><br />
<span style="font-family: Arial,Helvetica,sans-serif;">specifies the creation and expiration time of the security token. The STS is not obligated to honor this range.</span><br />
<br />
<span style="font-family: Arial,Helvetica,sans-serif;">These parameters can be retrieved from the WS-SecurityPolicy document also. In that case, they are added as child elements of the </span><span style="font-family: Arial,Helvetica,sans-serif;">SecondaryParameters element in the RST.</span><br />
<br />
<span style="font-family: Arial,Helvetica,sans-serif;"></span><br />
<br />
<span style="font-family: Arial,Helvetica,sans-serif;"><span style="font-size: large;">SAML and STS </span> </span><br />
<br />
<br />
<span style="font-family: Arial,Helvetica,sans-serif;">How does a SAML token and the parameters sent to the STS match with each other. How does the STS know which subject confirmation method should be used? OK, let's start with the more obvious one.</span><br />
<br />
<span style="font-family: Arial,Helvetica,sans-serif;">1) TokenType</span><br />
<span style="font-family: Arial,Helvetica,sans-serif;">the token type is either SAML 1.1 or SAML 2.0. The STS creates the corresponding SAML assertion</span><br />
<br />
<span style="font-family: Arial,Helvetica,sans-serif;">2) AppliesTo</span><br />
<span style="font-family: Arial,Helvetica,sans-serif;">the AppliesTo element defines the scope and thus match to the SAML AudienceRestriction element in the SAML condition</span><br />
<br />
<span style="font-family: Arial,Helvetica,sans-serif;">3) Lifetime</span><br />
<span style="font-family: Arial,Helvetica,sans-serif;">the value of the lifetime or the lifetime choosen by the STS matchs to the SAML conditions NotBefore and NotAfter</span><br />
<br />
<span style="font-family: Arial,Helvetica,sans-serif;">4) Claims</span><br />
<span style="font-family: Arial,Helvetica,sans-serif;">the claim values maps to a SAML attribute statement. It's standardized <a href="http://docs.oasis-open.org/imi/identity/v1.0/identity.html">here </a>how claims are encoded as a SAML attribute statement. </span><span style="font-family: Arial,Helvetica,sans-serif;">You can get more information about claims <a href="http://owulff.blogspot.com/2011/10/configure-and-deploy-cxf-25-sts-part-i.html">here</a>.</span><br />
<span style="font-family: Arial,Helvetica,sans-serif;"><br />
</span><br />
<span style="font-family: Arial,Helvetica,sans-serif;">How is the trust between the service provider and the STS established? This is fairly easy. The SAML assertion is signed by the STS. The signing certificate must be configured in the service provider to be trusted.</span><br />
<span style="font-family: Arial,Helvetica,sans-serif;"><br />
</span><br />
<span style="font-family: Arial,Helvetica,sans-serif;">But how can the STS know whether the subject confirmation method should be HoK, SV or Bearer.</span><br />
<span style="font-family: Arial,Helvetica,sans-serif;">If the KeyType contains the value </span><span style="font-family: Arial,Helvetica,sans-serif;"><b>PublicKey </b>or <b>SymmetricKey</b>, the subject confirmation method is <b>Holder-Of-Key</b>.</span><br />
<span style="font-family: Arial,Helvetica,sans-serif;">If the KeyType contains the value <b>Bearer</b>, the subject confirmation method is <b>Bearer</b>.</span><br />
<br />
<span style="font-family: Arial,Helvetica,sans-serif;">The benefit of HoK is that even if somebody gets into the possession of a SAML token he can't </span> <br />
<span style="font-family: Arial,Helvetica,sans-serif;">send requests masquerading as the subject<span style="font-family: Arial,Helvetica,sans-serif;"> </span>in the SAML token as he doesn't know the key (symmetric or private key). However SAML tokens with Bearer subject confirmation method must be protected. In most cases, Bearer combined with HTTPS is sufficient to prevent that "a man in the middle" can get into the possession of the SAML token.</span><br />
<br />
<span style="font-family: Arial,Helvetica,sans-serif;">The subject confirmation methods Bearer and Holder-Of-Key are widely used for all STS use cases as well as for Web Single Sign On in <a href="http://owulff.blogspot.com/2011/10/configure-and-deploy-identity-provider.html">WS-Federation Passive Requestor Profile</a> and SAML Post Profile. </span><br />
<span style="font-family: Arial,Helvetica,sans-serif;"><br />
</span><br />
<span style="font-family: Arial,Helvetica,sans-serif;">OK, what about sender-vouches? Even it is not clearly stated it makes <b>no sense</b> to request a <b>SAML token</b> from an <b>STS </b>with <b>sender-vouches</b> subject confirmation method.</span><br />
<span style="font-family: Arial,Helvetica,sans-serif;"><br />
</span><br />
<span style="font-family: Arial,Helvetica,sans-serif;">You might know this <a href="http://publib.boulder.ibm.com/infocenter/wasinfo/v8r0/index.jsp?topic=/com.ibm.websphere.base.doc/info/aes/ae/twbs_configsamlsendervouches_transportlevel_requeststs.html">paper </a>from IBM which describes how to get a SAML token from the STS with sender-vouches. Even though it's from IBM, I won't change my opinion ;-)</span><br />
<br />
<span style="font-family: Arial,Helvetica,sans-serif;">Let's step back once and have a look what the differences are between a SAML token with subject confirmation method Bearer and Sender-Vouches. Utlimately, it is just a string in the ConfirmationMethod element. Of course, an STS can put the string for Sender-Vouches into the SAML token - not a big deal. </span><br />
<br />
<span style="font-family: Arial,Helvetica,sans-serif;">The <a href="http://docs.oasis-open.org/wss/v1.1/wss-v1.1-spec-os-SAMLTokenProfile.pdf">WS-Security SAML token profile</a> defines the processing rules for HoK and Sender Vouches. In the case of Sender-Vouches it says that the attesting entity, (presumed to be) different from the subject, vouches for the verification </span><span style="font-family: Arial,Helvetica,sans-serif;">of the subject. The receiver MUST have an existing trust relationship with the attesting entity. The attesting entity MUST protect the assertion in combination with the message content against modification by another party</span><span style="font-family: Arial,Helvetica,sans-serif;">. The trust is established based on certificates where the attesting entity (service consumer) creates a signature which protects the SAML token and the SOAP body. The service provider verifies the signature to have the confirmation that nobody made changes either to the token or the SOAP body. The receiver (service provider) must have imported the certificate of the service consumer.</span><br />
<span style="font-family: Arial,Helvetica,sans-serif;">A SV SAML token itself is not signed in contrast to Bearer and HoK because there is no third party like an STS. It wouldn't make sense for an STS to issue unsigned SAML tokens as there would be no way to protect against other entities adding additional statements.</span><br />
<br />
<span style="font-family: Arial,Helvetica,sans-serif;">Therefore, Sender-Vouches doesn't make sense in the context of STS.</span><br />
<br />
<span style="font-family: Arial,Helvetica,sans-serif;">Where is SAML Sender-Vouches used? I blogged about this topic <a href="http://owulff.blogspot.com/2012/03/saml-sender-vouches-use-case.html">here</a>.</span><br />
<br />
<span style="font-family: Arial,Helvetica,sans-serif;"><br />
</span>Oliver Wulffhttp://www.blogger.com/profile/07294415212532150140noreply@blogger.com16tag:blogger.com,1999:blog-2816919410731663192.post-38915466560844832712012-02-06T13:26:00.001+01:002012-02-07T09:29:28.365+01:00Configure Fediz IDP and ASP.NET using WIF<span style="font-family: Verdana,sans-serif;">Fediz provides different components to support single sign on and claims based authorization for web applications based on WS-Federation. As described <a href="http://owulff.blogspot.com/2011/10/configure-and-deploy-identity-provider.html">here</a>, the IDP/STS is the central component which authenticates users and issues security tokens (ex. SAML) which includes information about the authenticated identity, their keys and claims. The other component is deployed within the relying party, the web application. How you can enable WS-Federation for Tomcat is described <a href="http://owulff.blogspot.com/2011/11/configure-tomcat-for-federation-part.html">here</a>.</span><br />
<span style="font-family: Verdana;">What about other technologies like Microsoft. WS-Federation is supported by Microsoft out-of-the-box by the <a href="http://msdn.microsoft.com/en-us/security/aa570351">Windows Identity Foundation</a> (WIF). ASP.NET supports similar extension points like Tomcat to intercept and customize request processing and authentication. The counterpart of a Tomcat Valve is a .NET <a href="http://msdn.microsoft.com/en-us/library/bb398986.aspx">HttpModule</a>.</span><br />
<br />
<span style="font-family: Verdana;">WIF is a .NET assembly (DLL) which provides http modules, new config section and other stuff. Thus, you can enable WS-Federation for your ASP.NET based web application by configuration. There is a very good post about WIF and ASP.NET <a href="http://msdn.microsoft.com/en-us/magazine/ff872350.aspx">here</a>. There is also a <a href="http://weblogs.asp.net/gunnarpeipman/archive/2011/02/17/5-minutes-wif-make-your-asp-net-application-use-test-sts.aspx">Visual Studio extension</a> to generate a mock IDP based on ASP.NET and WIF but it doesn't have the functionality supported by the mock IDP as part of Fediz. You can create test users and assign any kind of claims to each users thus you can easily test your claims based ASP.NET web application. IMHO, there is another reason, isn't it cool to show how interoperable .NET and Java is !?</span><br />
<br />
<span style="font-family: Verdana;">You can re-use the updated IDP provided <a href="http://owulff.blogspot.com/2011/12/updates-on-federation-sources.html">here</a>.</span><br />
<br />
<span style="font-family: Verdana;">The following steps are required to use this mock IDP in your ASP.NET web application.</span><br />
<br />
<span style="font-family: Verdana;"><span style="font-size: large;">1. Deploy Windows Identity Foundation</span></span><br />
<span style="font-family: Verdana;"></span><span style="font-family: Verdana;"></span><br />
<span style="font-family: Verdana;">You can download WIF <a href="http://msdn.microsoft.com/en-gb/evalcenter/dd440951.aspx">here</a> and install it. Finally, you only have to deploy the Microsot.IdentityModel.dll to your bin directory of the web application.</span><br />
<span style="font-family: Verdana;"><br />
</span><br />
<span style="font-family: Verdana;"></span><span style="font-family: Verdana;"><span style="font-size: large;">2. Import the IDP/STS certificate in the Microsoft </span><span style="font-size: large;">certificate store</span></span><br />
<span style="font-family: Verdana;">You can get more information about the Microsoft certificate store <a href="http://technet.microsoft.com/en-us/library/cc757138%28WS.10%29.aspx">here</a>.</span><br />
<span style="font-family: Verdana;">The relying party must establish a trust with the IDP/STS. This is achieved by trusting the certificate which was used to sign the SAML token. Windows and .NET have their own certificate store and doesn't understand a Java keystore (JKS). Therefore, we have to export the certificate in the JKS in a platform neutral format like PEM. You have to run the following command:</span><br />
<span style="font-family: Verdana;"><br />
<span style="font-family: "Courier New",Courier,monospace;">keytool -exportcert -alias mystskey -keystore stsstore.jks <br />
-storepass stsspass -rfc -file sts.pem</span><br />
Import the certificate file <span style="font-family: "Courier New",Courier,monospace;">sts.pem</span> into the store as described <a href="http://technet.microsoft.com/en-us/library/cc738545%28WS.10%29.aspx">here</a>.</span><br />
<span style="font-family: Verdana;">Ensure that you import the certificate into the "Trusted People" store.</span><br />
<span style="font-family: Verdana;"><br />
</span><br />
<span style="font-family: Verdana;">You are able to click on the certificate you imported before. The value of the field "Thumbprint" is required to establish the trust to the IDP within the relying party.</span><br />
<span style="font-family: Verdana;"><br />
</span><br />
<div class="separator" style="clear: both; text-align: center;"><a href="http://1.bp.blogspot.com/-0vbYZd9fNIU/Ty_GTpH9S5I/AAAAAAAAACs/oPtKta8PVao/s1600/import.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="200" src="http://1.bp.blogspot.com/-0vbYZd9fNIU/Ty_GTpH9S5I/AAAAAAAAACs/oPtKta8PVao/s320/import.PNG" width="320" /></a></div><span style="font-family: Verdana;"><br />
</span><br />
<span style="font-family: Verdana;"><br />
</span><br />
<span style="font-family: Verdana; font-size: large;">3. Configure WIF in web.config</span><br />
<br />
<br />
<span style="font-family: Verdana;">Different sections of the web.config must be updated. First, you must configure the new config section for WIF:</span><br />
<span style="font-family: Verdana;"><br />
</span><br />
<span style="font-family: Verdana;"><span style="font-family: "Courier New",Courier,monospace; font-size: small;"> </span><span style="font-family: "Courier New",Courier,monospace; font-size: small;"><configSections><br />
<section name="microsoft.identityModel"<br />
type="Microsoft.IdentityModel.Configuration.MicrosoftIdentityModelSection, Microsoft.IdentityModel, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" /><br />
</configSections></span></span><br />
<br />
<span style="font-family: Verdana;">Second, configure the http modules:</span><br />
<span style="font-family: Verdana;"> </span><br />
<div style="font-family: "Courier New",Courier,monospace;"><span style="font-size: small;"> <span style="font-family: "Courier New",Courier,monospace;"><system.web><br />
<httpModules><br />
<add name="SessionAuthenticationModule"<br />
type="Microsoft.IdentityModel.Web.SessionAuthenticationModule, Microsoft.IdentityModel, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" /><br />
<add name="WSFederationAuthenticationModule"<br />
type="Microsoft.IdentityModel.Web.WSFederationAuthenticationModule, Microsoft.IdentityModel, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" /><br />
</httpModules></span></span></div><div style="font-family: "Courier New",Courier,monospace;"><br />
</div><div style="font-family: "Courier New",Courier,monospace;"><span style="font-size: small;">Disable default authentication/authorization. Instead, the above http modules will handle authentication and authorization:</span></div><div style="font-family: "Courier New",Courier,monospace;"><span style="font-size: small;"><br />
</span></div><div style="font-family: "Courier New",Courier,monospace;"><span style="font-size: small;"> <authentication mode="None" /><br />
<authorization><br />
<deny users="?" /><br />
</authorization></span></div><span style="font-family: Verdana;"><br />
</span><br />
<span style="font-family: Verdana;">Configure WIF:</span><br />
<span style="font-family: Verdana;"><br />
</span><br />
<span style="font-family: Verdana;"><span style="font-family: "Courier New",Courier,monospace; font-size: small;"> </span><span style="font-family: "Courier New",Courier,monospace; font-size: small;"> <microsoft.identityModel><br />
<service saveBootstrapTokens="true"><br />
<issuerNameRegistry type="Microsoft.IdentityModel.Tokens.ConfigurationBasedIssuerNameRegistry, Microsoft.IdentityModel, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"><br />
<trustedIssuers><br />
<add thumbprint="977f0c1c0a2e9534d310a8e05380f5653524ca3f"<br />
name="https://b0d0ma02.ch.zurich.com:16050/fedizidp/" /><br />
</trustedIssuers><br />
</issuerNameRegistry><br />
<certificateValidation<br />
certificateValidationMode="PeerTrust" revocationMode="Online"<br />
trustedStoreLocation="LocalMachine" /><br />
<audienceUris><br />
<add value="https://teinf0095.emea.zurich.test/helloworld/" /><br />
</audienceUris><br />
<federatedAuthentication><br />
<wsFederation passiveRedirectEnabled="true"<br />
issuer="https://b0d0ma02.ch.zurich.com:16050/fedizidp/"<br />
realm="https://teinf0095.emea.zurich.test/helloworld/"<br />
requireHttps="true" /><br />
<cookieHandler requireSsl="false" name="FedAuth"<br />
hideFromScript="true" path="/helloworld" /><br />
</federatedAuthentication><br />
</service><br />
</microsoft.identityModel></span></span><br />
<span style="font-family: Verdana;"><br />
</span><br />
<span style="font-family: Verdana;">I'd like to highlight the following pieces in the </span><span style="font-family: Verdana;">section "microsoft.identityModel".</span><br />
<br />
<span style="font-family: Verdana;">1) </span><span style="font-family: Verdana;">issuerNameRegistry</span><br />
<span style="font-family: Verdana;">add the thumbprint to the issuerNameRegistry</span><br />
<span style="font-family: Verdana;"><br />
</span><br />
<span style="font-family: Verdana;">2) audienceUris</span><br />
<span style="font-family: Verdana;">add the valid uri's which must match with the audience restriction in the SAML token</span><br />
<span style="font-family: Verdana;"><br />
</span><br />
<span style="font-family: Verdana;">3) </span><span style="font-family: Verdana;">federatedAuthentication</span><br />
<span style="font-family: Verdana;">configure the URL of the IDP in the attribute "issuer" and the realm for the application. The realm matches with the audience restriction finally. </span><br />
<span style="font-family: Verdana;"><br />
</span><br />
<span style="font-family: Verdana;"><br />
</span><br />
<span style="font-family: Verdana;">More information about WIF configuration can be found <a href="http://msdn.microsoft.com/en-gb/library/gg607699.aspx">here</a>.</span><br />
<span style="font-family: Verdana;">That's it. You are ready for testing...</span><br />
<br />
<br />
<span style="font-family: Verdana; font-size: large;">4. If it doesn't work...</span><br />
<span style="font-family: Verdana;"> </span><br />
<span style="font-family: Verdana;"> 1) A generic exception is returned by the .NET application without indicating the root cause.</span><br />
<span style="font-family: Verdana;"><br />
</span><br />
<i><span style="font-family: Verdana;">There should be an error logged in the Microsoft Event Viewer (Administrative Tools) for the log type "Application".</span></i><br />
<span style="font-family: Verdana;"><br />
</span><br />
<span style="font-family: Verdana;">2) SecurityTokenValidationException is returned by the application</span><br />
<span style="font-family: Verdana;"><br />
</span><br />
<span style="font-family: Verdana;">exception details:</span><br />
<span style="font-family: Verdana;">[SecurityTokenValidationException: The X.509 certificate E=sts@sts.com, CN=www.sts.com, OU=IT Department, O=Sample STS -- NOT FOR PRODUCTION, L=Baltimore, S=Maryland, C=US is not in the trusted people store.]</span><br />
<span style="font-family: Verdana;"><br />
</span><br />
<i><span style="font-family: Verdana;">Certificate not imported into the Microsoft Certificate store (Trusted People store. See section 2.</span></i><br />
<span style="font-family: Verdana;"><br />
</span><br />
<span style="font-family: Verdana;">3) SecurityTokenException</span><br />
<span style="font-family: Verdana;"><br />
</span><br />
<span style="font-family: Verdana;">exception details:</span><br />
<span style="font-family: Verdana;">[SecurityTokenException: ID4175: The issuer of the security token was not recognized by the IssuerNameRegistry. To accept security tokens from this issuer, configure the IssuerNameRegistry to return a valid name for this issuer.]</span><br />
<span style="font-family: Verdana;"><br />
</span><br />
<span style="font-family: Verdana;"><i>Certificate not trusted. Ensure that the correct thumbprint is configured in web.config.</i></span>Oliver Wulffhttp://www.blogger.com/profile/07294415212532150140noreply@blogger.com0tag:blogger.com,1999:blog-2816919410731663192.post-27131300154466922602011-12-23T10:14:00.001+01:002011-12-23T10:36:51.882+01:00Updates on federation sourcesIn the last weeks I was working in enabling IBM Websphere with WS-Federation and setting up a testcase where a federation enabled web application consumes web services where the security context must be propagated. I need some more time to prepare an example and post a blog. Stay tuned.<br />
<br />
There are some updates with respect to the federation examples I posted in the last weeks.<br />
<br />
<ul><li>Sources have been moved from Google docs to the Apache CXF project </li>
<li>The SAML security token had a lifetime of 5 minutes which has been increased to 20 minutes</li>
<li> The Tomcat authenticator doesn't redirect if the security token is expired instead it blocks the incoming request</li>
</ul><br />
<br />
<div style="font-family: "Helvetica Neue",Arial,Helvetica,sans-serif;"><b>Sources have been moved from Google docs to the Apache <a href="http://cxf.apache.org/">CXF</a> project</b></div><br />
You can find the sources <a href="http://svn.apache.org/viewvc/cxf/sandbox/fediz/">here</a>. Right now, you have to check out the sources and build them on your own. This is fairly simple with Maven (mvn clean install).<br />
<br />
The package names have changed. Please ensure to configure the new package name org.apache.cxf.fediz. ...<br />
<br />
The STS of the CXF release 2.5.1 is used<br />
<br />
If you have any questions please raise them at the Apache CXF <a href="http://cxf.apache.org/mailing-lists.html">mailing list</a>. <br />
<br />
<br />
<b><span style="font-family: "Helvetica Neue",Arial,Helvetica,sans-serif;">The SAML security token had a lifetime of 5 minutes which has been increased to 20 minutes</span></b><br />
<br />
If you deploy the previous Tomcat example you could test the application for 5 minutes. Further requests have been rejected because the security token lifetime is expired (Condition in SAML 2.0).<br />
<br />
I made the following changes to the STS configuration to change the default lifetime which is fairly simple to do due to the usage of Spring.<br />
<span style="font-size: x-small;"><br />
</span><br />
<span style="font-size: x-small;"><span style="font-family: "Courier New",Courier,monospace;"> <bean id="transportSamlTokenProvider" class="org.apache.cxf.sts.token.provider.SAMLTokenProvider"></span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"> <property name="attributeStatementProviders" ref="attributeStatementProvidersList" /></span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"> <property name="<b>conditionsProvider</b>" ref="conditionsProvider" /></span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"> </bean></span><br style="font-family: "Courier New",Courier,monospace;" /><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"> <bean id="conditionsProvider"</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"> class="org.apache.cxf.sts.token.provider.DefaultConditionsProvider"></span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"> <property name="lifetime" value="1200" /></span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"> </bean></span></span><br />
<br />
If you don't configure the DefaultConditionsProvider the default lifetime is 5 minutes. You configure a different lifetime by setting a value in seconds for the property <span style="font-family: "Courier New",Courier,monospace;">lifetime</span>.<br />
<br />
<b><span style="font-family: "Helvetica Neue",Arial,Helvetica,sans-serif;">The Tomcat authenticator doesn't redirect if the security token is expired instead it blocked the incoming request</span></b><br />
<br />
As mentioned in the previous section, the issued SAML token expires after 5 minutes and blocks any incoming request of this user. The lifetime of the HTTP session and the security token can be different in deployments due to different non functional requirements for the application and the security infrastructure. Thus, the application server (Relying Party) should transparently redirect the user to the IDP. Usually, the user still has got a session with the IDP and is not challenged to enter username and password. A new SAML token is issued and sent back to the application server which validates the token and updates the session.<br />
<br />
This fix has been applied in revision <b style="font-weight: normal;">r1222148 <a href="http://svn.apache.org/viewvc/cxf/sandbox/fediz/fediz-tomcat/">here</a>.</b> <br />
<br />
<br />
<a name='more'></a><br />
<br />
<b>New features will come in New Year :-)</b><br />
<br />
<br />
<span style="font-size: large;">Merry Christmas and Happy New Year!</span>Oliver Wulffhttp://www.blogger.com/profile/07294415212532150140noreply@blogger.com2tag:blogger.com,1999:blog-2816919410731663192.post-91386533624820986022011-11-02T08:34:00.004+01:002012-05-02T12:28:17.405+02:00Configure Tomcat for federation - Part III<span style="font-family: Arial,Helvetica,sans-serif;"></span><br />
<span style="font-family: Arial,Helvetica,sans-serif;">I described in the previous blogs how to set up the <a href="http://owulff.blogspot.com/2011/10/configure-and-deploy-identity-provider.html">IDP</a> which plays a key role in Web SSO based on the Passive requestor profile of WS-Federation and the <a href="http://owulff.blogspot.com/2011/10/configure-and-deploy-cxf-25-sts-part-i.html">CXF STS</a> to issue security tokens. The IDP delegates authentication requests to the STS.</span><br />
<br />
<span style="font-family: Arial,Helvetica,sans-serif;">In WS-Federation, the authentication process is externalized to the IDP/STS. It provides you a SAML token (or another security token, WS-Federation is not tight to SAML) which contains all information of the authenticated user you need to implement finer grained authorization requirements without being tight to the user name.</span><br />
<br />
<span style="font-family: Arial,Helvetica,sans-serif;">The information in the SAML token must be integrated in Tomcat in such a way that application developers can use J2EE security as they are used to.</span><br />
<span style="font-family: Arial,Helvetica,sans-serif;">Example:</span><br />
<ul><li><span style="font-family: Arial,Helvetica,sans-serif;">HttpServletRequest.getUserPrincipal()</span></li>
<li><span style="font-family: Arial,Helvetica,sans-serif;">HttpServletRequest.isUserInRole()</span></li>
<li><span style="font-family: Arial,Helvetica,sans-serif;">security constraints in web.xml </span></li>
</ul><span style="font-family: Arial,Helvetica,sans-serif;">There is no need to configure any security related servlets/filters in the web.xml. This is managed on the Tomcat container level to benefit of container managed security.</span><br />
<br />
<span style="font-family: Arial,Helvetica,sans-serif;">It's standardized <a href="http://docs.oasis-open.org/imi/identity/v1.0/identity.html">here</a> how claim information (</span><span style="font-family: Arial,Helvetica,sans-serif;">firstname, lastname, email, etc)</span><span style="font-family: Arial,Helvetica,sans-serif;"> must be represented in an AttributeStatement of a SAML token (assertion) but there is no Java API standard how this information could be accessed by programming. The federation plugin provides an extension of the Tomcat principal class which provides all these information.</span><br />
<span style="font-family: Arial,Helvetica,sans-serif;"></span><br />
<br />
<span style="font-family: Arial,Helvetica,sans-serif;">This blog addresses two topics:</span><br />
<ul><li><span style="font-family: Arial,Helvetica,sans-serif;">how to build and deploy the federation plugin into Tomcat</span></li>
<li><span style="font-family: Arial,Helvetica,sans-serif;">how to build and deploy a federation enabled web application into Tomcat</span></li>
</ul><br />
<span style="font-size: small;"><span style="font-family: Arial,Helvetica,sans-serif;">The plugin has been tested with JDK 1.6 and Tomcat 7.0.</span></span><span style="font-family: Arial,Helvetica,sans-serif;"> </span><br />
<span style="font-family: Arial,Helvetica,sans-serif;"><br />
</span><br />
<span style="font-family: Arial,Helvetica,sans-serif;"><span style="font-size: large;"></span><span style="font-size: small;"></span></span><br />
<span style="font-size: large;"><span style="font-family: Arial,Helvetica,sans-serif;">Build and deploy the federation plugin into Tomcat</span></span><br />
<span style="font-size: small;"><span style="font-family: Arial,Helvetica,sans-serif;">The source code is bundled as maven plugins which can be downloaded <a href="http://svn.apache.org/viewvc/cxf/fediz/trunk/">here</a> and contains the following maven modules:</span></span><br />
<ul><li><span style="font-size: small;"><span style="font-family: Arial,Helvetica,sans-serif;">plugins/core<br />
This module contains the core ws-federation functionality which is container agnostic. The core functionality includes SAML 1.1/2.0 token validation (signature verification), lifetime and audience restriction validation. The FederationProcessor returns all information like roles, claims and authenticated user.</span></span></li>
<li><span style="font-size: small;"><span style="font-family: Arial,Helvetica,sans-serif;">plugins/tomcat<br />
This module contains the tomcat authenticator which integrates the ws-federation functionality into Tomcat. It hydrates the tomcat security context</span></span></li>
<li><span style="font-size: small;"><span style="font-family: Arial,Helvetica,sans-serif;">examples/simpleWebapp/<br />
This is a sample web application where the federation plugin is configured and makes use of security constraints and the Servlet Security API.<br />
This module is described in section "Build and deploy the federation sample application".</span></span></li>
</ul><br />
<span style="font-size: small;"><span style="font-family: Arial,Helvetica,sans-serif;">Run <span style="font-family: "Courier New",Courier,monospace;">mvn clean install</span> in each module to build the jar file.</span></span><br />
<span style="font-size: small;"><span style="font-family: Arial,Helvetica,sans-serif;">After the build, please follow these steps to deploy and configure the federation plugin.</span></span><br />
<br />
<span style="font-size: small;"><span style="font-family: Arial,Helvetica,sans-serif;">1) Create sub-directory fediz in </span></span><span style="font-family: Arial,Helvetica,sans-serif;">${catalina.home}/lib</span><br />
<br />
<span style="font-family: Arial,Helvetica,sans-serif;">2) Update calatina.properties in </span><span style="font-family: Arial,Helvetica,sans-serif;">${catalina.home}/conf</span><br />
<span style="font-family: Arial,Helvetica,sans-serif;">add the previously created directory to the common loader:<br />
common.loader=${catalina.base}/lib,${catalina.base}/lib/*.jar,${catalina.home}/lib,${catalina.home}/lib/*.jar,<b>${catalina.home}/lib/fediz/*.jar</b></span><br />
<span style="font-size: small;"></span><br />
<span style="font-size: small;"><span style="font-family: Arial,Helvetica,sans-serif;">3) Deploy the built libraries and dependencies to the directory created in (1)</span></span><br />
<span style="font-size: small;"><span style="font-family: Arial,Helvetica,sans-serif;">The built libraries and their dependencies can be found in the zip file located in fediz</span></span><span style="font-size: small;"><span style="font-family: Arial,Helvetica,sans-serif;">-tomcat/target/...zip-with-dependencies.zip</span></span><br />
<br />
<span style="font-family: Arial,Helvetica,sans-serif;">4) Configure Federation plugin</span><br />
<span style="font-family: Arial,Helvetica,sans-serif;">The current release of the federation plugin requires to configure the FederationAuthenticator which is configured like any other Valve as described <a href="http://tomcat.apache.org/tomcat-7.0-doc/config/valve.html">here</a>. </span><br />
<br />
<span style="font-family: Arial,Helvetica,sans-serif;">You can either configure the context in the server.xml or in META-INF/context.xml as part of your WAR file.</span><br />
<span style="font-family: Arial,Helvetica,sans-serif;"><br />
<b>server.xml</b><br />
<span style="font-family: "Courier New",Courier,monospace;"> <Context path="/fedizhelloworld" docBase="fedizhelloworld"></span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"> <Valve className="org.apache.cxf.fediz.tomcat.FederationAuthenticator"</span></span><br />
<span style="font-family: Arial,Helvetica,sans-serif;"><span style="font-family: "Courier New",Courier,monospace;"> issuerURL="https://localhost:9443/fedizidp/"</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"> truststoreFile="conf/stsstore.jks"</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"> truststorePassword="stsspass"</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"> trustedIssuer=".*CN=www.sts.com.*" /></span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"> </Context></span><br />
<br />
<b>META-INF/context.xml</b></span><br />
<span style="font-family: Arial,Helvetica,sans-serif;"></span><br />
<span style="font-family: "Courier New",Courier,monospace;"> <Context></span><span style="font-family: Arial,Helvetica,sans-serif;"><span style="font-family: "Courier New",Courier,monospace;"> </span></span><br />
<span style="font-family: Arial,Helvetica,sans-serif;"><span style="font-family: "Courier New",Courier,monospace;"> <Valve className="org.apache.cxf.fediz.tomcat.FederationAuthenticator"</span></span><br />
<span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"> issuerURL="https://localhost:9443/fedizidp/"</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"> truststoreFile="conf/stsstore.jks"</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"> truststorePassword="stsspass"</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"> trustedIssuer=".*CN=www.sts.com.*" /></span><br />
</Context></span><span style="font-family: Arial,Helvetica,sans-serif;"><span style="font-family: "Courier New",Courier,monospace;"> </span></span><br />
<span style="font-family: Arial,Helvetica,sans-serif;"><br />
</span><br />
<span style="font-family: Arial,Helvetica,sans-serif;">The attribute <span style="font-family: "Courier New",Courier,monospace;">issuerURL </span>tells the plugin where to redirect unauthenticated requests which access a protected resource (security constraint matches URI pattern).</span><br />
<span style="font-family: Arial,Helvetica,sans-serif;">The current release of the federation plugin supports SAML 1.1/2.0 tokens. The SAML token is signed to provide a way to establish a trust. The federation plugin must validated the SAML token. The validation process includes verifying whether the certificate has been issued by a trusted CA and whether the certificate subject is trusted. The certificate subject identifies the IDP/STS.</span><br />
<span style="font-family: Arial,Helvetica,sans-serif;">You can have more than one IDP/STS in your company. As soon as you grant B2B partners access (internet) to your web application you have at least 2 IDP/STS instances. Usually, you create a chain of IDP instances where the RP trusts only the internal IDP/STS instance and the internal IDP (so called Relying Party IDP) trusts the external IDP. This scenario is addressed in one of the next blogs.</span><br />
<span style="font-family: Arial,Helvetica,sans-serif;">The attribute <span style="font-family: "Courier New",Courier,monospace;">truststoreFile </span>tells the plugin where the truststore is located (Java Keystore format) and the password is configured in the attribute <span style="font-family: "Courier New",Courier,monospace;">truststorePassword</span>. The trusted IDP/STS is configured as a regular expression in the attribute <span style="font-family: "Courier New",Courier,monospace;">trustedIssuer</span>.</span><br />
<span style="font-family: Arial,Helvetica,sans-serif;"></span><br />
<span style="font-family: Arial,Helvetica,sans-serif;">It's not yet possible to configure a custom security token validator.</span><br />
<span style="font-family: Arial,Helvetica,sans-serif;"><br />
</span><br />
<span style="font-family: Arial,Helvetica,sans-serif;">5) Configure the CA certificates</span><br />
<span style="font-family: Arial,Helvetica,sans-serif;"></span><br />
<span style="font-family: Arial,Helvetica,sans-serif;">If you use the STS as described <a href="http://owulff.blogspot.com/2011/10/configure-and-deploy-cxf-25-sts-part-i.html">here</a> you can copy the keystore from fediz-idp-sts/src/test/resources/stsstore.jks to </span><span style="font-family: Arial,Helvetica,sans-serif;">the configured location in the attribute truststoreFile.</span><br />
<br />
<span style="font-family: Arial,Helvetica,sans-serif;"><i>(you can ignore the fact in this demo that the private key is contained in this keystore also which<b> must not</b> be the case for production. The certificate is sufficient for signature validation)</i></span><br />
<span style="font-family: Arial,Helvetica,sans-serif;"><span style="font-size: large;"></span></span><br />
<span style="font-family: Arial,Helvetica,sans-serif;"><br />
</span><span style="font-size: large;"><span style="font-family: Arial,Helvetica,sans-serif;">Build and deploy the federation sample application</span></span><br />
<span style="font-size: small;"><span style="font-family: Arial,Helvetica,sans-serif;">I've chosen the META-INF/context.xml approach to configure the federation plugin for ease of use.</span></span><br />
<br />
<span style="font-size: small;"><span style="font-family: Arial,Helvetica,sans-serif;">This web application provides three accessible resources:</span></span><br />
<ul><li><span style="font-size: small;"><span style="font-family: Arial,Helvetica,sans-serif;">index.html<br />
This static page is not secured by a security constraint</span></span></li>
<li><span style="font-size: small;"><span style="font-family: Arial,Helvetica,sans-serif;">secure/test.html<br />
This static page is secured by a security constraint in the web.xml</span></span></li>
<li><span style="font-size: small;"><span style="font-family: Arial,Helvetica,sans-serif;">/secureservlet/fed<br />
This servlet provides information about the authenticated user like username, roles and claims as illustrated in the following picture:</span></span></li>
</ul><div class="separator" style="clear: both; text-align: center;"><a href="http://3.bp.blogspot.com/-oQepdA-HNrg/TqgDM_yC-YI/AAAAAAAAABc/OjTSqJgzn_Y/s1600/Screenshot-1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="310" src="http://3.bp.blogspot.com/-oQepdA-HNrg/TqgDM_yC-YI/AAAAAAAAABc/OjTSqJgzn_Y/s640/Screenshot-1.png" width="640" /></a></div><div class="separator" style="clear: both; text-align: center;"><a href="http://3.bp.blogspot.com/-_4qX6_a5Mrg/TqWadgk_f9I/AAAAAAAAABU/u7_0e9WhMEw/s1600/fedservlet.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><br />
</a></div><span style="font-size: small;"><span style="font-family: Arial,Helvetica,sans-serif;"> </span></span><br />
<span style="font-size: small;"><span style="font-family: Arial,Helvetica,sans-serif;">The user and role information can be retrieved using standard J2EE security API. Unfortunately, there is no standard API to retrieve claims information thus the federation plugin provides an extension of the principal which can be accessed as illustrated here:</span></span><br />
<br />
<div style="font-family: "Courier New",Courier,monospace;"><span style="font-size: small;"> Principal p = request.getUserPrincipal(); </span></div><div style="font-family: "Courier New",Courier,monospace;"> if (p instanceof FederationPrincipal) {<br />
FederationPrincipal fp = (FederationPrincipal)p;</div><div style="font-family: "Courier New",Courier,monospace;"><span style="font-size: small;"> ClaimCollection claims = fp.getClaims();</span></div><div style="font-family: "Courier New",Courier,monospace;"><span style="font-size: small;"> ...</span></div><div style="font-family: "Courier New",Courier,monospace;"><span style="font-size: small;"> }</span></div><br />
<span style="font-size: small;"><span style="font-family: Arial,Helvetica,sans-serif;">Every security constraint must define at least one role in auth-constraint as defined in the Servlet specification. There are use cases where you might want to give access to resources to everybody who is authenticated. Therefore, the plugin can add a default role if no roles are provided as part of the SAML token. If not explicitly configured, the default role name is <i>Authenticated</i>.</span></span><br />
<br />
<b><br />
</b><br />
<div style="font-family: "Helvetica Neue",Arial,Helvetica,sans-serif;"><b><span style="font-size: small;">Encoding of roles in SAML token</span></b></div><div style="font-family: "Helvetica Neue",Arial,Helvetica,sans-serif;"><span style="font-size: small;"><br />
</span></div><div style="font-family: "Helvetica Neue",Arial,Helvetica,sans-serif;"><span style="font-size: small;">The federation authenticator provides the following attributes to customize where and how the role information is encoded in the SAML token. The role is like any other claim represented within the attribute statement.</span></div><div style="font-family: "Helvetica Neue",Arial,Helvetica,sans-serif;"><span style="font-size: small;"><br />
</span></div><div style="font-family: "Helvetica Neue",Arial,Helvetica,sans-serif;"><span style="font-size: small;">The IDP/STS in this example uses the following URI for the role claim:</span></div><div style="font-family: "Helvetica Neue",Arial,Helvetica,sans-serif;"><span style="font-size: small;">http://schemas.xmlsoap.org/ws/2005/05/identity/claims/role</span></div><div style="font-family: "Helvetica Neue",Arial,Helvetica,sans-serif;"><br />
</div><div style="font-family: "Helvetica Neue",Arial,Helvetica,sans-serif;">If your IDP/STS stores the role information in another claim, configure the attribute <span style="font-family: "Courier New",Courier,monospace;">roleClaimURI</span> in the FederationAuthenticator. The value of the attribute is a string where the list of roles are delimited by a character. The IDP/STS in this example use "," as the default delimiter. If you want to use another delimiter configure the attribute <span style="font-family: "Courier New",Courier,monospace;">roleDelimiter </span>in the FederationAuthenticator.</div>Oliver Wulffhttp://www.blogger.com/profile/07294415212532150140noreply@blogger.com9tag:blogger.com,1999:blog-2816919410731663192.post-22751718760420901942011-10-20T21:31:00.000+02:002011-10-20T21:31:13.714+02:00How to enable an interceptor without configuration in CXFImagine you develop an interceptor within your company which is for general use and not for a specific business project. There are different ways to configure an interceptor as described in more detail <a href="http://cxf.apache.org/docs/interceptors.html">here</a>. In summary:<br />
<ul><li>by programming</li>
<li>configure the interceptor on the bus, client or endpoint level</li>
<li>configure a feature which registers interceptor(s)</li>
<li>configure a policy which registers interceptors</li>
</ul>There might be use cases where you want to enable an interceptor just because the interceptor is available in the classpath. This means, you developed an interceptor, built a Jar and published to the maven repository. Another project should only add a dependency to your jar in their POM to enable the interceptor automatically. Done.<br />
<br />
This blog will explain how this works and an example can be downloaded <a href="https://docs.google.com/leaf?id=0B39bWm6JgpkfMWFhYzg0ZDAtOTJjMC00NjgxLThlNTctMDQ1MmVjMzlmMDJj&hl=en_US">here</a>.<br />
<br />
CXF 2.4 introduced a new feature called bus extension which are loaded during the initialization phase of a bus automatically. Thus, your interceptor registration code must get notified whenever a new client or server is created to be able to add the interceptor. CXF provides three LifecycleListners:<br />
<ul><li><a href="http://cxf.apache.org/javadoc/latest/org/apache/cxf/buslifecycle/BusLifeCycleListener.html">BusLifeCycleListener</a></li>
<li><a href="http://cxf.apache.org/javadoc/latest/org/apache/cxf/endpoint/ServerLifeCycleListener.html">ServerLifeCycleListener</a></li>
<li><a href="http://cxf.apache.org/javadoc/latest/org/apache/cxf/endpoint/ClientLifeCycleListener.html">ClientLifeCycleListener</a></li>
</ul>This example shows the usage of the Server- and ClientLifecycleListner. A lifecycle listener is registered by the corresponding lifecycle manager which can be resolved using the CXF bus as illustrated in the following code snippet:<br />
<br />
<span style="font-family: "Courier New", Courier, monospace;">public class DemoListener implements ClientLifeCycleListener, ServerLifeCycleListener {</span><br />
<br />
<span style="font-family: "Courier New", Courier, monospace;"><div> public DemoListener(Bus bus) {</div></span><div><span style="font-family: "Courier New", Courier, monospace;"> ServerLifeCycleManager slm = bus.getExtension(ServerLifeCycleManager.class);</span></div><span style="font-family: "Courier New", Courier, monospace;"> slm.registerListener(this);</span><br />
<br />
This class implements the lifecycle listener methods and registers itself to the lifecycle manager. The interceptor could be registered as illustrated in the following code snippet:<br />
<br />
<span style="font-family: "Courier New", Courier, monospace;">public void startServer(Server server) {</span><br />
<span style="font-family: "Courier New", Courier, monospace;"><div> System.out.println("--------- startServer");</div><div> server.getEndpoint().getInInterceptors().add(new DemoInterceptor());</div><div> server.getEndpoint().getOutInterceptors().add(new DemoInterceptor());</div><div>}</div></span><br />
<div></div><span style="font-family: "Courier New", Courier, monospace;">public void clientCreated(Client client) {</span><span style="font-family: "Courier New", Courier, monospace;"></span><br />
<span style="font-family: "Courier New", Courier, monospace;"><div> System.out.println("--------- clientCreated");</div><div> client.getOutInterceptors().add(new DemoInterceptor());</div><div> client.getInInterceptors().add(new DemoInterceptor());</div><div>}</div></span><br />
<div>So far so good, but there must be a way to trigger the instantiation of the class DemoListener. One option is to use Spring and make this class a spring managed component or you register this bean as a CXF bus extension.</div><br />
I'll explain how to register this bean as a bus extension thus it gets instantiated when the bus is created which means that the lifecycle listeners are registered in the startup phase too.<br />
Your Jar file must contain a file called bus-extensions.xml at the following location in the Jar:<br />
<span style="font-family: "Courier New", Courier, monospace;">META-INF/cxf/bus-extensions.txt</span><br />
<br />
The content of this text file is very simple. You just list the classname:<br />
<span style="font-family: "Courier New", Courier, monospace;">org.talend.ps.examples.busextension.DemoListener::false</span><br />
<br />
The last parameter is false which tells the bus whether the instantiation of the bean should be defered or not. If deferred is true, (default) the bus doesn't create the beans during startup. However, if something specifically asks for one of those beans, it will be created and loaded.<br />
<br />
If the class provides a constructor with the Bus argument, CXF will pass the bus during initialization.<br />
<br />
<span style="font-size: large;">Where else is this feature used? In CXF itself.</span><br />
<br />
This was a very simple example how to instantiate beans during bus startup without the requirement for Spring. A lot of the advanced and WS-* features in CXF 2.3 and earlier required that you explicitly imported resources like:<br />
<br />
<span style="font-family: "Courier New", Courier, monospace;"><import resource="classpath:META-INF/cxf/cxf.xml" /></span><span style="font-family: "Courier New", Courier, monospace;"></span><br />
<span style="font-family: "Courier New", Courier, monospace;"><div><import resource="classpath:META-INF/cxf/cxf-extension-soap.xml" /></div><div><import resource="classpath:META-INF/cxf/cxf-servlet.xml" /></div><div><import resource="classpath:META-INF/cxf/cxf-extension-jms.xml" /></div></span><br />
This was required to import the spring configuration files which contained bean definitions which usually implemented lifecycle listeners or support for policy. This is not required any more in CXF 2.4 and above. You only have to import the following resource now:<br />
<br />
<span style="font-family: "Courier New", Courier, monospace;"><import resource="classpath:META-INF/cxf/cxf.xml" /></span><br />
<br />
With CXF 2.4, these features are not plugged into the bus using a spring mechanism but instead the bus extension mechnism as illustrated in the simple example above.<br />
<br />
If you want to see more advanced usage of bus extension have a look to the sources of some of these CXF modules:<br />
<ul><li><a href="http://svn.apache.org/viewvc/cxf/trunk/rt/ws/addr/">WS-Addressing</a></li>
<li><a href="http://svn.apache.org/viewvc/cxf/trunk/rt/ws/rm/">WS-ReliableMessaging</a></li>
<li><a href="http://svn.apache.org/viewvc/cxf/trunk/rt/ws/security/">WS-Security</a></li>
<li><a href="http://svn.apache.org/viewvc/cxf/trunk/rt/ws/policy/">WS-Policy</a></li>
<li>...</li>
</ul><br />
An interesting interceptor example can be found in the <a href="http://www.talend.com/download.php#SF">Talend Service Factory</a>.Oliver Wulffhttp://www.blogger.com/profile/07294415212532150140noreply@blogger.com3tag:blogger.com,1999:blog-2816919410731663192.post-69970451499254847402011-10-18T07:15:00.000+02:002011-10-18T07:15:09.978+02:00Configure LDAP directory for CXF STS<span style="font-family: Arial,Helvetica,sans-serif;">I explained in my previous <a href="http://owulff.blogspot.com/2011/10/configure-and-deploy-cxf-25-sts-part-i.html">blog</a> how to set up the CXF STS where you manage your users and claims in a file.</span><span style="font-family: Arial;">This blog explains the required changes to integrate the CXF STS with a LDAP directory.</span><br />
<br />
<span style="font-family: Arial;">You can attach an LDAP directory either for username/password validation or for retrieving the claims data or both.</span><br />
<br />
<span style="font-family: Arial,Helvetica,sans-serif;"><b>1. Username and password authentication</b></span><br />
<br />
<span style="font-family: Arial,Helvetica,sans-serif;">WSS4j supports username/password authentication against a JAAS based backend since version 1.6.3.</span><br />
<br />
<span style="font-family: Arial;">The JDK provides a <a href="http://ws.apache.org/wss4j/apidocs/org/apache/ws/security/validate/JAASUsernameTokenValidator.html">JAAS LoginModule for LDAP</a> which can be configured as illustrated here in a sample jaas configuration (jaas.config):</span><br />
<span style="font-family: Courier New;"> </span><span lang="DE-CH"></span><br />
<span style="font-family: Courier New;">myldap {</span><br />
<span style="font-family: Courier New;"> com.sun.security.auth.module.LdapLoginModule REQUIRED</span><br />
<span style="font-family: Courier New;"> userProvider=<a href="ldap://ldap.mycompany.org:389/OU=Users,DC=mycompany,DC=org">ldap://ldap.mycompany.org:389/OU=Users,DC=mycompany,DC=org</a>"</span><br />
<span style="font-family: Courier New;"> authIdentity="cn={USERNAME},OU=Users,DC=mycompany,DC=org"</span><br />
<span style="font-family: Courier New;"> useSSL=false</span><br />
<span style="font-family: Courier New;"> debug=true;</span><br />
<span style="font-family: Courier New;">};</span><br />
<br />
<span style="font-family: Arial;">You can get more information about this LoginModule <a href="http://download.oracle.com/javase/6/docs/jre/api/security/jaas/spec/com/sun/security/auth/module/LdapLoginModule.html">here</a>.</span><br />
<br />
<span style="font-family: Arial;">In this example, all the users are stored in the organization unit Users within mycompany.org. The configuration filename can be chosen, i.e. jaas.config. The filename must be configured as a JVM argument. I recommend to set JVM related configurations for Tomcat in the setenv.sh/bat file located in tomcat/bin directory. This script is called by catalina.bat/sh implicitly and might look like this for UNIX:</span><br />
<br />
<div style="font-family: "Courier New",Courier,monospace;">#!/bin/sh </div><div style="font-family: "Courier New",Courier,monospace;">JAVA_OPTS="-Djava.security.auth.login.config=/opt/tomcat/conf/jaas.config"</div><span style="font-family: Courier New;"><span style="font-family: "Courier New",Courier,monospace;">export JAVA_OPTS</span></span><br />
<br />
<span style="font-family: Arial;">Now, the LDAP LoginModule is configured. Next we have to configure the JAASUsernameTokenValidator for the STS endpoint.</span><br />
<br />
<span style="font-family: Courier New;"><bean<br />
class="org.apache.ws.security.validate.JAASUsernameTokenValidator"<br />
id="jaasUTValidator"><br />
<property name="contextName" value="myldap"/><br />
</bean><br />
<br />
<jaxws:endpoint id="transportSTSUT"<br />
endpointName="ns1:TransportUT_Port"<br />
serviceName="ns1:SecurityTokenService"<br />
xmlns:ns1=<a href="http://docs.oasis-open.org/ws-sx/ws-trust/200512/">http://docs.oasis-open.org/ws-sx/ws-trust/200512/</a><br />
wsdlLocation="/WEB-INF/wsdl/ws-trust-1.4-service.wsdl"<br />
address="/STSServiceTransportUT"<br />
implementor="#transportSTSProviderBean"><br />
<br />
<jaxws:properties><br />
<entry key="ws-security.ut.validator"<br />
value-ref="jaasUTValidator"/><br />
</jaxws:properties><br />
</jaxws:endpoint></span><br />
<br />
<span style="font-family: Arial;">The property contextName must match with the context name defined in the JAAS configuration file which is "myldap" in this example.</span><br />
<a class="collapse" href="file:///C:/Users/marianne/AppData/Local/Temp/Temp1_cxf-transport.xml.zip/cxf-transport.xml#" style="color: blue; margin-left: -2em; position: relative;" xmlns="http://www.w3.org/1999/xhtml"><</a><br />
<span style="font-family: Arial,Helvetica,sans-serif;"><b>2. Claims management</b></span><br />
<br />
<span style="font-family: Arial,Helvetica,sans-serif;">When a STS client requests a claim, the ClaimsManager in the STS checks every registered ClaimsHandler who can provide the data of the requested claim.</span><span style="font-family: Arial;"> </span><span style="font-family: Arial;">The CXF STS provides a claims handler implementation which allows to add claims which are stored as user attributes in a LDAP directory. You can configure which claim URI maps to which LDAP user attribute. </span><span style="font-family: Arial;">The implementation uses the spring ldap module (LdapTemplate).</span><br />
<br />
<span style="font-family: Arial;"><span lang="DE-CH"> <span style="font-family: "Courier New",Courier,monospace;"><util:list id="claimHandlerList"></span><br />
<span style="font-family: "Courier New",Courier,monospace;"> <</span><span style="font-family: "Courier New",Courier,monospace;">ref bean="ldapClaimsHandler" /></span><br />
<span style="font-family: "Courier New",Courier,monospace;"> </span><span style="font-family: "Courier New",Courier,monospace;"></util:list></span><br />
<span style="font-family: "Courier New",Courier,monospace;"> </span><br />
<span style="font-family: "Courier New",Courier,monospace;"> <bean id="contextSource"</span><br />
<span style="font-family: "Courier New",Courier,monospace;"> class="org.springframework.ldap.core.support.LdapContextSource"></span><br />
<span style="font-family: Courier New;"> <property name="url" value="ldap://ldap.mycompany.org:389" /></span><br />
<span style="font-family: Courier New;"> <property name="userDn"</span><br />
<span style="font-family: Courier New;"> value="CN=techUser,OU=Users,DC=mycompany,DC=org" /></span><br />
<span style="font-family: Courier New;"> <property name="password" value="mypassword" /></span><br />
<span style="font-family: "Courier New",Courier,monospace;"> </bean></span><br />
<span style="font-family: "Courier New",Courier,monospace;"> </span><br />
<span style="font-family: "Courier New",Courier,monospace;"> <bean id="ldapTemplate" </span><br />
<span style="font-family: "Courier New",Courier,monospace;"> class="org.springframework.ldap.core.LdapTemplate"></span><br />
<span style="font-family: Courier New;"> <constructor-arg ref="contextSource" /></span><br />
<span style="font-family: "Courier New",Courier,monospace;"> </bean></span><br />
<span style="font-family: "Courier New",Courier,monospace;"> </span><br />
<span style="font-family: "Courier New",Courier,monospace;"> <util:map id="claimsToLdapAttributeMapping"></span><br />
<span style="font-family: Courier New;"> <entry</span><br />
<span style="font-family: "Courier New",Courier,monospace;"> </span><span style="font-family: "Courier New",Courier,monospace;">key="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname"</span><br />
<span style="font-family: "Courier New",Courier,monospace;"> </span><span style="font-family: "Courier New",Courier,monospace;">value="givenName" /></span><br />
<span style="font-family: "Courier New",Courier,monospace;"> </span><span style="font-family: "Courier New",Courier,monospace;"><entry key="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/surname"</span><br />
<span style="font-family: "Courier New",Courier,monospace;"> </span><span style="font-family: "Courier New",Courier,monospace;">value="sn" /></span><br />
<span style="font-family: "Courier New",Courier,monospace;"> </span><span style="font-family: "Courier New",Courier,monospace;"><entry</span><br />
<span style="font-family: "Courier New",Courier,monospace;"> </span><span style="font-family: "Courier New",Courier,monospace;">key="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress"</span><br />
<span style="font-family: "Courier New",Courier,monospace;"> </span><span style="font-family: "Courier New",Courier,monospace;">value="mail" /></span><br />
<span style="font-family: "Courier New",Courier,monospace;"> </span><span style="font-family: "Courier New",Courier,monospace;"> <entry key="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/country"</span><br />
<span style="font-family: "Courier New",Courier,monospace;"> </span><span style="font-family: "Courier New",Courier,monospace;">value="c" /></span><br />
<span style="font-family: "Courier New",Courier,monospace;"> </span><span style="font-family: "Courier New",Courier,monospace;"></util:map></span><br />
<span style="font-family: "Courier New",Courier,monospace;"> </span><br />
<span style="font-family: "Courier New",Courier,monospace;"> <bean id="ldapClaimsHandler"</span><br />
<span style="font-family: "Courier New",Courier,monospace;"> class="org.apache.cxf.sts.claims.LdapClaimsHandler"></span><br />
<span style="font-family: "Courier New",Courier,monospace;"> </span><span style="font-family: "Courier New",Courier,monospace;"><property name="ldapTemplate" ref="ldapTemplate" /></span><br />
<span style="font-family: "Courier New",Courier,monospace;"> </span><span style="font-family: "Courier New",Courier,monospace;"><property name="claimsLdapAttributeMapping"</span><br />
<span style="font-family: "Courier New",Courier,monospace;"> ref="claimsToLdapAttributeMapping" /></span><br />
<span style="font-family: "Courier New",Courier,monospace;"> </span><span style="font-family: "Courier New",Courier,monospace;"><property name="userBaseDN"</span><br />
<span style="font-family: "Courier New",Courier,monospace;"> value="OU=Users,DC=mycompany,DC=org" /></span><br />
<span style="font-family: "Courier New",Courier,monospace;"> </span><span style="font-family: "Courier New",Courier,monospace;"></bean></span></span></span><br />
<br />
<span style="font-family: Arial,Helvetica,sans-serif;">The claim id's are configured according to chapter 7.5 in the specification </span><a href="http://docs.oasis-open.org/imi/identity/v1.0/identity.html"><span style="font-family: Arial,Helvetica,sans-serif;"><span style="color: #993300;">Identity Metasystem Interoperability</span></span></a><span style="font-family: Arial,Helvetica,sans-serif;">. You can add as many entries in the map claimsToLdapAttributeMapping as you want. Thus you can add any user attribute from your LDAP directory to the issued SAML token.</span><br />
<span style="font-family: Arial,Helvetica,sans-serif;"><br />
</span>Oliver Wulffhttp://www.blogger.com/profile/07294415212532150140noreply@blogger.com0tag:blogger.com,1999:blog-2816919410731663192.post-41232805832252952072011-10-13T14:30:00.005+02:002012-05-02T12:31:17.654+02:00Configure and deploy Identity Provider (IdP) - Part II<span style="font-family: Arial,Helvetica,sans-serif;">In my previous <a href="http://owulff.blogspot.com/2011/10/configure-and-deploy-cxf-25-sts-part-i.html">blog</a> I talked about setting an STS which supports username/password authentication and the issuance of a SAML 2.0 token which contains additional claims information.</span><br />
<span style="font-family: Arial,Helvetica,sans-serif;">We need these claims information to provide the application (called Relying Party in <a href="http://docs.oasis-open.org/wsfed/federation/v1.2/ws-federation.html">WS-Federation</a> specification) the information like application roles for role based access control. Claims based authorization goes one step further and provides other claims data of the authenticated entity (SAML subject).</span><br />
<br />
<span style="font-family: Arial,Helvetica,sans-serif;"><span style="font-size: large;">Introduction</span> </span><br />
<br />
<span style="font-family: Arial,Helvetica,sans-serif;">This blog is about the Identity Provider (IDP) implementation which is referenced in the WS-Federation specification. Therefore, I'm giving a short introduction. This blog series looks at the passive requestor profile only of WS-Federation.</span><br />
<br />
<span style="font-family: Arial,Helvetica,sans-serif;">The following picture is used by Microsoft which supports WS-Federation in their <a href="http://msdn.microsoft.com/en-us/security/aa570351.aspx">Windows Identity Foundation</a> framework.</span><br />
<span style="font-family: Arial,Helvetica,sans-serif;"><br />
<a href="http://coheigea.blogspot.com/2011/09/talend-donate-security-token-service.html"></a></span><br />
<div class="separator" style="clear: both; text-align: center;"><a href="http://i.msdn.microsoft.com/ff872350.Bustamante_Figure1_hires%28en-us,MSDN.10%29.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="http://i.msdn.microsoft.com/ff872350.Bustamante_Figure1_hires%28en-us,MSDN.10%29.jpg" width="292" /></a></div><span style="font-family: Arial,Helvetica,sans-serif;">(C) Microsoft<br />
<a href="http://coheigea.blogspot.com/2011/09/talend-donate-security-token-service.html"></a></span><br />
<br />
<br />
<b><span style="font-family: Arial,Helvetica,sans-serif;">The key principals of WS-Federation are:</span></b><br />
<ul><li><span style="font-family: Arial,Helvetica,sans-serif;">Externalize authentication process from the application container</span></li>
<li><span style="font-family: Arial,Helvetica,sans-serif;">Provide the claims/attributes of the authenticated identity to the application for role based and fine grained authorization</span></li>
</ul><b><span style="font-family: Arial,Helvetica,sans-serif;">WS-Federation gives you the following benefits:</span></b><br />
<ul><li><span style="font-family: Arial,Helvetica,sans-serif;">Applications can benefit of stronger security mechanism without changes</span></li>
<li><span style="font-family: Arial,Helvetica,sans-serif;">Identities/users don't have to be provisioned in all security domains to propagate identities across the security domains</span></li>
<li><span style="font-family: Arial,Helvetica,sans-serif;">B2B partners can be integrated without changing the application (includes programming and configuration)</span></li>
<li><span style="font-family: Arial,Helvetica,sans-serif;">Audit-Trail end-to-end</span></li>
</ul><span style="font-family: Arial,Helvetica,sans-serif;"> </span><br />
<ul></ul><span style="font-family: Arial,Helvetica,sans-serif;"> <a href="http://coheigea.blogspot.com/2011/09/talend-donate-security-token-service.html"></a></span><br />
<span style="font-family: Arial,Helvetica,sans-serif;"><span style="font-size: large;">Deploy Identity Provider (IdP)</span><br />
<a href="http://coheigea.blogspot.com/2011/09/talend-donate-security-token-service.html"></a></span><br />
<span style="font-family: Arial,Helvetica,sans-serif;"><br />
<a href="http://coheigea.blogspot.com/2011/09/talend-donate-security-token-service.html"></a></span><br />
<span style="font-family: Arial,Helvetica,sans-serif;">This sample IDP will support the following functionality:</span><br />
<ul><li><span style="font-family: Arial,Helvetica,sans-serif;">Authentication based on username/password (Basic Authentication)</span></li>
<li><span style="font-family: Arial,Helvetica,sans-serif;">The authentication store is configured in the STS and can be file based (part of this example) or LDAP</span></li>
<li><span style="font-family: Arial,Helvetica,sans-serif;">Following federation parameters are supported:</span></li>
<ul><li><span style="font-family: Arial,Helvetica,sans-serif;">wtrealm</span></li>
<li><span style="font-family: Arial,Helvetica,sans-serif;">wreply</span></li>
<li><span style="font-family: Arial,Helvetica,sans-serif;">wctx</span></li>
<li><span style="font-family: Arial,Helvetica,sans-serif;">wresult</span></li>
</ul><li><span style="font-family: Arial,Helvetica,sans-serif;">Required claims can be configured per Relying Party (based on wtrealm value)<i><br />
</i></span></li>
</ul><span style="font-family: Arial,Helvetica,sans-serif;"><a href="http://www.noveit.ch/">Jürg Portmann</a> and myself have put together this IDP. You can download the maven project services/idp <a href="http://svn.apache.org/viewvc/cxf/fediz/trunk/services/idp/">here</a>.</span><br />
<span style="font-family: Arial,Helvetica,sans-serif;"></span><br />
<br />
<span style="font-family: Arial,Helvetica,sans-serif;"><b>1. Claims configuration per relying party</b></span><br />
<br />
<span style="font-family: Arial,Helvetica,sans-serif;">The required claims per relying party are configured in the WEB-INF/RPClaims.xml. </span>The XML file has the following structure. The key of each map entry must match with the <span style="font-family: "Courier New",Courier,monospace;">wtrealm</span> paramater in the redirect triggered by the relying party.<br />
(the set up of the relying part will be covered in the next blog).<br />
<br />
<span style="font-family: Arial,Helvetica,sans-serif;"></span><br />
<span style="font-family: "Courier New",Courier,monospace;"> <util:map id="realm2ClaimsMap"><br />
<entry key="http://localhost:8080/wsfedhelloworldother/"<br />
value-ref="claimsWsfedhelloworld" /><br />
<entry key="http://localhost:8080/wsfedhelloworld/"<br />
value-ref="claimsWsfedhelloworldother" /><br />
</util:map><br />
<br />
<util:list id="claimsWsfedhelloworld"><br />
<value>http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname<br />
</value><br />
<value>http://schemas.xmlsoap.org/ws/2005/05/identity/claims/surname<br />
</value><br />
</util:list><br />
<br />
<util:list id="claimsWsfedhelloworldother"><br />
<value>http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname<br />
</value><br />
<value>http://schemas.xmlsoap.org/ws/2005/05/identity/claims/surname<br />
</value><br />
<value>http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress<br />
</value><br />
</util:list> </span><br />
<br />
You group the required claims in beans which are a list of String as illustrated in <span style="font-family: "Courier New",Courier,monospace;">claimsWsfedhelloworld </span>and <span style="font-family: "Courier New",Courier,monospace;">claimsWsfedhelloworldother</span>.<br />
<br />
The map bean must be named <span style="font-family: "Courier New",Courier,monospace;">realm2ClaimsMap </span>and maps the different relying parties (applications) to one of the claim lists.<br />
<br />
<br />
<span style="font-family: Arial;">In a further release, this information will be pulled from a WS-Federation Metadata document published by the replying party. </span><br />
<br />
<br />
<span style="font-family: Arial;"><span style="font-family: Arial,Helvetica,sans-serif;"><b>2. Project dependencies</b></span></span><br />
<span style="font-family: Arial;"><span style="font-family: Arial,Helvetica,sans-serif;"><b> </b></span><br />
<span style="font-family: Arial,Helvetica,sans-serif;">The IDP reuses a lot of existing projects like Apache CXF to communicate with the STS for instance and provides an adaption of the WS-Trust interface to pure HTTP functionality as it is supported by a browser. The IDP has the following dependencies in the Maven project:</span></span><br />
<br />
<div style="font-family: "Courier New",Courier,monospace;"> <properties><br />
<cxf.version>2.5.2</cxf.version><br />
</properties></div><div style="font-family: "Courier New",Courier,monospace;"><br />
</div><div style="font-family: "Courier New",Courier,monospace;"> <dependencies></div><span style="font-family: Arial;"><span style="font-family: Arial,Helvetica,sans-serif;"> <span style="font-family: "Courier New",Courier,monospace;"> <dependency></span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"> <groupId>org.apache.cxf</groupId></span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"> <artifactId>cxf-rt-transports-http</artifactId></span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"> <version>${cxf.version}</version></span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"> </dependency></span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"> <dependency></span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"> <groupId>org.apache.cxf</groupId></span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"> <artifactId>cxf-rt-frontend-jaxws</artifactId></span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"> <version>${cxf.version}</version></span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"> </dependency></span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"> <dependency></span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"> <groupId>org.apache.cxf</groupId></span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"> <artifactId>cxf-rt-ws-policy</artifactId></span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"> <version>${cxf.version}</version></span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"> </dependency></span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"> <dependency></span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"> <groupId></span></span></span><span style="font-family: Arial;"><span style="font-family: Arial,Helvetica,sans-serif;"><span style="font-family: "Courier New",Courier,monospace;">org.apache.cxf</span></span></span><span style="font-family: Arial;"><span style="font-family: Arial,Helvetica,sans-serif;"><span style="font-family: "Courier New",Courier,monospace;"></groupId></span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"> <artifactId></span></span></span><span style="font-family: Arial;"><span style="font-family: Arial,Helvetica,sans-serif;"><span style="font-family: "Courier New",Courier,monospace;">cxf-rt-ws-security</span></span></span><span style="font-family: Arial;"><span style="font-family: Arial,Helvetica,sans-serif;"><span style="font-family: "Courier New",Courier,monospace;"></artifactId></span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"> <version>${cxf.version}</version></span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"> </dependency></span></span></span><br />
</dependencies><span style="font-family: Arial;"><span style="font-family: Arial,Helvetica,sans-serif;"><span style="font-family: "Courier New",Courier,monospace;"> </span></span></span><br />
<span style="font-family: Arial;"><br />
</span><br />
<span style="font-family: Arial,Helvetica,sans-serif;"><b>3. IDP web application configuration</b></span><br />
<br />
<span style="font-family: Arial,Helvetica,sans-serif;">Setting up the IDP involves a few steps only. If you you don't deploy the IDP in the same servlet container as the STS you must first download <a href="http://tomcat.apache.org/download-70.cgi">Tomcat 7</a> and update server.xml. If you deploy the IDP in the same servlet container you can skip 3.1</span><br />
<br />
<b><span style="font-family: Arial;">3.1 Configure HTTP/S connector in Tomcat </span></b><br />
<br />
<span style="font-family: Arial;">The HTTP connector should be configured with port 9080.</span><br />
<span style="font-family: Arial;"><br />
</span><br />
<span style="font-family: Arial;">The HTTPS connector in Tomcat is configured in conf/server.xml. Deploy the tomcatkeystore.jks of the example project to the Tomcat root directory if the Connector is configured as illustrated:</span><br />
<br />
<div style="font-family: "Courier New",Courier,monospace;"> <Connector port="9443" protocol="HTTP/1.1" SSLEnabled="true" <br />
maxThreads="150" scheme="https" secure="true" <br />
keystoreFile="tomcatKeystore.jks" <br />
keystorePass="tompass" sslProtocol="TLS" /></div><br />
<i>This connector configures a self-signed certificate which is used for simplification only. You should get a certificate signed by a Certificate Authority for production usage.</i><br />
<br />
<span style="font-family: Arial,Helvetica,sans-serif;"><b>3.2 Configure Username/password authentication</b></span><br />
<span style="font-family: Arial,Helvetica,sans-serif;"></span><br />
<br />
<span style="font-family: Arial,Helvetica,sans-serif;">As described in section 1. the requested claims per relying party are managed in the file WEB-INF/RPclaims.xml.</span><br />
<br />
<span style="font-family: Arial;"><span style="font-family: Arial,Helvetica,sans-serif;"><b>3.3 IDP and STS distribute<span style="font-family: Arial;">d</span></b></span></span><br />
<span style="font-family: Arial;"><span style="font-family: Arial,Helvetica,sans-serif;"><b><span style="font-family: Arial;"> </span></b></span> </span><br />
<span style="font-family: Arial;"> <span style="font-family: Arial,Helvetica,sans-serif;">If the IDP and STS are not deployed on the same machine (likewise in production) you have to update the following configuration:</span><br />
</span><br />
<span style="font-family: Arial;"></span><br />
<span style="font-family: Arial;"></span><br />
<span style="font-family: Arial;"></span><br />
<span style="font-family: Arial;"></span><br />
<br />
<span style="font-family: Arial;">1) The remote WSDL location of the STS:</span><br />
<span style="font-family: Arial;"> </span><br />
<span style="font-family: Arial;">WEB-INF/web.xml:</span><br />
<br />
<div style="font-family: "Courier New",Courier,monospace;"> <init-param><br />
<param-name>sts.wsdl.url</param-name><br />
<param-value>https://localhost:9443/wsfedidpsts/STSService?wsdl</param-value><br />
</init-param></div><span style="font-family: Arial;"> </span><br />
<span style="font-family: Arial;"> </span><br />
<span style="font-family: Arial;">2) the transport conduit to enable the truststore as described in more detail <a href="http://cxf.apache.org/docs/client-http-transport-including-ssl-support.html#ClientHTTPTransport%28includingSSLsupport%29-ConfiguringSSLSupport">here</a>:</span><br />
<span style="font-family: Arial;"><br />
</span><br />
<div style="font-family: "Helvetica Neue",Arial,Helvetica,sans-serif;">WEB-INF/beans.xml</div><br />
<span style="font-family: Arial;"><span style="font-family: "Courier New",Courier,monospace;"> <http:conduit name="https://localhost:9443/.*"></span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"> <http:tlsClientParameters disableCNCheck="true"></span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"> <sec:trustManagers></span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"> <sec:keyStore type="jks" password="cspass" resource="clientstore.jks"/></span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"> </sec:trustManagers></span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"> </http:tlsClientParameters></span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"> </http:conduit></span></span><br />
<span style="font-family: Arial;"></span><br />
<span style="font-family: Arial;"><br />
</span><br />
<span style="font-family: Arial;">3) fully qualified realm in realm2ClaimsMap</span><br />
<span style="font-family: Arial;"><br />
</span><br />
<span style="font-family: Arial;">As described in 1) the key of an entry in the map </span><span style="font-family: Arial;"><span style="font-family: "Courier New",Courier,monospace;">realm2ClaimsMap</span> must match with the <span style="font-family: "Courier New",Courier,monospace;"></span> parameter </span><span style="font-family: Arial;"><span style="font-family: "Courier New",Courier,monospace;">wtrealm</span></span><span style="font-family: Arial;"> in the redirect triggered by the relying party. If you access the relying party using a fully qualified URL, you must use the fully qualified URL in the IDP too.</span><span style="font-family: Arial;"> </span><br />
<span style="font-family: Arial;"><br />
</span><br />
<span style="font-family: Arial;">WEB-INF/RPclaims.xml</span><br />
<span style="font-family: Arial;"><br />
</span><br />
<span style="font-family: Arial;"> <util:map id="realm2ClaimsMap"><br />
<entry key="http://localhost:8080/wsfedhelloworldother/"<br />
value-ref="claimsWsfedhelloworld" /><br />
<entry key="http://localhost:8080/wsfedhelloworld/"<br />
value-ref="claimsWsfedhelloworld2" /><br />
</util:map><br />
</span><br />
<span style="font-family: Arial,Helvetica,sans-serif;"></span><br />
<br />
<span style="font-family: Arial,Helvetica,sans-serif;"><b>4. Deploy the IDP to Tomcat</b></span><br />
<br />
<span style="font-family: Arial,Helvetica,sans-serif;">To deploy the IDP using Maven you have to follow these steps:</span><br />
<ul><li><span style="font-family: Arial,Helvetica,sans-serif;">Configuring the following maven plugin</span><span style="font-family: "Courier New",Courier,monospace;"><br />
<plugin><br />
<groupId>org.codehaus.mojo</groupId><br />
<artifactId>tomcat-maven-plugin</artifactId><br />
<version>1.1</version><br />
<configuration><br />
<server>myTomcat</server><br />
<url>http://localhost:9080/manager/text</url><br />
<path>/${project.build.finalName}</path><br />
</configuration><br />
</plugin></span></li>
<span style="font-family: "Courier New",Courier,monospace;"></span>
<li><span style="font-family: Arial,Helvetica,sans-serif;">Add the server with username and password to your settings.xml</span></li>
<li><span style="font-family: Arial,Helvetica,sans-serif;">Ensure the user has the role "manager-script" as described </span><a href="http://tomcat.apache.org/tomcat-7.0-doc/manager-howto.html#Configuring_Manager_Application_Access"><span style="font-family: Arial,Helvetica,sans-serif;">here</span></a></li>
<li><span style="font-family: Arial,Helvetica,sans-serif;">Run mvn tomcat:redeploy<br />
(I recommend to use redeploy as deploy works the first time only)</span></li>
</ul><span style="font-family: Arial,Helvetica,sans-serif;">If you use Tomcat 6, you must change the url of the tomcat maven plugin:</span><br />
<span style="font-family: Courier New;"> <url>http://localhost:9080/manager</url></span><br />
<br />
<br />
<span style="font-family: Arial,Helvetica,sans-serif;"><b>4. Test the IDP</b></span><br />
<br />
<span style="font-family: Arial,Helvetica,sans-serif;">As long as you don't have a relying party in place you can't easily test the IDP. The following <a href="http://owulff.blogspot.com/2011/11/configure-tomcat-for-federation-part.html">post</a> explains the set up of the relying party using Tomcat 7. </span><br />
<span style="font-family: Arial,Helvetica,sans-serif;"><br />
</span><br />
<span style="font-family: Arial,Helvetica,sans-serif;">If you like you can test the IDP by using an HTTP client and pass the following request parameters (urls must be encoded):</span><br />
<br />
<div style="font-family: "Courier New",Courier,monospace;">wa wsignin1.0</div><div style="font-family: "Courier New",Courier,monospace;">wreply http://localhost:8080/wsfedhelloworld/secureservlet/fed</div><div style="font-family: "Courier New",Courier,monospace;">wtrealm http://localhost:8080/wsfedhelloworld/</div><span style="font-family: Arial,Helvetica,sans-serif;"><br />
</span><br />
<span style="font-family: Arial,Helvetica,sans-serif;">The browser will get a HTML form back (auto-submit). The action of the form is equal to the value of wreply which doesn't exist. You see the response of the STS escaped in the form parameter wresult.</span>Oliver Wulffhttp://www.blogger.com/profile/07294415212532150140noreply@blogger.com1