Friday, June 28, 2013

How SAML2 Single Logout Works

First, lets understand the single logout work flow that is initiated by SP


 Please note here,  i am using following diagram (This is copied from specification).  Here IDP is referred to SAML2 SSO Identity Provider and SP is referred to SAML2 SSO Service Provider

Profile Overview 







1.  LogoutRequest issued by SP to  IDP


2.  IDP determines authenticated SPs for given user session.  If there are no SPs, other than the SP who sends logout request, the profile proceeds with step 5. 


Otherwise, steps 3 and 4 are repeated for each SP 

3. LogoutRequest issued by IDP to SP


4. SP issues LogoutResponse to IDP


5. IDP issues LogoutResponse to SP who sends logout request


Let see what is in these requests and response messages 


Logout Request


LogoutRequest is extend from RequestAbstractType.  


There are some attributes that must be in the RequestAbstractType element 

1. ID   - An identifier for the request. This must be unique.  Basically a random number. 


2. Version  - Indicate SAML version 


3. IssueInstant - Time instant of issue of the request. The time value is encoded in UTC


Apart from that,  One of following is a required attribute for LogoutRequest request...

4. BaseID or NameID or EncryptedID  


This indicate the principle (user identifier).  Basically name that is known to both IDP and SP. 


Also there are few optional elements


5. NotOnOrAfter  - The time at which the request expires in UTC


6. Reason  -  reason for the logout, in the form of a URI reference.


There are two standard reasons 


urn:oasis:names:tc:SAML:2.0:logout:user  - user terminates session and initiates logout

urn:oasis:names:tc:SAML:2.0:logout:admin - admin terminates session and initiates logout

7. SessionIndex  - This is the session identifier that is used to identify the user session with both IDP and SP for given user.



Logout Repsonse


LogoutRepsonse is extend from StatusResponseType.  There are some attributes that must be in the StatusResponseType element.  i.e.  ID, Version and IssueInstant which is same as in RequestAbstractType. There is element called Status  element that is required.  Status element would contain the status code corresponding to the request. 



Sample Scenario


Lets take sample scenarios to explain how IDP and SPs handle the single logout scenario. Here we assume that there are IDP and two SPs; i.e called as SP1 and SP2 


Please note all request response messages must be signed or otherwise authenticated and integrity protected by the under line protocol. 


1.  User is trying access SP1 and user has no authenticated session, therefore user is redirected to IDP


2. IDP has no authenticated session for user. Therefore user would be authenticated with user store.    


3. After successful authentication; 


IDP creates SAML token based on user and user's attributes.  

IDP creates a session for user and IDP that is normally called as SSO session.  This SSO session is uniquely identified by session Id (which would be sent in assertion as SessionIndex) and the user. SSO session would contain details about the SP1.  Mostly SSO session would be persisted by the IDP

4. User is redirected to SP1 with SAML Response. 


Here we are interesting in followings element in the SAML Assertion 


a) Subject   -   This is used to identify the authenticated User. Mostly NameID is used for this.  Basically this is user name of the authenticated user. 

 
admin
b) AuthnStatement  -  This provides some statement describing how subject has been authenticated with IDP. 
 


urn:oasis:names:tc:SAML:2.0:ac:classes:Password


 Here user has been authenticated by providing password.  Also it specifies the session identifier of the session that has been created with IDP and user, using SessionIndex attribute 

5. If SAML response is valid, SP1 would create session for user and SP1.  Then, created session would be map with the received SessionIndex value.


6. Now same user is trying to access SP2. 
and user has no authenticated session, therefore user is redirected to IDP

7. IDP has an authenticated SSO session for user and IDP. Therefore SAML token is created.  SSO session would be updated with SP2 details. 


8. User is redirected to SP2 with SAML Response.   SAML Assertion would be same as 
we discussed in step4

9. If SAML response is valid, SP2 would create session with user and SP2.  Then, created session would be map with the received SessionIndex.


Now lets see single logout scenario....


10. User is trying to logout from SP1. Then LogoutRequest is sent to IDP from SP1.  


