March 7, 2012

WS-Federation across several companies

I described a simple scenario about the WS-Federation Passive Requestor Profile in my previous blogs:
Before I describe a more complex scenario, I'd like to summerize the benefits of the simple scenario:
  • Authentication is externalized to IdP/STS
  • New IdP authentication mechanism can be used by all applications
  • Role Based Access control (RBAC) supported in applications
  • Claims/Attrribute based acess control (ABAC) supported in applications
  • IDP and applications deployable in different networks (ex. on-premise and cloud)
  • Easy testing with Mock IdP


Federation with B2B partners in the internet

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.



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.


How does this work? Let's look at a concrete example.


Our federation enabled web application should be provided to two new partners (fabrikam.com and adatam.com).


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:
  • mycompany.com
    - 10000 users

    - five roles (user, manager, sales, accountmanager, admin)

  • adatam.com
    - IDP supported

    - 2000 users

    - three roles (employee, manager, administrator)

  • fabrikam.com
    - IDP supported
    with restrictions (SAML token contains user only)
    - 50 users

    - two roles (user, accountmanager)
The three companies have their own kind of naming for roles but the application must not differentiate between the different kind of role semantic.
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.


The following deployment diagram illustrates the solution:



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.


adatam.com 
What happens with the different kind of syntax of the roles?
The RP-IDP transforms the roles from the requestor IDP to the internal set of roles.
  • employee -> user
  • manager -> manager
  • administrator -> admin
fabrikam.com
How can the RP-IDP get the roles of the users?
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.


mycompany.com
Nothing changes.


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.


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.




Support for identity mapping and claims transformation in STS


The STS is the key component in the WS-Federation based solution who issues the security tokens. The CXF STS supports identity mapping in the release 2.5.x.


I've finished my work to add support for claims transformation in the CXF STS.

Soon, I'll provide more details how to configure an STS with several realms (security domains) and different federation relationships among them.

7 comments:

  1. How would you cater for different policies in different security domains eg different authentication mechanism?

    ReplyDelete
    Replies
    1. The WS-Federation spec defines the parameter "wauth" where you can tell the IDP what kind of authentication mechanism is required by the web application (ex. 2factor authentication). The AuthStatement of a SAML token can contain information about the authentication method.
      Other policy information can be retrieved in the published Metadata document.
      I've published a roadmap in the CXF Dev List about the features plan:
      http://cxf.547215.n5.nabble.com/Roadmap-for-fediz-in-sandbox-tp5603441p5603441.html

      Delete
  2. Hi Oliver. Is there any way that we can pass user name and password of apache syncope in apache cxf fediz project file UsernamePasswordCallbackHandler.java.While passing this syncope client user name and password token is not generated and shows failing authenticated. details.

    ReplyDelete
    Replies
    1. Hi
      In such a scenario I recommend that you don't store username/passwords in a spring configuration file. Instead, you could consider in setting up an LDAP directory (or a DB) to which you can connect the Fediz STS as well as Syncope. I do have the LDAP scenario running as well.

      Delete
  3. Hi Thanks ..
    when ever I am calling Syncope Client in Usernamepasswordcallback handler to access i am getting error like cannot instantiate "ststransport1" bean which is present in cxf-transport.xml file. I want to authenticate username and password using syncope client User Service.If we make changes in this Usernamepasswordcallback handler is that fine is there any where else do we need to make changes.





    ReplyDelete
  4. Hi Oliver,
    I need to call Syncope REST Services so that When ever i am passing Username/Password in browser that should authenticate with Syncope User Service Credentials. When i am calling Syncope Client i am getting error. Can you please guide me to resolve this issue as i am trying this from past 10 days. Generating SAML2 Token when using Our application with Fediz STS is working fine.But when i am callingSyncope REST Services in USERNamePasswordCallbackHandler. I am getting below error.

    org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'transportSTS1': Invocation of init method failed; nested exc
    tion is javax.xml.ws.WebServiceException: org.apache.cxf.bus.extension.ExtensionException: Could not create object of extension class org.apache.cxf
    sdl11.WSDLManagerImpl.
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1554)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:539)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:475)
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:302)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:229)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:298)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193)
    at at

    ReplyDelete
    Replies
    1. Hi there
      I think you want to set up a use case my collegue Colm blogged about it:
      http://coheigea.blogspot.com/2014/11/apache-syncope-12-tutorial-part-iv.html

      I'd recommend to post your questions to the cxf user mailing list:
      http://cxf.apache.org/mailing-lists.html

      HTH

      Oli

      Delete