Using session-based claims in adaptive scripts of WSO2 Identity Server

Dewni Weeraman
8 min readMar 29, 2021

--

Photo by Felix Hanspach on Unsplash

Data breaches happen on a daily basis, exposing billions of records of sensitive data. Studies show that the rate of identity-related crime is detonating. Especially with the COVID-19 pandemic, many businesses have been forced to go on remote, and hence more and more chances of personal information available online be susceptible to data breaches. Businesses need to be more vigilant to shield sensitive information from malicious attacks. Relying on the traditional username and password authentication is not safe anymore.

This where Multi-factor Authentication (MFA) comes into play. With MFA, an individual is required to present two or more verification factors to gain access to the protected resource. For example, logging into your online banking account will require you to enter the SMS OTP, in addition to providing the correct login credentials. However, with MFA, there is a trade-off between security and usability. For these reasons, businesses now rely on Adaptive Authentication.

Adaptive Authentication is the process of dynamically selecting the right factors that are required for authentication based on risks surrounding a particular user login attempt. Adaptive Authentication is a key feature offered by WSO2 Identity Server. For more detailed information on this feature, I recommend you to check the official documentation.

In this blog, I will show you how to set session-based temporary claims for a user using an adaptive script and pass those claims to the service provider in subsequent requests made to the service provider during the session.

Let’s imagine the following hypothetical scenario and see how this is achievable with the WSO2 Identity Server.

Scenario:

Let’s assume there is an application that displays the real-time traffic information of cities in Sri Lanka based on the user’s logged-in city. Each user will have a pre-defined set of cities to which he/she is entitled to view traffic information. For example, if user Bob logs in from Colombo he will get traffic information in Colombo. However, if Bob tries to log into the application from a city that he is not entitled to view traffic information, then he will get an authentication failure. When the user logs into the application, the application will send a query parameter containing the name of the city from which the user has logged in. Until the user’s login session expires, the city represented from this query parameter will be persisted in the session and will be considered as the user’s current city.

Based on the aforementioned scenario, let’s see how we can persist the city in the user’s session using an adaptive script. To demonstrate this capability I will be using a SAML-based sample webapp called Travelocity.

Note:

Please note that the query parameter used here is only for demonstration purposes. In a real-world scenario, necessary steps should be taken to send these data in a secure immutable manner.

Pre-requisites:

Download the latest WSO2 Identity Server from here. For details on running the Identity Server, see Running the Product.

Step 01 - Set up sample webapp.

Refer here to deploy the Travelocity webapp and configure the webapp as a SAML service provider in WSO2 IS.

Step 02 - Configure claims.

To persist the allowed list of cities of the user, let’s create a local claim in the wso2 claim dialect.

  • Access WSO2 IS management console.
  • Navigate to Main > Identity > Claims > Add > Add Local Claim > http://wso2.org/claims.
  • Click Add Local Claim and enter the following values.
    - Claim URI: http://wso2.org/claims/allowedCities
    - Display Name: Allowed cities
    - Description: List of allowed cities to view traffic information.
    - Mapped Attribute(s): User Store Domain Name: PRIMARY, Mapped Attribute: region
    - Supported By Default: True
  • Click Add and click OK to save the custom claim.

To temporarily persist the logged-in city of the user, create the following custom claim.

  • Navigate to Main > Identity > Claims > Add > Add Local Claim > http://wso2.org/claims.
  • Click Add Local Claim and enter the following values.
    - Claim URI: http://wso2.org/claims/loggedInCity
    - Display Name: Logged-in city
    - Description: Currently logged in city.
    - Mapped Attribute(s): User Store Domain Name: PRIMARY, Mapped Attribute: stateOrProvinceName
  • Click Add and click OK to save the custom claim.

Step 03 - Create user and configure user profile.

  • Click Identity > Users and Roles > Add > Add New User
  • In the Users view, select the User Profile of the created user.
  • Fill in the user profile information. For Allowed cities, provide a list of comma-separated cities as provided below.