Lets see what should be in this request. 


Basically,  SP1 need to provided the SSO session that is associated with IDP and the User. 


SP1 could finds out, received SessionIndex id and NameID for the user. As these details has been kept in SP's  session


Then creates LogoutRequest based on that.. 


Sample LogoutRequest would be as follows

 

admin
26C0530CBEA1DCF404C95B029D6A64AF
 
11. IDP validates LogoutRequest and If valid, it finds out the associate SSO session for given SessionIndex and that also is matched with NameID 

12. IDP identifies the SPs that have been authenticated for the user from the SSO session.   Then IDP sends LogoutRequest to each SP (other than SP1) with corresponding SessionIndex and NameID


Therefore same LogoutRequest that is discussed in step10 would be sent to SP2 from IDP


13. SP2 validates and processes LogoutRequest. SP2 invalidates the session that is associated with SessionIndex and is matched with NameID 

14. SP2 sends LogoutResponse  to IDP with the status of success


15. IDP validates the LogoutResponse  and tracks on received status

16. Finally IDP invalidates SSO session  that is  associated with SessionIndex and 
is matched with NameID 

17. IDP sends  LogoutResponse to SP1  


If all are success 
LogoutResponse would be with status code   

urn:oasis:names:tc:SAML:2.0:status:Success


If SP2 sends an error status in LogoutResponse, then with status code


urn:oasis:names:tc:SAML:2.0:status:PartialLogout


If any other error, it would be with error status code.



I guess,  this would help you to understand how single logout must be implemented. Basically , if i simplify, this in code level... 

In IDP implementation, There must be a some kind of SSO session (session between User and IDP) persistence method. It can be a simple in-memory Map;  
with SessionIndex (session Id) as the key and session as the value of the Map. Please find sample implementation from here     

In SP implementation. There must be a some kind of user session (session between User and SP) persistence method. It can be a simple in-memory Map; 
with SessionIndex (received SessionIndex in Assertion) as the key and user session as the value of the Map. Please find sample implementation from here    

With WSO2 Identity Server 4.5.0 release, you could find sample web apps that demonstrate single logout functions.   

Wednesday, November 21, 2012

Identity management feature with WSO2 Identity Server


Identity management feature is a separate feature that is shipped as carbon feature that can be installed with WSO2 Identity server.  This is one of powerful feature that shows the extensibility of  WSO2 Carbon platform.  i.e.  This feature is an implementation of a listener interface in carbon user kernel. These listener implementations would be executed before of after a user kernel action is done such as adding user,  authentication and so on.    

Before going in to more implementation details,  In this blog post, let see what is supported by this feature by default. But always you can extend these as you wish.

Some of the features that is included...

1. User account verification methods
2. Password recovery methods
3. User account recovery methods.
4. Account locking / unlocking

Let see how we can install Identity management feature with WSO2 Identity Server 4.0.0

Lets Start from a fresh pack of WSO2 Identity Server 4.0.0 release which can be found at here

Step1 : Start server by running wso2server script file and login to management console 

Step2 : Go to feature manager UI and configure P2 repository which is available online


Step3 : Search for identity management feature 



Step4 : Install it by going through required steps. 



Step5 : Restart the server.



However due to following error, P2 installation would not work out of the box which would probably be fixed in next release.


Therefore you need to go through following additional step to get this work. 

1. Do proper attribute mapping with your user store 
2. Delete current database and create new one and start server with -Dsetup option (Basically you need to point to a new registry and user mgt database)
3. Uninstall SCIM feature from WSO2 Identity server. 

After this installation,  you would see new UI links with WSO2 Identity Server.  But most important thing is the APIs. There are two web service API, that has been deployed with identity management feature. These two API can be used by external application to implement identify management use cases.





Also there are some new configurations that you need to know in following configuration files

user-mgt.xml file

     Email and Captcha are used for account and password recovery processes. Therefore actual applications (may be application that uses WSO2 Identity Server API) can handle email sending and capatcha management as they like. Or else it can be delegated to WSO2 Identity server using following properties   
   
