How to Write a Custom User Store Manager - WSO2 Identity Server 4.5.0

With this post I will be demonstrating writing a simple custom user store manager for WSO2 Carbon and specifically in WSO2 Identity Server 4.5.0 which is released recently. The Content is as follows,
  1. Use case
  2. Writing the custom User Store Manager
  3. Configuration in Identity Server
You can download the sample here.

Use Case

By default WSO2 Carbon has four implementations of User Store Managers as follows.
  • org.wso2.carbon.user.core.jdbc.JDBCUserStoreManager
  • org.wso2.carbon.user.core.ldap.ReadOnlyLDAPUserStoreManager
  • org.wso2.carbon.user.core.ldap.ReadWriteLDAPUserStoreManager
  • org.wso2.carbon.user.core.ldap.ActiveDirectoryLDAPUserStoreManager
Let's look at a scenario where a company has a simple user store where they have kept customer_id, customer_name and the password (For the moment let's not worry about salting etc. as purpose is to demonstrate getting a custom user store into action). So the company may want to keep this as it is, as there may be other services depending on this and still wanting to have identities managed. Obviously it's not a good practice to duplicate these sensitive data to another database to be used by the Identity Server as then the cost of securing both databases is high and can guide to conflicts. That is where a custom User Store Manager comes handy, with the high extendibility of Carbon platform.

So this is the scenario I am to demonstrate with only basic authentication.

We have the following user store which is currently in use at the company.
CREATE TABLE CUSTOMER_DATA (
             CUSTOMER_ID INTEGER NOT NULL AUTO_INCREMENT,
             CUSTOMER_NAME VARCHAR(255) NOT NULL,
             PASSWORD VARCHAR(255) NOT NULL,
             PRIMARY KEY (CUSTOMER_ID),
             UNIQUE(CUSTOMER_NAME)
);


INSERT INTO CUSTOMER_DATA (CUSTOMER_NAME, PASSWORD) VALUES("pushpalanka" ,"pushpalanka");
INSERT INTO CUSTOMER_DATA (CUSTOMER_NAME, PASSWORD) VALUES("lanka" ,"lanka"); 

I have only two entries in user store. :) Now what we want is to let these already available users to be visible to Identity Server, nothing less, nothing more. So it's only the basic authentication that User Store Manager should support, according to this scenario.

Writing the custom User Store Manager

There are just 3 things to adhere when we writing the User Store Manager and the rest will be done for us.

  • Implement the 'org.wso2.carbon.user.api.UserStoreManager' interface
There are several other options to do this, by implementing 'org.wso2.carbon.user.core.UserStoreManager' interface or extending 'org.wso2.carbon.user.core.common.AbstractUserStoreManager' class, as appropriate. In this case as we are dealing with a JDBC User Store, best option is to extend the existing JDBCUserStoreManager class and override the methods as required.
CustomUserStoreManager extends JDBCUserStoreManager 

@Override
    public boolean doAuthenticate(String userName, Object credential) throws UserStoreException {

        if (CarbonConstants.REGISTRY_ANONNYMOUS_USERNAME.equals(userName)) {
            log.error("Anonymous user trying to login");
            return false;
        }

        Connection dbConnection = null;
        ResultSet rs = null;
        PreparedStatement prepStmt = null;
        String sqlstmt = null;
        String password = (String) credential;
        boolean isAuthed = false;

        try {
            dbConnection = getDBConnection();
            dbConnection.setAutoCommit(false);
            sqlstmt = realmConfig.getUserStoreProperty(JDBCRealmConstants.SELECT_USER);

            prepStmt = dbConnection.prepareStatement(sqlstmt);
            prepStmt.setString(1, userName);

            rs = prepStmt.executeQuery();

            if (rs.next()) {
                String storedPassword = rs.getString("PASSWORD");
                if ((storedPassword != null) && (storedPassword.trim().equals(password))) {
                    isAuthed = true;
                }
            }
        } catch (SQLException e) {
            throw new UserStoreException("Authentication Failure. Using sql :" + sqlstmt);
        } finally {
            DatabaseUtil.closeAllConnections(dbConnection, rs, prepStmt);
        }

        if (log.isDebugEnabled()) {
            log.debug("User " + userName + " login attempt. Login success :: " + isAuthed);
        }

        return isAuthed;

    }

  • Register Custom User Store Manager in OSGI framework
