2
votes

I need to implement a JAAS LoginModule in Liberty.

I've been able to implement and configure (the login() and commit() methods are executed and return true) the custom module but it still does not work (I am still redirected to the login page as if the container doesn't really considers the user authenticated).

Based on what I've read on the IBM documentation I'm pretty sure I need to do something in the "login() method" I just don't know what. I've seen some examples where things are added to the Subject or the "sharedState" map but I don't seam to be able to figure out exactly what my code needs to so.

So some code examples of how to pass the user/group/role back to the container would be appreciated.


I've managed to make some progress, now the authentication works but the authorization does not.

I've added this code to the login() method:

    java.util.Hashtable<String, Object> customProperties = 
            (java.util.Hashtable<String, Object>) sharedState.
            get(AttributeNameConstants.WSCREDENTIAL_PROPERTIES_KEY);
    if (customProperties == null) {
        customProperties = new java.util.Hashtable<String, Object>();
    }

    customProperties.put(AttributeNameConstants.WSCREDENTIAL_UNIQUEID, username);
    customProperties.put(AttributeNameConstants.WSCREDENTIAL_SECURITYNAME, username);
    ((Map<String, Object>)sharedState).put(AttributeNameConstants.WSCREDENTIAL_PROPERTIES_KEY,
            customProperties);

After this it all works but only if I use the following in the server.xml:

 <application-bnd>
    <security-role name="adminrole">
      <special-subject type="ALL_AUTHENTICATED_USERS" />
    </security-role>
  </application-bnd>

So all authenticated users have the role needed to access my application.

But if I try to replace the special subject with a user or a group I get an error which says:

CWWKS9104A: Authorization failed for user userXXX:defaultRealm while invoking CustomLoginTest on /. The user is not granted access to any of the required roles: [adminrole].

So there must be other things to return from the login() method (maybe I need to set something in the subject also). Adding the list of user groups to the sharedState map does not work also:

customProperties.put(AttributeNameConstants.WSCREDENTIAL_GROUPS, groups);
2

2 Answers

1
votes

It's need other default loginModules to create WebSphere credential for authentication. Take a look at this document for how to configure the JAAS custom login modules. https://www-01.ibm.com/support/knowledgecenter/SSEQTP_8.5.5/com.ibm.websphere.wlp.doc/ae/twlp_sec_jaas.html?cp=SSEQTP_8.5.5&lang=en Your custom JAAS login module can pass the user information to other default loginModule using the hashmap either in the sharedState or subject.

1
votes

And now the final part of the puzzle. For the authorization to work the code needed to return the groups of the user and those groups needed to exist in a basic registry. The code looks like this:

    customProperties.put(AttributeNameConstants.WSCREDENTIAL_UNIQUEID, username);
    customProperties.put(AttributeNameConstants.WSCREDENTIAL_SECURITYNAME, username);
    List<String> groups = new ArrayList<String>();
    groups.add("oidc-users");       
    customProperties.put(AttributeNameConstants.WSCREDENTIAL_GROUPS, groups);

And the server.xml:

<basicRegistry id="basic" realm="BasicRealm">
    <group name="oidc-users"></group>
</basicRegistry>

<webApplication id="CustomLoginTest" location="CustomLoginTest.war" name="CustomLoginTest">
 <application-bnd>
    <security-role name="authenticated">
        <group name="oidc-users" />
    </security-role>
  </application-bnd>
</webApplication>

And of course the web.xml:

<security-constraint>
    <web-resource-collection>
        <web-resource-name>Demo Servlet</web-resource-name>
        <url-pattern>/ *</url-pattern>
    </web-resource-collection>
    <auth-constraint>
        <role-name>authenticated</role-name>
    </auth-constraint>
</security-constraint>