Custom User Store in our Identity Server

Over the past 3 months, I have been leading a couple QuickStarts (or QSP as we call them) around API Manager and Identity Management (IS). Our API Manager relies on some of the IS components, especially for all OAuth2-based security scenarios ( issuing and validating access tokens).

In both QuickStarts, we had to create custom user stores, both backed by JDBC. We either totally replaced the default user store by a custom one, or leveraged the multiple user store feature. IS turned out very flexible to accomodate to the specific schema requirements of our customers, and my colleague Johann, who works in the IS team, very quickly implemented the custom code that would allow IS to interact with those custom user repositories.

The magic for all this to work is in the user-mgt.xml file. IS is packaged with a default LDAP-based store, based on ApacheDS. All other products are packaged with a JDBC-based store, using H2.

Here is a sample user store definition, which shows how you can externalize the SQL queries used to manage users and roles in the custom DB:

<UserStoreManager class="com.sample.wso2.TestUserStoreManager">
 <Property name="dataSource">jdbc/testuserstore</Property>
 <Property name="DomainName"></Property>
 <Property name="ReadOnly">false</Property>
 <Property name="MaxUserNameListLength">100</Property>
 <Property name="IsEmailUserName">false</Property>
 <Property name="DomainCalculation">default</Property>
 <Property name="PasswordDigest">SHA-256</Property>
 <Property name="StoreSaltedPassword">true</Property>
 <Property name="UserNameUniqueAcrossTenants">false</Property>
 <Property name="PasswordJavaRegEx">^[\S]{5,30}$</Property>
 <Property name="PasswordJavaScriptRegEx">^[\\S]{5,30}$</Property>
 <Property name="UsernameJavaRegEx">^[^~!#$;%^*+={}\\|\\\\&lt;&gt;,\'\"]{3,30}$</Property>
 <Property name="UsernameJavaScriptRegEx">^[\\S]{3,30}$</Property>
 <Property name="RolenameJavaRegEx">^[^~!#$;%^*+={}\\|\\\\&lt;&gt;,\'\"]{3,30}$</Property>
 <Property name="RolenameJavaScriptRegEx">^[\\S]{3,30}$</Property>
 <Property name="UserRolesCacheEnabled">true</Property>
 <Property name="maxFailedLoginAttempt">0</Property>
 <Property name="InternalJDBCRolesOnly">true</Property>
 <Property name="SelectUserID">SELECT USER_ID,PWD_HASH FROM USERS WHERE USER_ID=?</Property>
 <Property name="AddUser">INSERT INTO USERS (USER_ID, PWD_HASH) VALUES (?, ?)</Property>
 <Property name="GetIsUserExisting">SELECT USER_ID FROM USERS WHERE USER_ID=?</Property>

Now, what about coding ? Well, that’s the advantage of OpenSource code : here is the JDBCUserStore we use, which extends the AbstractUserStoreManager class:

A tip : start with overriding the user methods (addUser, getUser, isExistingUser, listUsers) as well as doAuthenticate.

Leave a Reply

Please log in using one of these methods to post your comment: Logo

You are commenting using your account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s