This is just simple step to make sure new custom user store manager is available through OSGI framework. With this step the configuration of new user store manager becomes so easy with the UI in later steps. We just need to place following class inside the project.

/**
 * @scr.component name="custom.user.store.manager.dscomponent" immediate=true
 * @scr.reference name="user.realmservice.default"
 * interface="org.wso2.carbon.user.core.service.RealmService"
 * cardinality="1..1" policy="dynamic" bind="setRealmService"
 * unbind="unsetRealmService"
 */
public class CustomUserStoreMgtDSComponent {
    private static Log log = LogFactory.getLog(CustomUserStoreMgtDSComponent.class);
    private static RealmService realmService;

    protected void activate(ComponentContext ctxt) {

        CustomUserStoreManager customUserStoreManager = new CustomUserStoreManager();
        ctxt.getBundleContext().registerService(UserStoreManager.class.getName(), customUserStoreManager, null);
        log.info("CustomUserStoreManager bundle activated successfully..");
    }

    protected void deactivate(ComponentContext ctxt) {
        if (log.isDebugEnabled()) {
            log.debug("Custom User Store Manager is deactivated ");
        }
    }

    protected void setRealmService(RealmService rlmService) {
          realmService = rlmService;
    }

    protected void unsetRealmService(RealmService realmService) {
        realmService = null;
    }
}


  • Define the Properties Required for the User Store Manager
There needs to be this method 'getDefaultProperties()' as follows. The required properties are mentioned in the class 'CustomUserStoreConstants'. In the downloaded sample it can be clearly seen how this is used.
@Override
    public org.wso2.carbon.user.api.Properties getDefaultUserStoreProperties(){
        Properties properties = new Properties();
        properties.setMandatoryProperties(CustomUserStoreConstants.CUSTOM_UM_MANDATORY_PROPERTIES.toArray
                (new Property[CustomUserStoreConstants.CUSTOM_UM_MANDATORY_PROPERTIES.size()]));
        properties.setOptionalProperties(CustomUserStoreConstants.CUSTOM_UM_OPTIONAL_PROPERTIES.toArray
                (new Property[CustomUserStoreConstants.CUSTOM_UM_OPTIONAL_PROPERTIES.size()]));
        properties.setAdvancedProperties(CustomUserStoreConstants.CUSTOM_UM_ADVANCED_PROPERTIES.toArray
                (new Property[CustomUserStoreConstants.CUSTOM_UM_ADVANCED_PROPERTIES.size()]));
        return properties;
    } 

The advanced properties carries the required SQL statements for the user store, written according to the custom schema of our user store.
Now all set to go. You can build the project with your customization to the sample project or just use the jar in the target. Drop the jar inside CARBON_HOME/repository/components/dropins and drop mysql-connector-java-<>.jar inside CARBON_HOME/repository/components/lib. Start the server with ./wso2carbon.sh from CARBON_HOME/bin. In the start-up logs you will see following log printed.

INFO {org.wso2.sample.user.store.manager.internal.CustomUserStoreMgtDSComponent} -  CustomUserStoreManager bundle activated successfully.

Configuration in Identity Server

In the management console try to add a new user store as follows.
 In the shown space we will see our custom user store manager given as an options to use as the implementation class, as we registered this before in OSGI framework. Select it and fill the properties according to the user store.


Also in the property space we will now see the properties we defined in the constants class as below.
If our schema changes at any time we can edit it here in dynamic manner. Once finished we will have to wait a moment and after refreshing we will see the newly added user store domain, here I have named it 'wso2.com'. 
So let's verify whether the user are there. Go to 'Users and Roles' and in Users table we will now see the users details who were there in the custom user store as below.

 If we check the roles these users are assigned to Internal/everyone role. Modify the role permission to have 'login' allowed. Now if any of the above two users tried to login with correct credentials they are allowed.