<Property name="emailSendingInternallyManaged">true</Property>
<Property name="captchaVerificationInternallyManaged">true</Property>

     After maximum number of failed login attempts, user account must be locked.  No of attempts can be configured. 

<Property name="maxFailedLoginAttempt">3</Property>

    When using temporary or one time password to create a user account, password can be configured as follows

<Property name="defaultPassword">123456</Property>


claim-config.xml 

There are new user attribute values that have been introduced with this feature. We need to properly configure those

email-admin-config.xml

If email is sent by WSO2 Identity Server, we need to configure the contain of it.  By using this file, we can configure it for different use cases. 

axis2.xml 

  If email is sent by WSO2 Identity Server, you need to configure axis2 email sender configurations 


        wso2is@gmail.com 
        wso2is 
        222222
        smtp.gmail.com

        587
        true
        true
     

Monday, November 12, 2012

Multiple user store manager feature with WSO2 Identity Server 4.0.0


This is powerful feature which is shipped with WSO2 Identity Server 4.0.0 release. With that feature, you are able to configure more than one user store with WSO2 Identity Server. User stores can be LDAP, JDBC or AD or combination of different user stores. Also it can be configured both read/write and read only modes.

I am going to use this feature to configure  LDAP with multiple OU (Organization Units) Where each OU is treated as different user store. There are some scenario where we want to treat OU as a separate user store by WSO2 Identity Server. As an example,  we want to connect different OUs, to WSO2 Identity Server with read-write mode and user must be created in a defined OU. 

First let assume our exiting LDAP structure as following....  where we have  three OU under the "pathberiya.com" domain (i.e dc=pathberiya, dc=com).  Each OU contains users and these users are assign to roles, i.e under the "pathberiya.com" domain.  Also there are users who are under the "pathberiya.com" domain. 





Step1.  Identify different OUs that must be connected with WSO2 Identity Server.  in above sample,  it would be 

ou=users,dc=pathberiya,dc=com,ou=system
ou=users,ou=it,dc=pathberiya,dc=com,ou=system
ou=users,ou=sales,dc=pathberiya,dc=com,ou=system
ou=users,ou=marketing,dc=pathberiya,dc=com,ou=system


Step2.  Creating user store configurations for each OU.  As each OU is treated as a user store,  So we need to create separate user store manager configurations and configure them in the user-mgt.xml file which can be found at <IS_HOME>/repository/conf directory.

(i) WSO2 Identity server identify each user store using a domain name. lets assign domain names for each OU. (any name what you prefer)

dc=pathberiya,dc=com,ou=system        ========== >    pathberiya.com
ou=users,ou=it,dc=pathberiya,dc=com,ou=system              ======= >    it.com
ou=users,ou=sales,dc=pathberiya,dc=com,ou=system         ======= >   sales.com
ou=users,ou=marketing,dc=pathberiya,dc=com,ou=system  ======= >    marketing.com 

Please note in  "pathberiya.com" domain,  all users in the four OUs can be seen.

(ii) We need to identify one user store as the primary user store.  Primary user store must be configured as the first user store configuration in the user-mgt.xml file. Let see what are the functions of primary user store.
  • If domain name is not defined for user,  then user is 1st authenticated with primary user store, If it is not successful,  then user is authenticated with other user store according to the order that has been configured in user-mgt.xml file.
  • User Management UI of the WSO2 Identity server is loaded from this user store. Basically User Management UI does not show users of other user store.
So as all users are defined for  "pathberiya.com" domain,  we set this domain as primary user store.

(iii) Then lets identify role search based for WSO2 Identity Server's roles.

ou=roles,dc=pathberiya,dc=com,ou=system

(iv) Then we need to identify the admin user and role for WSO2 Identity Server from above user stores (OUs)

let select  user called "adminUser" in primary user store as the admin user for WSO2 Identity Server. And  "admin" role in  ou=roles,dc=pathberiya,dc=com,ou=system as admin role  for WSO2 Identity Server.

lets see our final configuration of the user-mgt.xml file.  Please fine here 

