Configuring WSO2 IS as a Key manager

Senthuran Manoharan
4 min readAug 4, 2019

--

WSO2 API Manager has already embedded key manager that handles all security and access token related operation. But if there is a need to add the external key manager then we have to separately add an external key manager. Here in this blog I have explained the steps to add the WSO2 IS_KM as the key manager. For this I have used APIM version of 2.1 and IS_KM version of 5.3 . <APIM> refers to the location of the api manager and <IS_KM> refers to the location of the key manager. Download the wso2 IS_KM and APIM. Configure the port offset for wso2 IS. Open the <IS_KM>/repository/conf/carbon.xml and change the offset to 1.

<offset>1</offset>

Configuring the databases

Source: https://docs.wso2.com/display/AM210/Configuring+WSO2+Identity+Server+as+a+Key+Manager

First create the database in mysql. Here I have used mysql version of 5.7.25 . Here in my database username and password of mysql is “root”.

mysql> create database apimgtdb;
mysql> use apimgtdb;
mysql> source <APIM>/dbscripts/apimgt/mysql.sql;
mysql> grant all on apimgtdb.* TO ‘root’@’localhost’ identified by ‘root’;
mysql> create database userdb;
mysql> use userdb;
mysql> source <API-M_HOME>/dbscripts/mysql.sql;
mysql> grant all on userdb.* TO ‘root’@’localhost’ identified by ‘root’;
mysql> create database regdb;
mysql> use regdb;
mysql> source <API-M_HOME>/dbscripts/mysql.sql;
mysql> grant all on regdb.* TO ‘root’@’localhost’ identified by ‘root’;

Download the mysql jdbc connector jar and place it inside the <APIM>/repository/components/lib and <IS_KM>/repository/components/lib.

Add these configuration inside the datasource file of both APIM and IS_KM.

<datasource>
<name>WSO2AM_DB</name>
<description>The datasource used for the API Manager database</description>
<jndiConfig>
<name>jdbc/WSO2AM_DB</name>
</jndiConfig>
<definition type=”RDBMS”>
<configuration>
<url>jdbc:mysql://localhost:3306/apimgtdb?useSSL=false</url>
<username>root</username>
<password>root</password>
<defaultAutoCommit>false</defaultAutoCommit>
<driverClassName>com.mysql.jdbc.Driver</driverClassName>
<maxActive>50</maxActive>
<maxWait>60000</maxWait>
<testOnBorrow>true</testOnBorrow>
<validationQuery>SELECT 1</validationQuery>
<validationInterval>30000</validationInterval>
</configuration>
</definition>
</datasource>
<datasource>
<name>WSO2UM_DB</name>
<description>The datasource used by user manager</description>
<jndiConfig>
<name>jdbc/WSO2UM_DB</name>
</jndiConfig>
<definition type=”RDBMS”>
<configuration>
<url>jdbc:mysql://localhost:3306/userdb?useSSL=false</url>
<username>root</username>
<password>root</password>
<driverClassName>com.mysql.jdbc.Driver</driverClassName>
<maxActive>50</maxActive>
<maxWait>60000</maxWait>
<testOnBorrow>true</testOnBorrow>
<validationQuery>SELECT 1</validationQuery>
<validationInterval>30000</validationInterval>
</configuration>
</definition>
</datasource>
<datasource>
<name>WSO2REG_DB</name>
<description>The datasource used by the registry</description>
<jndiConfig>
<name>jdbc/WSO2REG_DB</name>
</jndiConfig>
<definition type=”RDBMS”>
<configuration>
<url>jdbc:mysql://localhost:3306/regdb?useSSL=false</url>
<username>root</username>
<password>root</password>
<driverClassName>com.mysql.jdbc.Driver</driverClassName>
<maxActive>50</maxActive>
<maxWait>60000</maxWait>
<testOnBorrow>true</testOnBorrow>
<validationQuery>SELECT 1</validationQuery>
<validationInterval>30000</validationInterval>
</configuration>
</definition>
</datasource>

