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.   

1 comment:

  1. Nice post Asela, thanks!

    Just one question, why do you need to maintain a Map for the SP? I have had to implement my own single log out servlet for Weblogic and apart from the "SAML2 related actions" (construct, verify and sign the requests) I only need to invalidate the current session: javax.servlet.http.HttpSession.invalidate()

    Thanks and best regards,

    Luis

    ReplyDelete