Basically you can create one user store configuration as following and you can create others user store configurations for each OUs  easily by changing  the "UserSearchBase" , "UserDNPattern" and "DomainName" attributes. 
 
            ldap://localhost:10389
            uid=admin,ou=system
            secret
            (objectClass=person)
     inetOrgPerson
            ou=users,ou=it,dc=pathberiya,dc=com,ou=system
            (&(objectClass=person)(uid=?))
            uid
     [a-zA-Z0-9._-]{3,30}$
            ^[\\S]{3,30}$
     ^[\\S]{3,30}$
            [a-zA-Z0-9._-]{3,30}$
            ^[\\S]{5,30}$
     true
     true
     false
            ou=roles,dc=pathberiya,dc=com,ou=system
            (objectClass=groupOfNames)
            groupOfNames
            (&(objectClass=groupOfNames)(cn=?))
            cn
            member
            true
     true
            uid={0},ou=users,ou=it,dc=pathberiya,dc=com,ou=system
            it.com
        


Step3. Start WSO2 Identity Server by running wso2server script file from  <IS_HOME>/bin directory


Step4. Try  authentication and user management function with sample client. (or Soapui ).  Here is the sample code to run user management functions.

Here when authenticating the users,  if the user  (say user called "user1") is in the it.com domain (IT OU), then you need to pass the user name as   it.com/user1

When creating user in sales domain (Sales OU), you need to create the user by providing user name as "sales.com/newUser1"

Friday, November 9, 2012

Disabling WS-Security for IN or OUT messages in Axis2


This is another blog post on WS-Security with Apache Rampart.  Usually, when we are securing a web service with WS-Security, both web service request and response messages are secured. But there are scenarios where you want to configured WS-Security only for web service request or either service response messages.  Say, you may providing some secret data to web server, but web server responses just saying "yes" or "no".  Here you do not want to worry on securing response message.  So like that,  there are several use cases with this. 

Lets see how we can configure this with Apache Rampart; security module of Axis2 

There are two approaches for this. 

Approach 1 : Apache Rampart is an axis2 module where it encapsulates several axis2 handlers.  Configuration file called "module.xml" can be used for configuring this module. If we want to remove security processing for response messages,  we can just remove the defined axis2 handlers from the OutFlow selection. 

But there is a drawback with this.  If we remove axis2 handlers from the OutFlow selection,  Then this would effect for all the services that are deployed in the axis2 engine. Therefore,  there are must be a way to configure this in service level. 


Approach 2 :  As suggest in here,  We can write a new simple module (say "NoSecurity" module) and plug it with axis2 handler chain where this module can ask to skip the rampart module (handlers).  Therefore we can engage "NoSecurity" module only for desired services 


However it is not easy to write a module to skip rampart. Therefore i have used the concept of IN and OUT policies in Rampart. Here we are configuring OUT policy that has no security assertion  to skip the security processing. 

"NoSecurity" Project contains  handler called "NoSecurityHandler" that inject the IN or OUT policy to rampart.  This handler must be placed in the "NoSecurity" phase of axis2 message flows.  Handler has been enclosed with the "NoSecyrityModule" module.

Let see how we can configure this module in a practical use case.  

User case 1

WSO2AS as our web service engine and let try to apply this module for echo service that has been hosted there. 

Step1.  Please do desired changes in to the module and build it with maven.  You would find the .mar module in target directory

Step2. Copy .mar module in to   <CARBON_HOME>/repository/deployment/server/axis2modules  directory. 

Step3. Configure new  "NoSecurity" phase in axis2.xml file which can be found at <CARBON_HOME>/repository/conf/axis2 directory.

Here you can select the desired flow.   i.e.  InFlow, OutFlow InFaultFlow and OutFaultFlow.  Here i am configuring it OutFlow  before the "Security" Phase. 

Step4. Restart the server

Step5  Login to management console of Carbon Server and Go to Service dashboard page of echo service 


Step6. Go to module configuration and select your "NoSecurity" module to engage.



Step7. Now you are done, you can engage and disengage this module for each services using Carbon management console.




User case 2