Step 04 - Configure adaptive authentication script.

  • Browse the service provider created in Step 01.
  • Expand Local & Outbound Authentication Configuration.
  • Select Advanced Configuration as the Authentication Type.
  • Expand Authentication Step Configuration > Local Authenticators.
  • Select basic.
  • Expand Script Based Adaptive Authentication and add the below provided JS script.

Tip:

Note that the session-based temporary claims are stored as

subject.claims[<temporary_claim_uri>]

Claims persisted in the user-store level are read as

subject.localClaims[<local_claim_uri>]

The query parameter is defined for this flow as currentCity. The query parameter value is read from the script as

context.request.params.currentCity
  • Click Update to save the changes.

Step 05 - Configure the session-based claim as a service provider requested claim.

  • Browse the service provider created in Step 01.
  • Expand Claim Configuration
  • For Select Claim mapping Dialect , choose Use Local Claim Dialect.
  • Click Add Claim URI in Requested Claims.
  • Add http://wso2.org/claims/loggedInCity as a requested claim.
  • Click Update to save the changes.

Step 06 - Modify the SAML request to send city as a query parameter

SAML tracer which is a web browser extension for tracing details of SAML flow will be used to capture the SAML request.

  • View the SAML traffic captured by the extension. You will see the SAML request made to the WSO2 Identity Server.
  • Copy this request. Sample request is provided below for your reference.
https://localhost:9443/samlsso?SAMLRequest=nVPBjtowFLz3KyLfSUJYtNQiWVHQqkjbigLbQ2%2FGeQEXxy%2F1c4D9%2BzoJtKhqEeoxznsz45nx%2BOlU6uAAlhSalPXDmAVgJObKbFP2un7ujdhT9m5MotQVn9RuZ5bwowZywYQIrPNrUzRUl2BXYA9KwuvyJWU75yoeRUfCRFGoUQrNR%2FEojpwVB%2FDfyr2FEstohyWE36liwcyDKiNcK6TZJw%2FQbu6QHH%2F%2F8DCIGhlEyIJntBJaOSkrhCZgwXyWsmqDEveFwqKoyi2WW222iCqvdriXUOZC4Wa%2FxdxP00IQqQP83ieqYW7ICeNSlsRJvxcPeslo3X%2FkwwEfPoaDZPiNBQuLzrPoD8p0LtXWcBSkiBtRAnEn%2BWry6YUnYcw33RDxj%2Bv1oreEXFmQjgVfL44njeM%2BA0O89fg2XHXmZtk5kVa0vR9AXEJj2R9JjKNrxA4%2FqfhnDzGfLVAr%2BRZMtMbj1IJw3jZna2iDKIW7TdqcqLxXtKO8aq5ODoy3YbVo8L%2FUQqtCgU1Zx37tSHKvJdEvzeeGQt4WxNfTwckFUywrYRU1rsNJNCn8B0tHwq%2BRp9q7uoTiCu7uEG6OSS4baH%2FcdPWINm%2B65%2FsD%2BdoKQxVa18X2Vz1Z9%2B9fhmSXxK9fdfYT&SigAlg=http%3A%2F%2Fwww.w3.org%2F2000%2F09%2Fxmldsig%23rsa-sha1&Signature=fiyc9RFLIrWBAlvuNKlzHCdNsOwq9VXdLUcrUJ%2FK341MpDR49z08rgC8zpFjuaGNLHdEjkqYTIpjLgRMDlBMu83hzj3gO7gHejWiDaGlb0EtpicSpf%2FugTML5ejq8BSl3bAbvPt3THXLdjYDAyJLRzJrYh4cRuZkovD4HRqbLQQyT%2B4lkCmPuNXg2h%2FWUVxqPmD3XzmpD2Td%2BUFZ8V4QOdqXSHzP2AXOeCYBj%2BPPt7cUwMOtSTelmStKcLg8faq72SDdwHWBzjycXF7%2BdrNWyTd9Q3IZZTXt5%2FI%2BuYUP%2B4PHPhdM3bOmNS%2FQqFSQQzZJsHvyW7QxHdPM5uSQHREi6Q%3D%3D
  • Edit this request to add the query parameter currentCity.
