This site contains the documentation that is relevant to older WSO2 product versions and offerings.
For the latest WSO2 documentation, visit https://wso2.com/documentation/.

Authentication Session Persistence

This section explains sessions in the WSO2 Identity Server (IS) and the process of enabling session persistence for these sessions. This is particularly useful when the 'remember me option' is selected when logging into either the service provider or the WSO2 Identity Server.

Understanding sessions in the WSO2 Identity Server

When you log in to a web application using WSO2 Identity Server, a single sign-on (SSO) session is created by the Identity Server for the user of the application. Also, as the user logs in to the web application, a session is created in the web application itself for the user. These are two separate sessions and they are not synchronized with each other.

For an example, if the web application has a session timeout of 20 minutes and the WSO2 IS SSO session timeout is 5 minutes, the application users will not see the login page up to 20 minutes. That is because WSO2 IS is not invalidating the session by force on the web application.

If the web application session timeout is 5 minutes and the WSO2 IS SSO session timeout is 20 minutes, the users will not see the login page up to 20 minutes. This is because even when the web application container session timeout after 5 minutes, the session was kept alive since WSO2 IS SSO session is still alive. The user will not be redirected to the login screen of the SP until the WSO2 IS SSO session is invalidated.

WSO2 Identity Server creates separate SSO session for SSO login and it is different from the session that is created when you log in to the Identity Server management console.

When an end user logs in through the WSO2 Identity Server for the service provider application (using SAML2 SSO, OpenID Connect, Passive STS, etc.), the Identity Server creates an SSO session for end users and a cookie related to the created SSO session is set to the user’s browser.

This cookie can be seen as commonauthId. It is set to the user’s browser with the hostname of WSO2 Identity Server instance and the value of the commonauthId cookie is the SSO session identifier. When SSO session is created in the WSO2 Identity Server, the session is put into the session cache and persisted to the database. To persist it into the database, you must enable the session persistence.

 Click here to read about the importance of persisting the session.

SSO sessions have been stored in an in-memory cache. It is recommended to persist the SSO session due to following reasons:

  • If you are running a single WSO2 Identity Server instance and the server is restarted, all SSO sessions are removed. If you have multiple nodes of WSO2 instances, it is not guaranteed that you can recover all the sessions. Although the cache is distributed, it is not 100% split to each node.
  • A cache has a limit. If there is a large number of SSO sessions, memory consumption can be high and it can make result reduced server performance. Usually, the cache is evicted after a given number of entries (by default 10000 entries). Therefore, some SSO sessions can be evicted from caches when there is a large number of user logins.
  • When there is a clustered deployment, if you do not have persistence, you need to rely completely on the distributed cache. However, if you have persistence, you can rely on it as well. This increases the reliability of the overall system.

The Identity Server has multiple local caching usages in different layers to improve the product performance. But most of the caches are ready to persist in the database if required.

There are three types of data objects that are persisted in the database.

1. Session Data

Once the user gets authenticated over WSO2 Identity Server, it will create a session data object which stores the authenticated user and the other authentication flow details. This will be stored in the database to share across the cluster nodes.

2. Operational Data

This covers the same session data as in above but the outdated records. For example, once the user gets authenticated, there will be a record for login status to that session id. When the user logs out from the system, the above record is not removed from the table and instead, a new record is added for the same session id with status called 'logout'. So the valid record is the last one and all the other records under that session id will be outdated. Those outdated records belong to the operational data.

3. Temporary Data

In authentication flow, there are many temporary data objects that will be kept for few seconds only. These data objects are kept in cache. But to make the cluster environment consistent without having the local cache, the data objects are stored in the same database table where the session data is stored. 

When you consider the data persistence which belongs to the critical path and high concurrency situation, you have to further improve the following key aspects as well.

Data Clean-Up

Since the above data are collected over the authentication flow, it will grow the database with that data very frequently. So we had to manage few tasks to clean the data in the database for some given conditions.

Task Pool

We are storing above data within a critical path which controls the authentication. So we have introduced a pooling mechanism to put the data persistence tasks into that pool and continue the critical path without blocking it.

How this will work in the clustered environment.

Even in the clustered environment, we don’t recommend to enable the Hazelcast distributed caching for the Identity data. So in this case also we have to rely only on the local cache. And this case especially we have to disable the pool by ‘PoolSize’ is set to 0. Because otherwise there can be some data inconsistency situation which the one node get late to update the database before the other node try to access the same data from the database. Even we use the local cache here, it will trigger the cache invalidation notification system to consistent the data among the nodes in the cluster when the data get deleted or updated, but not for adding the data.


The following configuration found in the <IS_HOME>/repository/conf/identity/identity.xml file, under the Server and JDBCPersistenceManager elements are used to enable session persistence. 

<SessionDataPersist>
	<Enable>true</Enable>
	<Temporary>true</Temporary>
	<PoolSize>0</PoolSize>
	<SessionDataCleanUp>
		<Enable>true</Enable>
		<CleanUpTimeout>20160</CleanUpTimeout>
		<CleanUpPeriod>1140</CleanUpPeriod>
		<!--Instead of deleting all the records at once, we are deleting the records in chunks to prevent
		the -->
		<!--possible deadlock and lock scenarios. The following property defines the chunk size.-->
		<DeleteChunkSize>50000</DeleteChunkSize>
	</SessionDataCleanUp>
	<OperationDataCleanUp>
		<Enable>true</Enable>
	</OperationDataCleanUp>
</SessionDataPersist>

The following table describes the elements of the configurations mentioned above.

Configuration elementDescription

Enable

This enables the persistence of session data. Therefore, this must be configured to true if you wish to enable session persistence.

Temporary

Setting this to true enables persistence of temporary caches that are created within an authentication request.

