OpenID Connect Session Management Support in WSO2 IS

Piraveena Paralogarajah
5 min readNov 18, 2017

This is about how OpenID Connect Session management actually works in WSO2 IS. You can refer this blog to see what is actually explained in OpenID Connect Session management spec.

I will explain this with two sample applications playground2 and, playground3.

Lets play with playground!

  1. First playground2 needs to send authentication request. So you need to fill the text boxes with following inputs.

Authorization Grant Type :
Authorization Code (With this sample we can test OIDC only for Authorization Code flow)

Client Id :
Client ID of the playground2 application registered

Scope :
openid

Callback URL :
http://localhost:8080/playground2/oauth2client

Authorize Endpoint :
https://localhost:9443/oauth2/authorize

Logout Endpoint :
https://localhost:9443/oidc/logout

Session Iframe Endpoint :
https://localhost:9443/oidc/checksession?client_id=<ClientID of playground2 application>

Sends authentication request from playground2

2. After you click Authorize button, you will be redirected to wso2 IDP. It will prompt a login page. Enter credentials there.

Login page of wso2 IDP

3. Then a consent page will be displayed. Click ‘Approve Always’ in the consent page (It is mandatory to click “Approve Always” to support OIDC Session Management. Later I will explain the reason )

Consent page

4. Then you will get Authorization code as a URL parameter. With that , you will get another parameter called session_state. This is the one that plays major role in OIDC Session management.

Authorization code and session_state as received in response by playgronud2

5. With this point onwards, OIDC Session management will start.

If you check the console window, you can see the msg “ The session has not changed”.

This The session has not changed” tells whether the session_state value has changed or not. This session_state value is calculated separately for each RP. It is the combination of client_id, origin url(callback-url ) and opbs cookie value. So it is unique for each relying party.

session_state= hash(client_id+opbs cookie value+ origin url)

For playground2,

client_id:
4Nubd6Zrs1umDJtOWqSpsmW_EQMa

opbs cookie value:
9706b266-da8b-4b09–9e28–3c2a05f26bc6

session_state:
5ff5fd2792fb8e7cdc9699456d371ef7db03fb8cbc068354d36ebe641c70a3c0.uPkAVcDi3Sw-8QgUCuUZJg

“Here note the current opbs cookie value and the session_state of playground2”.

RP has an iframe (RP iframe) which sends post message to OP iframe (OP iframe= https://localhost:9443/oidc/checksession?client_id=<ClientID of playground2 application>)

When RP Iframe sends a post message to OP Iframe, client_id and the current session_state value will be sent. With this http post message opbs cookie of the IS server domain will also go. Similarly RP will poll OP periodically.

Then OP iframe re-calculates session_state using , client_id and obps cookie value.

session_state (recalculated) = hash(client_id + obps cookie value+ origin url)

check whether

session_state (recalculated ) = session_state (sent by RP in request)

If the calculated value and the received value are equal, then you will get the msg as “The session has not changed” .

6. Similarly invoke the playground3 app

With this authentication request, the opbs cookie stored for this domain will be sent.

Cookie sent in the request

7. As the response to this authentication request, authorization code will be sent for playground3. But IDP will set a different opbs cookie value to this domain.

Cookie received in the the response

When a new application is invoked in a same browser session, a new cookie will be set.

8. So playground2 will notice the change in cookie, and RP Iframe of playground2 will send a http post message to OP Iframe. With this post message, it will send the current client_id, session state value and opbs cookie value.

For playground2,

client_id:
4Nubd6Zrs1umDJtOWqSpsmW_EQMa

session_state:
5ff5fd2792fb8e7cdc9699456d371ef7db03fb8cbc068354d36ebe641c70a3c0.uPkAVcDi3Sw-8QgUCuUZJg

obps cookie value:
3389f1d8–625e-44f1–891e-ff94683ee079

9. Now IS will recalculate session_state . The calculated session_state will be different, Since the opbs cookie is changed.

session_state(recalculated) = e3010c3c2dd36583f27ccd1d1ec0bef4c90ae672f5e072e27196e3166764dba1.ximp189Ry2tBdMXySkuzRQ

10. So the recalculated session_state won’t be equal to the session_state received by OP.

session-state(sent by RP)=5ff5fd2792fb8e7cdc9699456d371ef7db03fb8cbc068354d36ebe641c70a3c0.uPkAVcDi3Sw-8QgUCuUZJg

session_state (recalculated) != session-state(sent by RP)

So OP will sent a message as “changed”.

11. As Playground2 received a message as “changed”, it will try to reauthenticate. So it will send a authentication request as

https://localhost:9443/oauth2/authorize?client_id=4Nubd6Zrs1umDJtOWqSpsmW_EQMa&scope=openid&response_type=code&redirect_uri=http://localhost:8080/playground2/oauth2client&prompt=none

RP will send prompt=none as a request parameter. If prompt=none, Then Authorization Server MUST NOT display any authentication or consent user interface pages. An error is returned if an end-user is logged out. To prevent IS from showing consent page, we selected “Approve Always” (You got the reason why we selected “Approve Always” at the start 😃).

If the user is still logged in, it won’t return any error messages.

12. When a playground3 invokes logout endpoint, playground2 also will be logged out.

When playground3 invokes /logout api, IS server will clear the session and opbs cookie will be removed. So session_state of playground2 will be changed. So playground2 will notice the change in cookie and it will send a passive request to IS as shown below with prompt=none.

https://localhost:9443/oauth2/authorize?client_id=4Nubd6Zrs1umDJtOWqSpsmW_EQMa&scope=openid&response_type=code&redirect_uri=http://localhost:8080/playground2/oauth2client&prompt=none

Since the user is logged out, this reauthentication will fail and playground2 will get response as

http://localhost:8080/playground2/oauth2client?error_description=Authentication+required&error=login_required&session_state=80d0e5537ab51b6a25e47a8a3ea80fa32991514ef881d2cfe64b258993cf0848.5nizW6uSMMAkPAmrOd5TGA

--

--

Piraveena Paralogarajah

Software Engineer @WSO2, CSE Undergraduate @ University of Moratuwa, Former Software Engineering Intern @ WSO2