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.