For the key manager to access the registry database add this configuration in the <IS_KM>/repository/conf/registry.xml (Do not replace the existing configuration).

<dbConfig name=”govregistry”>
<dataSource>jdbc/WSO2REG_DB</dataSource>
</dbConfig>
<remoteInstance url=”https://localhost:9443/registry">
<id>gov</id>
<cacheId>root@jdbc:mysql://localhost:3306/regdb</cacheId>
<dbConfig>govregistry</dbConfig>
<readOnly>false</readOnly>
<enableCache>true</enableCache>
<registryRoot>/</registryRoot>
</remoteInstance>
<mount path=”/_system/governance” overwrite=”true”>
<instanceId>gov</instanceId>
<targetPath>/_system/governance</targetPath>
</mount>
<mount path=”/_system/config” overwrite=”true”>
<instanceId>gov</instanceId>
<targetPath>/_system/config</targetPath>
</mount>

Configure Key Manager with APIM.

Point the API gateway in the IS to the APIM gateway port to enable communication between key manager and gateway. Change the ServerURL in the <IS_KM>/repository/conf/api-manger.xml as

<ServerURL>https://localhost:9443/services/</ServerURL>

When tokens get revoked it should be cleared from the token cache in the gateway. Open the <IS_KM>/repository/conf/api-manger.xml and change the <RevokeAPIURL> element that appears under the <OAuthConfigurations> as

<RevokeAPIURL>https://localhost:8243/revoke</RevokeAPIURL>

For the user management purpose change the <IS_KM>/ repository/conf/user-mgt.xml to point to the WSO2UM_DB. (comment the already available datasource )

<Configuration>
<AddAdmin>true</AddAdmin>
<AdminRole>admin</AdminRole>
<AdminUser>
<UserName>admin</UserName>
<Password>admin</Password>
</AdminUser>
<EveryOneRoleName>everyone</EveryOneRoleName> <! — By default users in this role sees the registry root →
<Property name=”isCascadeDeleteEnabled”>true</Property>
<Property name=”initializeNewClaimManager”>true</Property>
<Property name=”dataSource”>jdbc/WSO2UM_DB</Property>
</Configuration>

Configure APIM with the Key Manager.

In order to handle the Authorization and key validation tasks change the AuthManager, APIKeyValidator ServerURL to point the IS_KM in the <APIM>/repository/conf/api-manger.xml. Enable the WS Client and disable the thrift in the <APIM> /repository/conf/api-manger.xml under the APIKeyValidator.

<AuthManager>
<! — Server URL of the Authentication service →
<ServerURL>https://localhost:9444/services/</ServerURL>
<! — Admin username for the Authentication manager. →
<Username>${admin.username}</Username>
<! — Admin password for the Authentication manager. →
<Password>${admin.password}</Password>
<! — Indicates whether the permissions checking of the user (on the Publisher and Store) should be done
via a remote service. The check will be done on the local server when false. →
<CheckPermissionsRemotely>false</CheckPermissionsRemotely>
</AuthManager>
<APIKeyValidator>
<! — Server URL of the API key manager →
<ServerURL>https://localhost:9444/services/</ServerURL>
<! — Admin username for API key manager. →
<Username>${admin.username}</Username>
<! — Admin password for API key manager. →
<Password>${admin.password}</Password>
<KeyValidatorClientType>WSClient</KeyValidatorClientType>
<ThriftClientConnectionTimeOut>10000</ThriftClientConnectionTimeOut>
<! — ThriftClientPort>10397</ThriftClientPort →
<EnableThriftServer>false</EnableThriftServer>
<ThriftServerHost>localhost</ThriftServerHost>
<! — ThriftServerPort>10397</ThriftServerPort →
<KeyValidationHandlerClassName>org.wso2.carbon.apimgt.keymgt.handlers.DefaultKeyValidationHandler</KeyValidationHandlerClassName>
</APIKeyValidator>

