kinglite
kinglite

Reputation: 349

Liberty ldap security-role/group mapping not working

In my server.xml I have the following configuration:

<enterpriseApplication location="myApp.ear" name="myApp" id="myapp" autoStart="true">
    <classloader commonLibraryRef="global" apiTypeVisibility="spec, ibm-api, api, third-party"/>
    <application-bnd >
        <security-role name="MyAdmin">
            <group name="App.Admin"/>
            <group name="cn=App.Admin,ou=ent,ou=App,ou=apps,o=somedir"/>
            <!--user name="memyselfandi"/-->
            <!--group name="App.Admin" access-id="group:LdapRegistry/cn=App.Admin,ou=ent,ou=App,ou=apps,o=somedir"/-->
        </security-role>
    </application-bnd>
</enterpriseApplication>

My subject after the authentication looks like this:

    Principal: WSPrincipal:uid=MEMYSELFANDI,ou=person,o=somedir
    Public Credential: com.ibm.ws.security.credentials.wscred.WSCredentialImpl@b29eac,
        realmName=LdapRegistry,
        securityName=MEMYSELFANDI,
        realmSecurityName=LdapRegistry/MEMYSELFANDI,
        uniqueSecurityName=uid=MEMYSELFANDI,ou=person,o=somedir,
        primaryGroupId=null,
        accessId=user:LdapRegistry/uid=MEMYSELFANDI,ou=person,o=somedir,
        groupIds=[SomeOtherGroups, App.Admin]
    Private Credential: CustomLoginModuleCredential
    Private Credential: com.ibm.ws.security.token.internal.SingleSignonTokenImpl@7c2ff51c

The groupIDs were set by my custom login module, because the group in the ldap registry has no entries in the attribute with the members and thus were not set by standard Liberty login modules. So in my custom module I search for the user in LDAP and add the groups of the entry to the groupIds array of the private credentials:

WSCredential credential = (WSCredential) _sharedState.get(com.ibm.wsspi.security.
                auth.callback.Constants.WSCREDENTIAL_KEY);
String[] grpList = ldapEntry.getAttribute("myEntGrps").getValues();
[..]
credential.getGroupIds().add(grpList[i]);

Is there something else I would have to do or is it sufficient to just add the String of the groups to the array?

I also tried using the securityGroupName (e.g. cn=myGroup,ou=...) instead of just the group name (e.g. myGroup).

What would be the right format?

With this all, when I call my protected servlet, I get the error message:

CWWKS9104A: Authorization failed for user uid=MEMYSELFANDI,ou=person,o=somedir while invoking myApp on /. The user is not granted access to any of the required roles: [MyAdmin].

When I change the configuration in the server.xml to accept the user memyselfandi, I get access. So the configuration is working for users but not groups. I also tried using access-id, but this also did not work (my LDAP realm is named LdapRegistry).

In the trace.log I see the following (log entry is truncated by Liberty I guess):

 ppbnd.internal.authorization.AppBndAuthorizationTableService 3 Added the following subject to role mapping for application: myApp.
    App.Admin
    []
[..]
< updateMapsForAccessId Exit
    {user:LdapRegistry/uid=MEMYSELFANDI,ou=person,o=somedir=[],App.Admin=[]}

With user configured in the server.xml, the role is mapped to the user user:LdapRegistry/uid=MEMYSELFANDI,ou=person,o=somedir=[MyAdmin]

Is there some way to test why it is not working? Maybe it's some LDAP configuration issue? What can I set to get the needed log information? Currently I log:

traceSpecification="*=info:com.ibm.ws.security.*=all:com.ibm.websphere.security.*=all:com.ibm.ws.webcontainer.security.*=all:com.ibm.ws.wim.*=all"/>

I would like to know what is processed in the background when the groups are tried to be mapped. Or better, the error I make so that the groups cannot be mapped or found.

Upvotes: 3

Views: 1498

Answers (1)

kinglite
kinglite

Reputation: 349

After some testing, it turns out, that when you add the groups to the subject you have to use the "access-id" format.

So this is what my login module now does:

WSCredential credential = (WSCredential) _sharedState.get(com.ibm.wsspi.security.
            auth.callback.Constants.WSCREDENTIAL_KEY);
UserRegistry registry = RegistryHelper.getUserRegistry(credential.getRealmName());
String[] grpList = ldapEntry.getAttribute("myEntGrps").getValues();
[..]
  credential.getGroupIds().add("group:"+credential.getRealmName()+"/"+registry.getGroupSecurityName(grpList[i]));

In the end the group entry will look like this:

group:MyLdapRealm/cn=myGroup,ou..

Upvotes: 1

Related Questions