https://localhost:9443/samlsso?SAMLRequest=nVPBjtowFLz3KyLfSUJYtNQiWVHQqkjbigLbQ2%2FGeQEXxy%2F1c4D9%2BzoJtKhqEeoxznsz45nx%2BOlU6uAAlhSalPXDmAVgJObKbFP2un7ujdhT9m5MotQVn9RuZ5bwowZywYQIrPNrUzRUl2BXYA9KwuvyJWU75yoeRUfCRFGoUQrNR%2FEojpwVB%2FDfyr2FEstohyWE36liwcyDKiNcK6TZJw%2FQbu6QHH%2F%2F8DCIGhlEyIJntBJaOSkrhCZgwXyWsmqDEveFwqKoyi2WW222iCqvdriXUOZC4Wa%2FxdxP00IQqQP83ieqYW7ICeNSlsRJvxcPeslo3X%2FkwwEfPoaDZPiNBQuLzrPoD8p0LtXWcBSkiBtRAnEn%2BWry6YUnYcw33RDxj%2Bv1oreEXFmQjgVfL44njeM%2BA0O89fg2XHXmZtk5kVa0vR9AXEJj2R9JjKNrxA4%2FqfhnDzGfLVAr%2BRZMtMbj1IJw3jZna2iDKIW7TdqcqLxXtKO8aq5ODoy3YbVo8L%2FUQqtCgU1Zx37tSHKvJdEvzeeGQt4WxNfTwckFUywrYRU1rsNJNCn8B0tHwq%2BRp9q7uoTiCu7uEG6OSS4baH%2FcdPWINm%2B65%2FsD%2BdoKQxVa18X2Vz1Z9%2B9fhmSXxK9fdfYT&SigAlg=http%3A%2F%2Fwww.w3.org%2F2000%2F09%2Fxmldsig%23rsa-sha1&Signature=fiyc9RFLIrWBAlvuNKlzHCdNsOwq9VXdLUcrUJ%2FK341MpDR49z08rgC8zpFjuaGNLHdEjkqYTIpjLgRMDlBMu83hzj3gO7gHejWiDaGlb0EtpicSpf%2FugTML5ejq8BSl3bAbvPt3THXLdjYDAyJLRzJrYh4cRuZkovD4HRqbLQQyT%2B4lkCmPuNXg2h%2FWUVxqPmD3XzmpD2Td%2BUFZ8V4QOdqXSHzP2AXOeCYBj%2BPPt7cUwMOtSTelmStKcLg8faq72SDdwHWBzjycXF7%2BdrNWyTd9Q3IZZTXt5%2FI%2BuYUP%2B4PHPhdM3bOmNS%2FQqFSQQzZJsHvyW7QxHdPM5uSQHREi6Q%3D%3D&currentCity=Colombo
  • Access the above-edited request in a fresh browser window.
  • Log in as Bob.
  • Give permission for Travelocity to access the configured session-based claim.
  • Upon successful authentication, the following page is displayed.

Here, you can see that the session-based claim value has been passed to the service provider upon successful execution of the logic defined in the authentication script.

  • The following logs will be displayed in the terminal.
[2021-03-28 23:36:50,291] [8e544db4-7b36-4cea-b596-38c5ad85d64c]  INFO {org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.JsLogger} - >>> Login request started.[2021-03-28 23:36:56,753] [3d27d17f-535d-4f21-9ab9-4447168ec4a2]  INFO {org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.JsLogger} - >>> The user: Bob@carbon.super has the following cities : Colombo, Jaffna, Dambulla[2021-03-28 23:36:56,771] [3d27d17f-535d-4f21-9ab9-4447168ec4a2]  INFO {org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.JsLogger} - >>> The user: Bob@carbon.super has the requested city: Colombo

Now, let’s make a login request without the currentCity query parameter.

  • Access the below provided request in a new tab of the same browser window.