In this setup I have used embedded LDAP that comes with IS_KM, then need to point to the particular LDAP in APIM. Copy the user store from the <IS_KM>/repository/conf/user-mgt.xml and delete the existing user store in APIM and replace with the IS_KM user store into the <APIM>/repository/conf/user-mgt.xml. Increment the ConnectionURL port by IS_KM port offset. By default this port has a value of 10389.

<UserStoreManager class=”org.wso2.carbon.user.core.ldap.ReadWriteLDAPUserStoreManager”>
<Property name=”TenantManager”>org.wso2.carbon.user.core.tenant.CommonHybridLDAPTenantManager</Property>
<Property name=”ConnectionURL”>ldap://localhost:10390</Property>
<Property name=”ConnectionName”>uid=admin,ou=system</Property>
<Property name=”ConnectionPassword”>admin</Property>
<Property name=”AnonymousBind”>false</Property>
<Property name=”UserSearchBase”>ou=Users,dc=wso2,dc=org</Property>
<Property name=”UserEntryObjectClass”>identityPerson</Property>
<Property name=”UserNameAttribute”>uid</Property>
<Property name=”UserNameSearchFilter”>(&amp;(objectClass=person)(uid=?))</Property>
<Property name=”UserNameListFilter”>(objectClass=person)</Property>
<Property name=”DisplayNameAttribute”/>
<Property name=”ReadGroups”>true</Property>
<Property name=”WriteGroups”>true</Property>
<Property name=”GroupSearchBase”>ou=Groups,dc=wso2,dc=org</Property>
<Property name=”GroupEntryObjectClass”>groupOfNames</Property>
<Property name=”GroupNameAttribute”>cn</Property>
<Property name=”GroupNameSearchFilter”>(&amp;(objectClass=groupOfNames)(cn=?))</Property>
<Property name=”GroupNameListFilter”>(objectClass=groupOfNames)</Property>
<Property name=”MembershipAttribute”>member</Property>
<Property name=”BackLinksEnabled”>false</Property>
<Property name=”UsernameJavaRegEx”>[a-zA-Z0–9._-|//]{3,30}$</Property>
<Property name=”UsernameJavaScriptRegEx”>^[\S]{3,30}$</Property>
<Property name=”UsernameJavaRegExViolationErrorMsg”>Username pattern policy violated</Property>
<Property name=”PasswordJavaRegEx”>^[\S]{5,30}$</Property>
<Property name=”PasswordJavaScriptRegEx”>^[\S]{5,30}$</Property>
<Property name=”PasswordJavaRegExViolationErrorMsg”>Password length should be within 5 to 30 characters</Property>
<Property name=”RolenameJavaRegEx”>[a-zA-Z0–9._-|//]{3,30}$</Property>
<Property name=”RolenameJavaScriptRegEx”>^[\S]{3,30}$</Property>
<Property name=”SCIMEnabled”>true</Property>
<Property name=”IsBulkImportSupported”>false</Property>
<Property name=”EmptyRolesAllowed”>true</Property>
<Property name=”PasswordHashMethod”>PLAIN_TEXT</Property>
<Property name=”MultiAttributeSeparator”>,</Property>
<Property name=”MaxUserNameListLength”>100</Property>
<Property name=”MaxRoleNameListLength”>100</Property>
<Property name=”kdcEnabled”>false</Property>
<Property name=”defaultRealmName”>WSO2.ORG</Property>
<Property name=”UserRolesCacheEnabled”>true</Property>
<Property name=”ConnectionPoolingEnabled”>false</Property>
<Property name=”LDAPConnectionTimeout”>5000</Property>
<Property name=”ReadTimeout”/>
<Property name=”RetryAttempts”/>
</UserStoreManager>

As a final step start the key manager and then the api manager. In order to start the node go to <IS_KM/APIM>/bin and type the command as

sh wso2server.sh

Reference

--

--