So we have successfully configured Identity Server to use our Custom User Store without much hassel.

Cheers!

Ref: http://malalanayake.wordpress.com/2013/04/03/how-to-write-custom-jdbc-user-store-manager-with-wso2is-4-1-1-alpha/

Note: For the updated sample for Identity Server - 5.0.0, please use the link, https://svn.wso2.org/repos/wso2/people/pushpalanka/SampleCustomeUserStoreManager-5.0.0/

Google

Comments

  1. Hi Pushpalanka, thank you for your blog.
    I tried out your CustomUserStoreManager with WSO2IS 4.5.0, it works :), however I experienced some troubles when requesting tokens using "password" grant type (using OAuth 2.0):

    (1) Getting access token for the first time works fine, I get access token, refresh token, etc.
    (2) Subsequent requests for access token work fine too, I get tokens from (1), etc.
    (3) Subsequent request for refreshing tokens works fine too, I get new access and new refresh token, etc.
    (4) But now, subsequent request for access token results in getting tokens from the very first request (1) not the ones obtained in step (3) and validation of this access token fails.

    All subsequent requests for refreshing token do actually nothing. This happens when some user from secondary user store manager is used. When I repeat these steps using admin/admin as username/password which is kept as primary user, everything works as I expect - request for access token (4) returns new fresh tokens (from (3))

    I don't know whether I'm missing something, please it would be very helpful if you could look at it. I hope I wrote my problem clear for understanding :) Thank you in advance

    ReplyDelete
    Replies
    1. Hi Martin,

      Yes, I could understand the problem. At first sight it looked like a problem in caching. But as it only occurs with secondary user store there seems to be something else. I'll dig more into this and let you know. If you can share the configuration of your secondary user store without the sensitive details, it would be helpful (My-email: lankalux@gmail.com).

      Regards,

      Delete
    2. Hi Pushpalanka,

      Did you have a chance to look at the issue Martin reported. We are thinking of implementing a secondary user store for oAuth protected resources.

      Thanks
      Pradeep

      Delete
    3. Hi Martine - We're facing issues while setting CustomUserStore in WSO2 IS tool. Could you please guide us how you able to make it successful ?

      The steps we followed
      1) Downloaded source code from this link and created custom-user-store.jar file and place it to C:\wso2is-5.0.0\repository\components\lib
      2) In user-mgt.xml we created

      Please help ASAP. We really need your help/guidance.

      Delete
  2. Excellent post. Really really helpful.

    ReplyDelete
  3. If you came across an error in Windows environment caused by,
    length of the index "REG_PATH_IND_BY_PATH_VALUE" in line 31 of mysql.sql script it too long

    At creating the database use the following command,

    CREATE DATABASE JDBC_demo_user_store CHARACTER SET latin1;

    The error occuurs because of the key length is too high when mysql uses UTF-8 encoding which is Windows default. The default encoding for mysql in linux environment is latin1.



    ReplyDelete
  4. This comment has been removed by a blog administrator.

    ReplyDelete
  5. Hi, i tried to implements org.wso2.carbon.user.api.UserStoreManager instead of extending JDBCUserStoreManager but i get a class cast exception : java.lang.ClassCastException: org.wso2.sample.user.store.manager.CustomUserStoreManager cannot be cast to org.wso2.carbon.user.core.UserStoreManager.

    I don't know if i miss something?

    ReplyDelete
  6. Hi Pushpalanka,

    I am trying to configure the WSO@ version 4.1.0 with the custom DB (Oracle 11g XE). I just fallowed the steps that you mentioned, but getting the exception below. Could you please help me in resolving the below error.

    [2014-02-03 22:12:51,749] ERROR {org.wso2.carbon.ldap.server.DirectoryActivator} - An unknown exception occurred while starting LDAP server.
    [com.ctc.wstx.exc.WstxLazyException] com.ctc.wstx.exc.WstxIOException: Invalid UTF-8 start byte 0xa0 (at char #13386, byte #11999)
    at com.ctc.wstx.exc.WstxLazyException.throwLazily(WstxLazyException.java:45)
    at com.ctc.wstx.sr.StreamScanner.throwLazyError(StreamScanner.java:720)
    at com.ctc.wstx.sr.BasicStreamReader.safeFinishToken(BasicStreamReader.java:3643)
    at com.ctc.wstx.sr.BasicStreamReader.getText(BasicStreamReader.java:848)
    at org.apache.axiom.util.stax.wrapper.XMLStreamReaderWrapper.getText(XMLStreamReaderWrapper.java:164)
    at org.apache.axiom.om.impl.builder.StAXOMBuilder.createComment(StAXOMBuilder.java:476)
    at org.apache.axiom.om.impl.builder.StAXOMBuilder.next(StAXOMBuilder.java:279)
    at org.apache.axiom.om.impl.llom.OMElementImpl.buildNext(OMElementImpl.java:653)
    at org.apache.axiom.om.impl.llom.OMNodeImpl.getNextOMSibling(OMNodeImpl.java:122)
    at org.apache.axiom.om.impl.traverse.OMChildrenIterator.getNextNode(OMChildrenIterator.java:36)
    at org.apache.axiom.om.impl.traverse.OMAbstractIterator.hasNext(OMAbstractIterator.java:58)
    at org.apache.axiom.om.impl.traverse.OMFilterIterator.hasNext(OMFilterIterator.java:54)
    at org.apache.axiom.om.impl.llom.OMElementImpl.getFirstChildWithName(OMElementImpl.java:273)
    at org.wso2.carbon.user.core.config.RealmConfigXMLProcessor.buildRealmConfiguration(RealmConfigXMLProcessor.java:148)
    at org.wso2.carbon.ldap.server.configuration.LDAPConfigurationBuilder.getUserManagementXMLElement(LDAPConfigurationBuilder.java:560)
    at org.wso2.carbon.ldap.server.configuration.LDAPConfigurationBuilder.buildPartitionConfigurations(LDAPConfigurationBuilder.java:368)
    at org.wso2.carbon.ldap.server.configuration.LDAPConfigurationBuilder.buildConfigurations(LDAPConfigurationBuilder.java:179)
    at org.wso2.carbon.ldap.server.DirectoryActivator.start(DirectoryActivator.java:60)
    at org.eclipse.osgi.framework.internal.core.BundleContextImpl$1.run(BundleContextImpl.java:711)
    at java.security.AccessController.doPrivileged(Native Method)
    at org.eclipse.osgi.framework.internal.core.BundleContextImpl.startActivator(BundleContextImpl.java:702)
    at org.eclipse.osgi.framework.internal.core.BundleContextImpl.start(BundleContextImpl.java:683)
    at org.eclipse.osgi.framework.internal.core.BundleHost.startWorker(BundleHost.java:381)
    at org.eclipse.osgi.framework.internal.core.AbstractBundle.resume(AbstractBundle.java:389)
    at org.eclipse.osgi.framework.internal.core.Framework.resumeBundle(Framework.java:1130)
    at org.eclipse.osgi.framework.internal.core.StartLevelManager.resumeBundles(StartLevelManager.java:559)
    at org.eclipse.osgi.framework.internal.core.StartLevelManager.resumeBundles(StartLevelManager.java:544)
    at org.eclipse.osgi.framework.internal.core.StartLevelManager.incFWSL(StartLevelManager.java:457)
    at org.eclipse.osgi.framework.internal.core.StartLevelManager.doSetStartLevel(StartLevelManager.java:243)
    at org.eclipse.osgi.framework.internal.core.StartLevelManager.dispatchEvent(StartLevelManager.java:438)
    at org.eclipse.osgi.framework.internal.core.StartLevelManager.dispatchEvent(StartLevelManager.java:1)
    at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230)
    at org.eclipse.osgi.framework.eventmgr.EventManager$EventThread.run(EventManager.java:340)


    Regards,
    Ravi

    ReplyDelete
    Replies
    1. Hi Ravindra,

      There is some invalid character in your user-mgt.xml.

      Delete
    2. Hi Pushpalanka, Yes you were right. There was some hidden junk characters in the xml file and i just removed those as well. But Still i am facing issues with it.

      TID: [0] [IS] [2014-02-11 12:51:06,232] ERROR {org.wso2.carbon.ldap.server.DirectoryActivator} - An unknown exception occurred while starting LDAP server. {org.wso2.carbon.ldap.server.DirectoryActivator}
      java.lang.NullPointerException: Name is null
      at java.lang.Enum.valueOf(Enum.java:235)

      A details logs are sent to your mail. Could you please guide me in resolving the issue.
      Thanks,
      Ravi

      Delete
  7. This comment has been removed by the author.

    ReplyDelete
  8. Hi Pushpamali,

    Download sample link is not working here. Could you kindly direct me to a correct link or can you send me the sample. My email
    suranga.herath@gmail.com

    Many Thanks,

    ReplyDelete
  9. Please find updated sample custom user store manager for WSO2 Identity Server at, https://svn.wso2.org/repos/wso2/people/pushpalanka/SampleCustomeUserStoreManager-5.0.0/

    ReplyDelete
  10. This comment has been removed by a blog administrator.

    ReplyDelete
  11. Hi Pushpalanka, After adding custom user store in the wso2, all users are displaying in read only mode. I have changed the ReadOnly property to false. But still its displaying in read mode.

    setProperty("ReadOnly","Read Only", "false", "Indicates whether the user store of this realm operates in the user read only mode or not");

    Could you please let me know how we can have custom user store in a read/write mode.

    Thanks

    ReplyDelete
    Replies
    1. Hi Ravindra,

      If you have built your custom user store manager on top of the provided sample, it carries a method as below, which you should override.

      " @Override
      public boolean isReadOnly() throws UserStoreException {
      return true;
      }"

      Please note the sample only demonstrates the basic functions and have not demonstrated the capability to switch between ReadOnly and ReadWrite modes.

      Thanks,
      Pushpalanka

      Delete
  12. Please provide me if you have sample examples for customizing error messages from customuserstore manager
    Thanks
    Kishore

    ReplyDelete
  13. Another use of the custom userstores can be found in [1].

    [1] http://tharindue.blogspot.com/2015/05/a-workaround-for-renaming-username-of.html

    ReplyDelete
  14. After create my custom user store, I can create secondary user store, but I can't update the configuration, I get this error.

    TID: [0] [IS] [2015-08-21 19:46:17,084] ERROR {org.apache.axis2.rpc.receivers.RPCInOnlyMessageReceiver} - Exception occurred while trying to invoke service method editUserStore {org.apache.axis2.rpc.receivers.RPCInOnlyMessageReceiver}
    java.lang.NullPointerException
    at java.util.concurrent.ConcurrentHashMap.hash(ConcurrentHashMap.java:333)
    at java.util.concurrent.ConcurrentHashMap.remove(ConcurrentHashMap.java:1175)
    at org.wso2.carbon.caching.impl.CacheImpl.getAndRemove(CacheImpl.java:486)
    at org.wso2.carbon.identity.user.store.configuration.UserStoreConfigAdminService.getAndRemoveRandomPasswordContainer(UserStoreConfigAdminService.java:713)
    at org.wso2.carbon.identity.user.store.configuration.UserStoreConfigAdminService.addProperties(UserStoreConfigAdminService.java:382)
    at org.wso2.carbon.identity.user.store.configuration.UserStoreConfigAdminService.writeUserMgtXMLFile(UserStoreConfigAdminService.java:607)
    at org.wso2.carbon.identity.user.store.configuration.UserStoreConfigAdminService.editUserStore(UserStoreConfigAdminService.java:236)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606) ...

    ReplyDelete
  15. HI Pushpa,

    I have a need in our project to get a list of currently logged-in users, we are using WSO2 for SAML token. Are there any APIs that provide you a list of users whose SAML token is still valid? or some other ways to get the list of currently login user?

    Regards

    ReplyDelete
  16. We are not able to see custom manager class in the management console in Identiy Server 5.0

    and not getting this log on server start up
    INFO {org.wso2.sample.user.store.manager.internal.CustomUserStoreMgtDSComponent} - CustomUserStoreManager bundle activated successfully.

    ReplyDelete
    Replies
    1. Hi Amzad,

      It means that the custom user store manager is not activated correctly in OSGI runtime. If you post the skeleton of the class + internal DS component class, would be able to help.

      Regards,
      Pushpalanka

      Delete
  17. MANIFEST FILE

    Manifest-Version: 1.0
    Export-Package: org.wso2.sample.user.store.manager.internal;uses:="org
    .apache.commons.logging,org.wso2.carbon.user.api,org.wso2.carbon.user
    .core.service,org.osgi.framework,org.osgi.service.component,org.wso2.
    sample.user.store.manager",org.wso2.sample.user.store.manager;uses:="
    org.wso2.carbon.user.core.claim,org.apache.commons.logging,org.wso2.c
    arbon.user.api,org.wso2.carbon.user.core.jdbc,org.wso2.carbon.user.co
    re.profile,org.wso2.carbon.user.core.util,org.wso2.carbon.user.core"
    Private-Package: org.wso2.sample.user.store.manager.*
    Built-By: amzad.mohammed
    Tool: Bnd-0.0.238
    Bundle-Name: sample01
    Created-By: Apache Maven Bundle Plugin
    DynamicImport-Package: *
    Build-Jdk: 1.7.0_67
    Bundle-Version: 1.0.0
    Bnd-LastModified: 1449552340869
    Bundle-ManifestVersion: 2
    Bundle-Description: A Simple Bundle which print "Hello World" and "Goo
    dbye World"
    Bundle-SymbolicName: sample01
    Import-Package: org.apache.commons.logging;resolution:=optional;versio
    n="1.1",org.osgi.framework;resolution:=optional;version="1.3",org.osg
    i.service.component;resolution:=optional;version="1.2",org.wso2.carbo
    n.user.api;resolution:=optional;version="1.0",org.wso2.carbon.user.co
    re;resolution:=optional;version="4.2",org.wso2.carbon.user.core.claim
    ;resolution:=optional;version="4.2",org.wso2.carbon.user.core.jdbc;re
    solution:=optional;version="4.2",org.wso2.carbon.user.core.profile;re
    solution:=optional;version="4.2",org.wso2.carbon.user.core.service;re
    solution:=optional;version="4.2",org.wso2.carbon.user.core.util;resol
    ution:=optional;version="4.2",org.wso2.sample.user.store.manager;reso
    lution:=optional,org.wso2.sample.user.store.manager.internal;resoluti
    on:=optional

    ReplyDelete
  18. Hi Pushaplanka ,
    Please find the internalDS Class and custom manager class
    public class CustomUserStoreMgtDSComponent {
    private static Log log = LogFactory.getLog(CustomUserStoreMgtDSComponent.class);
    private static RealmService realmService;

    protected void activate(ComponentContext ctxt) {

    CustomUserStoreManager customUserStoreManager = new CustomUserStoreManager();
    ctxt.getBundleContext().registerService(UserStoreManager.class.getName(), customUserStoreManager, null);
    log.info("CustomUserStoreManager bundle activated successfully..");
    }

    protected void deactivate(ComponentContext ctxt) {
    if (log.isDebugEnabled()) {
    log.debug("Custom User Store Manager is deactivated ");
    }
    }

    protected void setRealmService(RealmService rlmService) {
    realmService = rlmService;
    }

    protected void unsetRealmService(RealmService realmService) {
    realmService = null;
    }

    ReplyDelete
    Replies
    1. Hi Amzad,

      What I wanted to see was the imports in the class.
      Please for the imported class of "UserStoreManager.class.getName()" UserStoreManager here. It should be org.wso2.carbon.user.api.UserStoreManager and NOT from the core. Just a guess.

      Thanks,
      Pushpalanka

      Delete
  19. Please find the imports,

    CustomUserStoreManager class imports
    ---------------------------------------
    import org.apache.commons.logging.Log;
    import org.apache.commons.logging.LogFactory;
    import org.wso2.carbon.CarbonConstants;
    import org.wso2.carbon.user.api.Properties;
    import org.wso2.carbon.user.api.Property;
    import org.wso2.carbon.user.core.UserRealm;
    import org.wso2.carbon.user.core.UserStoreException;
    import org.wso2.carbon.user.core.claim.ClaimManager;
    import org.wso2.carbon.user.core.jdbc.JDBCRealmConstants;
    import org.wso2.carbon.user.core.jdbc.JDBCUserStoreManager;
    import org.wso2.carbon.user.core.profile.ProfileConfigurationManager;
    import org.wso2.carbon.user.core.util.DatabaseUtil;

    import java.sql.Connection;
    import java.sql.PreparedStatement;
    import java.sql.ResultSet;
    import java.sql.SQLException;
    import java.util.Date;
    import java.util.Map;


    CustomUserStoreMgtDSComponent imports
    -----------------------------------------
    import org.apache.commons.logging.Log;
    import org.apache.commons.logging.LogFactory;
    import org.osgi.service.component.ComponentContext;
    import org.wso2.carbon.user.api.UserStoreManager;
    import org.wso2.carbon.user.core.service.RealmService;
    import org.wso2.sample.user.store.manager.CustomUserStoreManager;

    ReplyDelete
  20. Hi Pushaplanka,
    First of all thanks for such nice post..
    I am totally new to wso2.
    I would like to know that same configuration/steps mentioned above can be applied to wso2 api manager 1.9.1. to create custom user store manager.
    As I have tried it but it gives me following error,
    {org.wso2.carbon.user.core.common.DefaultRealmService} - Cannot initialize the realm. {org.wso2.carbon.user.core.common.DefaultRealmService}
    org.wso2.carbon.user.core.UserStoreException: org.wso2.sample.user.store.manager.CustomUserStoreManagerType class java.lang.ClassNotFoundException

    also i have added jar in dropins and updated user-mgt.xml as,


    what is causing ClassNotFoundException

    ReplyDelete
    Replies
    1. Yes this is applicable to API Manager 1.9.1 version as well. This seems more like a problem with the custom component or the configuration.

      Delete
    2. We're facing issues while setting CustomUserStore in WSO2 IS tool. Could you please guide us how you able to make it successful ?
      The steps we followed are:-
      1) Downloaded source code from this link and created custom-user-store.jar file and place it to C:\wso2is-5.0.0\repository\components\lib
      2) In user-mgt.xml we created
      Please help ASAP. We really need your help/guidance.

      Delete
    3. thanks for your response Pushpalanka. It was really helpful.
      I missed this properties ,
      and
      inside user-mgt.xml.

      Delete
    4. This comment has been removed by the author.

      Delete
  21. Hi Pushpalanka,

    Thanks for the detailed post. I've tried this today to setup secondary store for Governance Registry (without Identity Server) as ReadonlyLDAPprovider but get the following error in the log

    file org.wso2.carbon.user.api.UserStoreException: Error occured during the transformation process of <>\repository\deployment\server\userstores\DomainName.xml
    at org.wso2.carbon.identity.user.store.configuration.UserStoreConfigAdminService.writeUserMgtXMLFile(UserStoreConfigAdminService.java:648)
    at org.wso2.carbon.identity.user.store.configuration.UserStoreConfigAdminService.addUserStore(UserStoreConfigAdminService.java:217)
    ...
    ...
    at org.wso2.carbon.identity.user.store.configuration.stub.UserStoreConfigAdminServiceStub.addUserStore(UserStoreConfigAdminServiceStub.java:905)
    at org.wso2.carbon.identity.user.store.configuration.ui.client.UserStoreConfigAdminServiceClient.addUserStore(UserStoreConfigAdminServiceClient.java:93)
    at java.lang.Thread.run(Thread.java:745)

    Can you please help?

    ReplyDelete
    Replies
    1. Hi, The issue seems to be at generating the XML file from the values you have entered for the secondary user store. Do you see the DomainName.xml file created at the mentioned location. If not try creating the file manually with the relevant configurations.

      Delete
  22. Hi,
    Is it possible with JDBCUserStoreManager to avoid reuse of password from UM_USER table?
    For such scenario I tried with CustomJDBCUserStoreManager and overriding doUpdateCredential() method. But it shows all user's as read-only. It does not provide any option to add user or change password with CustomUserStoreManager's domain in my case.
    Is it possible with CustomUserStoreManager as it shows all users are read-only ?

    ReplyDelete
    Replies
    1. Yes Sarang. CustomUserStoreManager can be overriden for your desired behavior. This sample implements a readOnly user store, hence no write operations allowed. You have freedom to extend a ReadWriteUserStoreManager or implement in such manner, overriding desired methods.

      Delete
  23. The quality can be tested with time. Our custom writing service has many years of experience and thousands of satisfied clients. Become one of them and order a high-quality paper with us!
    custom wrtiting

    ReplyDelete
  24. Hi Pushpalanka,
    i am not able to downlad the 'download the sample' as getting ubuntu services has closed
    where i need to download the file
    please suggest me

    ReplyDelete
    Replies
    1. New link is added in the end of the post. You can take it here, https://svn.wso2.org/repos/wso2/people/pushpalanka/SampleCustomeUserStoreManager-5.0.0/

      Delete
  25. Hi,
    According to your blog, I have successfully created CustomUserStore.jar and tested it with WSO2AM V1.9.1 and WSO2AM V1.10
    But when same (customuserstore.jar) i tried to use with WSO2AM 2.0.0, it was started for first time perfectly but second time when i tried to start WSO2AM2.0.0 i got following error on console,

    [2016-11-08 19:24:50,734] INFO - ConnectionCloseMethodHandler ConnectionClose frame received
    [2016-11-08 19:24:50,734] INFO - ConnectionCloseMethodHandler Error :530: not allowed:Thread-48
    [2016-11-08 19:24:50,736] ERROR - AMQStateManager Notifying Waiters([org.wso2.andes.client.state.StateWaiter@4965f48b]) for error:not allowed
    [2016-11-08 19:24:50,737] INFO - PassThroughListeningIOReactorManager Pass-through HTTPS Listener started on 0:0:0:0:0:0:0:0:8243
    [2016-11-08 19:24:50,744] INFO - ConnectionCloseOkMethodHandler Received Connection-close-ok
    [2016-11-08 19:24:50,745] ERROR - AMQProtocolHandler AMQP timed out when attempting to close the connection
    org.wso2.andes.AMQTimeoutException: Server did not respond in a timely fashion [error code 408: Request Timeout]
    ....
    ....
    [2016-11-08 19:24:50,745] INFO - AMQConnection Unable to connect to broker at tcp://192.168.200.11:5672
    org.wso2.andes.AMQException: Error occurred while establishing a connection

    Could you suggest what i need to do extra with WSO2AM2.0.0 ?
    Note: Same CustomUserStore.jar is working with WSO2AM - V1.9.1/V1.10 and WSO2IS - V5.0/V5.1

    ReplyDelete
  26. Hi,

    It would be great if you could update the download link in the post to https://svn.wso2.org/repos/wso2/people/pushpalanka/SampleCustomeUserStoreManager.zip

    It currently points to Ubuntu One location which is not accessible.

    ReplyDelete

Post a Comment

Popular posts from this blog

Signing SOAP Messages - Generation of Enveloped XML Signatures

How to send an HTML email in Java (Using Google SMTP Server)

Install Liferay over a MySQL Database