WSO2 ESB as proxy service engine for your message meditation.  Here we are going to engage this module to disable the security check of incoming message from BE service.  Therefore it is little bit different on writing the module.  Because WSO2 ESB deals with two InFlows  i.e   Messages coming to proxy service and Response messages from BE service.




If we want to only enable this module for messages coming from BE services. We can have a simple check  of a property called "synapse.send"
 if("true".equals(messageContext.getProperty("synapse.send"))){ 

 }
Please find the module project for this for here.   Configuration steps would be same as in WSO2AS, only thing is,  we need to select the correct axis2 phase.

Monday, November 5, 2012

How to invoke secured backend service using WSO2 ESB

Please visit new my blog for this blog post from here





WSO2 ESB can be used for implementing various security patterns in your SOA. It supports message level security with WS-Security specification. In this blog post, we are going to use WSO2 ESB to invoke a secured BE service. 

Client ------------------->  WSO2 ESB -------------------> BE service. 

Lets assume BE service is secured with WS-Security policy.  

Policy contains both signature and encryption  and client needs to provide X509 certificate for authentication. It mean WSO2 ESB proxy service must be authenticated to the BE service.   Therefore security policy provides the authentication Integrity and Confidentiality. 

Here is WSDL of the BE service. It is just a simple echo service. 

Lets go through step by step

Step1 : We need to create matching policy for WSO2 ESB side to invoke the BE service. We can just copy the policy from WSDL for this. It would be some thing like this

Step2 : To do the encryption and signing, we need to define the certificates that contains private key and public key for this.  This is done through a configuration. 

WSO2 ESB uses Apache rampart as the WS-Security implementation. Rampart has, it own way to define the key store and key data using configuration called "rampart configuration". We can add this rampart configuration, in to the Security Policy as an assertion.  Please find more details about rampart configurations from here

Lets add rampart configuration. 

To sign and encryption,  we need to specify following....    

1. Signature and Encryption  crypto. as we are using keystores,   i.e  keystore details.   Such as keystore file, password, type and so on. 

We can define them as follows ...
  

                        
                            JKS
                            /home/asela/Security/resources/keys/client.jks
                            apache
                        
                    
                    
                        
                            JKS
                            /home/asela/Security/resources/keys/client.jks
                            apache
                        
                    

2  Private key (certificate) that is going to sign the message 

This the certificate alias name of private key of the client.jks file
client
3. Public key (certificate) that is going to encrypt the message

This is the certificate alias name of the public certificate of the BE service. That is also contains in my client.jks file.
service
4. Private key password 

We can not define private key password in rampart configuration,  we need to provide it through password class back implementation. Therefore here i am defining the class name of the password call back implementation 
org.wso2.samples.pwcb.PWCBHandler
Now we are done with policy,  it would be as this


Step3 : Lets create a password call back class to inject private key password.  You can get help from this blog post. 

Step4 : Upload our policy to the WSO2 ESB. Here we are uploading created policy file as a resource in the WSO2 ESB's registry. 

1.  Login to WSO2 ESB management console and Go to  "Registry Browser" 



2. Add new registry collection  (folder) in preferred location. I have selected governance collection for this  



3. Upload policy from file system as a resource. 



Step5 : Create  ESB end point for BE service with security

1. Go to  Endpoint configuration UI in Management console 



2. Create new address end point with your BE service configuration and then select advance options. 



3. Select WS-Security option under the QoS in advance options



4. Select Governance registry collection to local the uploaded policy 



5. Finish the endpoint creation 


Step6 :  Create sample proxy service with our secured endpoint.

There are different ways to create proxy service according to your preferences. Here i am creating simple pass through proxy 

1. Create proxy service by defining the endpoint created above



2. You can see synapse configuration as following in proxy and endpoint configurations  



Now we are done...!!!  You can invoke the proxy service with non-secured client. 

Previous 

Secured Client ------------------------------------------------>  Secured BE service 

Now with WSO2ESB

Non Secured Client 
(Endpoint is changed to proxy enpoint) ---------> WSO2ESB  -------------> Secured BE service