https://localhost:9443/samlsso?SAMLRequest=nVPBjtowFLz3KyLfSUJYtNQiWVHQqkjbigLbQ2%2FGeQEXxy%2F1c4D9%2BzoJtKhqEeoxznsz45nx%2BOlU6uAAlhSalPXDmAVgJObKbFP2un7ujdhT9m5MotQVn9RuZ5bwowZywYQIrPNrUzRUl2BXYA9KwuvyJWU75yoeRUfCRFGoUQrNR%2FEojpwVB%2FDfyr2FEstohyWE36liwcyDKiNcK6TZJw%2FQbu6QHH%2F%2F8DCIGhlEyIJntBJaOSkrhCZgwXyWsmqDEveFwqKoyi2WW222iCqvdriXUOZC4Wa%2FxdxP00IQqQP83ieqYW7ICeNSlsRJvxcPeslo3X%2FkwwEfPoaDZPiNBQuLzrPoD8p0LtXWcBSkiBtRAnEn%2BWry6YUnYcw33RDxj%2Bv1oreEXFmQjgVfL44njeM%2BA0O89fg2XHXmZtk5kVa0vR9AXEJj2R9JjKNrxA4%2FqfhnDzGfLVAr%2BRZMtMbj1IJw3jZna2iDKIW7TdqcqLxXtKO8aq5ODoy3YbVo8L%2FUQqtCgU1Zx37tSHKvJdEvzeeGQt4WxNfTwckFUywrYRU1rsNJNCn8B0tHwq%2BRp9q7uoTiCu7uEG6OSS4baH%2FcdPWINm%2B65%2FsD%2BdoKQxVa18X2Vz1Z9%2B9fhmSXxK9fdfYT&SigAlg=http%3A%2F%2Fwww.w3.org%2F2000%2F09%2Fxmldsig%23rsa-sha1&Signature=fiyc9RFLIrWBAlvuNKlzHCdNsOwq9VXdLUcrUJ%2FK341MpDR49z08rgC8zpFjuaGNLHdEjkqYTIpjLgRMDlBMu83hzj3gO7gHejWiDaGlb0EtpicSpf%2FugTML5ejq8BSl3bAbvPt3THXLdjYDAyJLRzJrYh4cRuZkovD4HRqbLQQyT%2B4lkCmPuNXg2h%2FWUVxqPmD3XzmpD2Td%2BUFZ8V4QOdqXSHzP2AXOeCYBj%2BPPt7cUwMOtSTelmStKcLg8faq72SDdwHWBzjycXF7%2BdrNWyTd9Q3IZZTXt5%2FI%2BuYUP%2B4PHPhdM3bOmNS%2FQqFSQQzZJsHvyW7QxHdPM5uSQHREi6Q%3D%3D
  • You will observe that the loggedInCity claim value is displayed even though this value is not present in the request. Here, the value is read from the session.
  • The following logs will be displayed in the terminal.
[2021-03-28 23:41:47,921] [0f1698bb-932c-41ee-b411-031a30a96e0f]  INFO {org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.JsLogger} - >>> Login request started.[2021-03-28 23:41:47,925] [0f1698bb-932c-41ee-b411-031a30a96e0f]  INFO {org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.JsLogger} - >>> currentCity is not present in the login request as a query parameter.[2021-03-28 23:41:47,953] [0f1698bb-932c-41ee-b411-031a30a96e0f]  INFO {org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.JsLogger} - currentCity is available in the session.

Let’s logout and see the behaviour.

  • Perform a login request without the currentCity query parameter.

This time, the loggedInCity claim value not be displayed as the previous session has been terminated.

Let’s also check the behaviour when the user tries to log in to the application with a city he/she is not entitled to access the traffic information.

  • Add a city that Bob is not entitled to as the currentCity query parameter and perform the request. A sample request is provided for your reference. below.