PoolSize

PoolSize ‘0’ means, there won't be a separate asynchronous thread to do the persistence and will execute that task in the same thread. In other words, data persistence will happen by blocking the main thread which was executed by the initial request itself and the authentication flow will be blocked until this relevant data persistence task gets done.

SessionDataCleanUp

This section of the configuration is related to the cleaning up of session data.

Enable

Selecting true here enables the cleanup task and ensures that it starts running.

CleanUpTimeOut

This is the timeout value (in minutes) of the session data that is removed by the cleanup task. The default value is 2 weeks.

CleanUpPeriod

This is the time period (in minutes) that the cleanup task would run. The default value is 1 day. This is used for both session data cleanup and operation data cleanup through the same task.

DeleteChunkSizeThis value determines (limits) the number of rows that will be deleted in a single delete query statement. The default value is 50000. If the number of rows to delete is larger than this limit, the DELETE statement is repeated until the number of affected rows is less than the LIMIT value.
OperationDataCleanUpThis section of the configuration is related to the cleaning up of operation data.

About size of Delete Chunks

The value of delete chunk size depends on various factors such as:
- The size of a row of the table. You can calculate this by adding bytes needed for each column, and some control information per record.
- The underlying physical storage. e.g Normal SATA spinning Disk, SSD, SCSI, Amazon S3/EBS etc.
- The type of the database engine (e.g. MySql, MSSql, Oracle). Each one has different data organization mechanism in physical storage.
- OS where the DB server runs.

You can calculate this by adding bytes needed for each column, and some control information per record. The best way to calculate the chunk size it is to run a sample program that calculates the size. To do this, you may need to insert a large number of artificial records on the table and run a deletion query with incremental chunk sizes.

 How to calculate the Delete Chunk Size

You can calculate the Delete Chunk Size using a tool. Follow the steps below to calculate the Delete Chunk Size.

  1. Download the tool from here and unzip.

  2. Using a text editor, open the run.sh and change the following arguments according to your environment. (sample values are given in the table below)

    ArgumentDescriptionSample value
    arg0

    path to the JDBC SQL connector

    /home/wso2dinali/SUPPORT/mysql-connector-java-5.1.42/mysql-connector-java-5.1.42-bin.jar

    arg1

    ChunkSizeDeleteTest

    com.mysql.jdbc.Driver

    arg2

    Database URL which contains session data tables

    jdbc:mysql://localhost:3306/JDBC?useSSL=false

    arg3

    DB username

    root

    arg4

    DB password

    root

    arg5

    No of times the original table should be copied to duplicate table. This will help to create a table with a big size to calculate the exact performance.

    100000

    Format

    Java -cp .:{path to the JDBC SQL connector} ChunkSizeDeleteTest "{SQL driver name}" "{Databse URL which contains session data tables}" "{DB username}" "{DB password}" {No of times to duplicate}


    Sample

    java -cp .:/home/wso2dinali/SUPPORT/mysql-connector-java-5.1.42/mysql-connector-java-5.1.42-bin.jar ChunkSizeDeleteTest "com.mysql.jdbc.Driver" "jdbc:mysql://localhost:3306/JDBC?useSSL=false" "root" "root" 100000


  3. Run the tool and note down how long it takes against each chunk size given.

    sh run.sh
  4. Plot the results and figure out the optimal Delete Chunk Size.

    If you get the following as output:

    round:0 The chunk size 256 takes time of 1ms

    round:1 The chunk size 512 takes time of 0ms

    round:2 The chunk size 1000 takes time of 1ms

    round:3 The chunk size 5000 takes time of 2ms

    round:4 The chunk size 50000 takes time of 2ms

    round:5 The chunk size 100000 takes time of 0ms

    round:6 The chunk size 512000 takes time of 1ms

    From the above output, you can conclude that the best chunk size would be 512 or 100,000 as the optimal chunk size. Furthermore, you can take the average for more accurate results.

Note that this chunk size configuration may change later if you decide to upgrade the DB cluster, their storage etc. Hence it is not a static value. The optimal value needs to be measured each time you do a change in your database infrastructure.


Why do we need to have a proper delete chunk size?

In the world of World Wide Web, Sessions are the simplest way to store data for individual users against a unique session ID. These can be used to persist state information between page requests. When we consider all the requests and responses that come to a page per day, that is really a large amount. Due to this reason, the session data storing in the “IDN_AUTH_SESSION_STORE” table in the WSO2CARBON_DB of WSO2 IS is really high. This table fills up quickly if your system receives too many loads of requests.

After a certain period of time, these session data becomes outdated. In order to stop the exponential table growth, you can run a session clean up task at predefined time intervals via a script. If this storing of session data is huge, the data that needs to be deleted also will come in bulk.

The session clean up task also takes a certain amount of time and consumes a certain amount of resources. Therefore, we always need to improve the performance of session clean up tasks. For this DeleteChunkSize property has introduced in WSO2 Identity Server. This will also help to reduce dead-locks happening during session clean up task. With the use of DeleteChunkSize value, the deletion happens batch wisely. “DeleteChunkSize” of data is deleted at one time.

But if you didn’t select a correct number for the DeleteChunkSize, you will end up with less performance. Therefore selecting suitable chunk size for your database is a must.

This chuck size may differ due to various factors of your environment

  • The size of a row of the table. Calculate this by adding bytes needed for each column, and some control information per record.
  • The underlying physical storage. e.g Normal SATA spinning Disk, SSD, SCSI, Amazon S3/EBS etc.
  • The type of the database engine (e.g. MySql, MSSql, Oracle). Each one has different data organization mechanism in physical storage.
  • OS where the DB server runs.

Therefore, it is hard to select a DeleteChunkSize without considering all the above factors.