A custom registry is a registry that you implement using the com.ibm.websphere.security.UserRegistry Java interface, as provided by the product. A custom registry can support virtually any type of account repository from a relational database, flat file, and so on. For this sample, a file-based user registry is implemented by the FileRegistrySample.java file and users and groups are defined in the users.props and groups.props files (see the Custom User Registry sample to download the files).

In this sample, WebSphere Application Server Developer Tools are used to create a Liberty feature for the custom user registry implementation. An OSGi bundle is created with bundle activation and FileRegistrySample.java file is imported. The Activation class is modified to register it as an OSGi service and to receive configuration data. The Liberty feature is created with the OSGi bundle which can be installed into an existing Liberty profile server and used to configure a custom user registry for user applications.

Attention: The sample provided is intended to familiarize you with this feature. Do not use this sample in an actual production environment.

Procedure

  1. Implement the custom user registry (FileRegistrySample.java file). For more information, see Developing the UserRegistry interface for using custom registries.
  2. Creating an OSGi bundle with Bundle Activation. This can be achieved by using Eclipse and the WDT tool. For more information, see Developing an OSGi bundle with simple activation
    1. Create an OSGi Bundle Project and choose to create an Activator class
    2. Import the FileRegistrysample.java file
    3. Change the Activator class to extend the FileRegistrySample class and implement BundleActivator, ManagedService
    4. Register the services. Add processing so that user and groups files defined in the server.xml file are passed to the FileRegistrySample.java file. The Liberty profile configuration is managed by the OSGi Configuration Admin service and can be accessed according to the OSGi Configuration Admin service specification.
    5. Make sure that correct import statements are added for the bundle.
  3. Create the Liberty Feature using the tool:
    1. Click on New -> OSGi -> Liberty Feature
    2. Add the OSGi bundle which was created in the above step
    3. It will create a subsystem.mf file which is later renamed as the feature_name.mf file
    4. This feature can be installed into the runtime by right clicking the feature name in the tool and choosing "Install Feature"
    5. For more information, see Liberty profile: Product extension
  4. Export the Liberty feature: Right-click on the feature name and export the feature as an .esa file
  5. Install the feature: Install the exported .esa file by running the command below from the bin directory in the Liberty profile installation:
        featureManager install sampleCustomUserRegistry-1.0.esa

    This will put the feature bundle in the ${wlp.user.dir}/extension/lib directory and the .mf file in the ${wlp.user.lib}/extension/lib/features directory.

  6. Configure the server.xml file:
    1. After the feature is installed into the user product extension location, configure the server.xml file with the feature name. For example:
      <featureManager>
            <feature>usr:sampleCustomUserRegistry-1.0</feature>
          </featureManager>
      
    2. Add the configuration information:
      <customUserRegistry usersFile="${server.config.dir}/resources/security/users.props" groupsFile="${server.config.dir}/resources/security/groups.props" />
      
    3. Add an application which will use this custom user registry for authentication. For example,
      <application type="ear" id="SecureEJBSample" name="SecureEJBSample" location="${server.config.dir}/apps/SecureEJBSample.ear">
            <application-bnd>
              <security-role name="servletRole">
                <special-subject type="ALL_AUTHENTICATED_USERS" />
              </security-role>
              <security-role name="ejbRole">
                <user name="user1" />
              </security-role>
            </application-bnd>
          </application>
      
  7. Execute the application:
    1. Access the protected resource. For example:
      http://localhost:9080/SecureEJBSample/sampleServlet
    2. At the prompt, enter the valid user from custom user registry which is also mapped to a role in the application binding for authorization:
      • user: user1
      • password: user1pwd
    3. Confirm that the servlet output is as follows:
      In SecureEJBServlet, Hello Secure EJB World.

Files needed for the sample:

The following files are included in the CustomUserRegistrySample.jar file:

  1. The sampleCustomUserRegistry-1.0_1.0.0.201306201237.esa file contains the sample custom user registry source and binaries
  2. The users.props file contains sample users and it is in the CustomUserRegistrySample server’s resources/security directory
  3. The groups.props file contains sample groups and it is in the CustomUserRegistrySample server’s resources/security directory
  4. The SecureEJBSample.ear file contains sample application and source and it is in the CustomUserRegistrySample server’s apps directory