https://localhost:9443/samlsso?SAMLRequest=nVPBjtowFLz3KyLfSUJYtNQiWVHQqkjbigLbQ2%2FGeQEXxy%2F1c4D9%2BzoJtKhqEeoxznsz45nx%2BOlU6uAAlhSalPXDmAVgJObKbFP2un7ujdhT9m5MotQVn9RuZ5bwowZywYQIrPNrUzRUl2BXYA9KwuvyJWU75yoeRUfCRFGoUQrNR%2FEojpwVB%2FDfyr2FEstohyWE36liwcyDKiNcK6TZJw%2FQbu6QHH%2F%2F8DCIGhlEyIJntBJaOSkrhCZgwXyWsmqDEveFwqKoyi2WW222iCqvdriXUOZC4Wa%2FxdxP00IQqQP83ieqYW7ICeNSlsRJvxcPeslo3X%2FkwwEfPoaDZPiNBQuLzrPoD8p0LtXWcBSkiBtRAnEn%2BWry6YUnYcw33RDxj%2Bv1oreEXFmQjgVfL44njeM%2BA0O89fg2XHXmZtk5kVa0vR9AXEJj2R9JjKNrxA4%2FqfhnDzGfLVAr%2BRZMtMbj1IJw3jZna2iDKIW7TdqcqLxXtKO8aq5ODoy3YbVo8L%2FUQqtCgU1Zx37tSHKvJdEvzeeGQt4WxNfTwckFUywrYRU1rsNJNCn8B0tHwq%2BRp9q7uoTiCu7uEG6OSS4baH%2FcdPWINm%2B65%2FsD%2BdoKQxVa18X2Vz1Z9%2B9fhmSXxK9fdfYT&SigAlg=http%3A%2F%2Fwww.w3.org%2F2000%2F09%2Fxmldsig%23rsa-sha1&Signature=fiyc9RFLIrWBAlvuNKlzHCdNsOwq9VXdLUcrUJ%2FK341MpDR49z08rgC8zpFjuaGNLHdEjkqYTIpjLgRMDlBMu83hzj3gO7gHejWiDaGlb0EtpicSpf%2FugTML5ejq8BSl3bAbvPt3THXLdjYDAyJLRzJrYh4cRuZkovD4HRqbLQQyT%2B4lkCmPuNXg2h%2FWUVxqPmD3XzmpD2Td%2BUFZ8V4QOdqXSHzP2AXOeCYBj%2BPPt7cUwMOtSTelmStKcLg8faq72SDdwHWBzjycXF7%2BdrNWyTd9Q3IZZTXt5%2FI%2BuYUP%2B4PHPhdM3bOmNS%2FQqFSQQzZJsHvyW7QxHdPM5uSQHREi6Q%3D%3D&currentCity=Matara
  • Since Bob, doesn’t have the city Matara persisted in the allowedCities claim, the following authentication failed page will be displayed.
  • The following logs will be displayed in the terminal.
[2021-03-28 23:42:05,923] [949beb3c-8eb5-456c-9173-715cb7d015f0]  INFO {org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.JsLogger} - >>> Login request started.[2021-03-28 23:42:05,964] [949beb3c-8eb5-456c-9173-715cb7d015f0]  INFO {org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.JsLogger} - >>> The user: bob@carbon.super has the following cities : Colombo, Jaffna, Dambulla[2021-03-28 23:42:05,980] [949beb3c-8eb5-456c-9173-715cb7d015f0]  INFO {org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.JsLogger} - >>> The user: bob@carbon.super does not have the requested city. Hence displaying the error page.

Additional Note:

Please note the script provided here is only to show how a session-based temporary claim can be used in an adaptive script. In a real-world scenario, conditions such as how to handle session-based claims when a user is using multiple devices at the same time should be considered.

You have reached the end of this blogpost. I hope you got a basic understanding of how to use session-based claims with adaptive scripts to achieve your use-case.

Have questions?

Reach us via wso2is.slack.com to ask questions directly from our team, and engage with an active community of developers.

--

--

Dewni Weeraman
Dewni Weeraman

Written by Dewni Weeraman

Software Engineer at WSO2 | Graduate of University of Westminster

No responses yet