15 Comments on "Creating a custom user registry as a Liberty user feature"

  1. Jessica Pamdeth April 28, 2016

    With all the interest in relational database based user registries, is it possible to get an example of using that? This seems a more practical example than the file based one provided now.

  2. Joe Kesselman January 28, 2016

    Something that may not be obvious: The com.ibm.ws.samples.cur package in the sample Custom User Registry needs OSGi access to the Liberty SPI layer, not just APIs. To recompile it under Eclipse, you will probably need to go to Preferences/Plug-in Development/Target Platform, and explicitly switch to the “with SPI” server target. If you don’t, you’ll get compilation errors.

  3. I can’t seem to make the groups part working. Of course with a custom user registry I do not want to map users to roles in the server.xml file, but in the database.
    However, when I remove the for example so that only specific users have for example the servletRole. I added
    “servletRole:006:user1″ to the groups file, but the only thing I get is this error log:
    [AUDIT ] CWWKS9104A: Authorization failed for user user1:defaultRealm while invoking SecureEJBSampleEAR on /. The user is not granted access to any of the required roles: [servletRole].

    What am I missing here?

    Btw: we are using liberty 8.5.5 and the sample seems to be written to an older API version. I get complaints about the WSCredential class not being part of the API for example.

    • Teddy_J_Torres September 17, 2015

      Hi Fachat,

      Thank you for using WAS Liberty. The authorization is configured separately from the user registry. Since you want to use the role mapping in a database, then you can use JACC to achieve this. For more details on how to develop a JACC provider, please see the Knowledge Center article http://www14.software.ibm.com/webapp/wsbroker/redirect?version=phil&product=was-nd-dist&topic=twlp_developing_jacc_auth_provider

      If you do not use JACC, then the role mapping for authorization must be configured either in the server.xml, the ibm-application-bnd.xml, or the ibm-application-bnd.xmi file as described in this other article, http://www14.software.ibm.com/webapp/wsbroker/redirect?version=phil&product=was-nd-dist&topic=twlp_sec_rolebased

      Once the role mapping for authorization is done using any of the above methods and the user or the group it is in is mapped to the role, the user will be authorized and the message CWWKS9104A will not be issued.

      The WSCredential API is included in the jar file com.ibm.websphere.appserver.api.basics_1.0.2.jar that is located in the wlp/dev/api/ibm directory. Please ensure that this jar file is in the classpath when editing or compiling your classes.

      Regards,
      Teddy J. Torres

      • Hi Terry, thank you for your answer!

        In the meantime I managed to get it to work. Liberty calls the “getUniqueGroupIds(user)” method, which in the File Registry Sample uses the users file. I overlooked that because I found the groups/user mapping in the groups file. So then mapping the registry group to the JEE group in server.xml worked, which is ok.

        Unfortunately I also use a custom JAAS provider together with the custom user registry. I had understood that JAAS would allow that user/role mapping, but with liberty obviously not.

        Now when using a JAAS provider, the getUniqueGroupIds(user) method is not called anymore. Some questions:

        1) what do I need to do in the JAAS provider to have the roles checked with the custom user registry?
        2) Is a JAAS provider necessary when I have a custom user registry and implement its checkPassword() method?
        3) Can I use this (setup from 2.) with Bluemix ID as a Service Single-Sign-On “password” checks as well? (i.e. call out via HTTP to another service?)

        Many thanks!

        • Teddy_J_Torres September 22, 2015

          Hi Fachat,

          I am glad that the Custom User Registry is now working for you. Let us clarify some terminology to avoid problems or confusion. Please let me know if you meant JACC instead of JAAS. JAAS is used during the authentication phase. It is also during that phase when the custom registry is used to verify the user is who it says it is. On the other hand, when a JACC provider is configured it is used during the authorization phase after the authentication has taken place. If you still need to use the custom registry from the JACC provider, then a service reference should be added to the JACC provider for the custom user registry. That might not be necessary since the WSCredential in the Subject should already contain the groups the authenticated used is in. A JACC provider is necessary if the role is not already mapped in the server.xml or in the bindings (ibm-application-bnd.xml, or the ibm-application-bnd.xmi file). SSO will work regardless of registry type or whether JACC is used or not. The one requirement is that the user should exist in the user registry of the server where the request is being sent to.

          Regards,
          Teddy J. Torres

          • Hi Teddy,
            thanks for your answer. We are in fact using a custom JAAS module to authenticate users, and also assign them roles. I think what I stumbled over was that JAAS can authenticate any user even users that are not(!) configured in the user registry – but roles do not work this way. They need to be configured in the user registry.

            As we are using a static set of roles, we can configure them in the basic user registry, and are set with our JAAS provider, without need for a JACC module.

            Regards,
            André

  4. I am trying to implement a similar customUserRegistry but with database.
    In my user registry class i need to make a DB connection.
    Is there any API i can use to read my DB credentials (schema, user, password, etc) form server.xml.

    • Teddy_J_Torres March 26, 2015

      Hi Akshat,

      Thank you for using the custom user registry support. There is no API to extract the user or password for a DB in server.xml. The OSGi service component xml file should be configured to receive configuration and the service should process the configuration during its activation. Also, please note the restrictions on using a datasource from a custom user registry as documented in http://www14.software.ibm.com/webapp/wsbroker/redirect?version=phil&product=was-nd-iseries&topic=tsectbucs. It indicates to use the JDBC java.sql.DriverManager interface to connect to the database.

      Regards,

      Teddy J. Torres

  5. I have installed the CustomUserRegistry sample feature and added the feature to my server. If I add the configuration information to the corresponding server.xml file my eclipse (editor) show the statement as being in error since is not recognized by my eclipse (syntax checker). However that statement is recognized by my server and the attributes are passed to the feature which is working fine.
    Is there a way to define as a valid xml tag or is there something missing in the feature definition.

    Thanks and kind regards
    Stefan Sell

  6. Roman Kharkovski September 10, 2014

    Your file based registry sample works well for me, but now I am changing it to the database and here is the question – I have JPA based classes that deal with users in the database in my web app that runs on Liberty 8.5.5.3. I am developing in Eclipse.

    I want to use the same JPA classes inside of the custom user registry. What is the best way to package and share these classes between my web app and the custom registry?

    Shall I create a separate Java project for my persistent classes and bundle the jar file with custom registry as well as web app? (this will cause duplication of classes) Or shall I create some shared library with my JPA classes and use it with both custom registry and web app? Or does it need to be OSGi bundle? I am afraid I am going to have problem doing JPA resource injection in OSGi bundle…

  7. Teddy_J_Torres August 27, 2014

    Hi,
    The SecurityEJBSample.ear is included in the sample CustomUserRegistrySample.jar download file. The sample can be downloaded from https://developer.ibm.com/wasdev/downloads/#asset/samples-Custom_User_Registry

    There is also another sample page dedicated to just the Secure EJB sample and it can be found here, https://developer.ibm.com/wasdev/downloads/#asset/samples-Secure_EJB_Sample

  8. CHK1_pushka_pushka August 24, 2014

    Where is the sources of SecureEJBSample.ear? Can’t finish this tutorial without it. Please, publish. Thanks.

Join The Discussion

Your email address will not be published. Required fields are marked *