Search code examples
jwtopenid-connectopen-liberty

Liberty OIDC Provider: map name from basicRegistry to preferred_username in JWT


I'm trying to set up Liberty as OIDC provider. This configuration will be used in local dev environment, so I want to avoid a full blown LDAP configuration.

A minimal configuration would look like this:

<server description="myServer">

    <basicRegistry id="basic" realm="customRealm">
        <user name="myTestUser" password="test"/>
    </basicRegistry>

    ...
    

    <openidConnectClient id="RS" inboundPropagation="required"
                         clientId="my-api"
                         clientSecret="mySecret"
                         scope="openid profile email"
                         jwkEndpointUrl="https://localhost:9443/oidc/endpoint/my-oidc/jwk"
                         issuerIdentifier="https://localhost:9443/oidc/endpoint/my-oidc"
                         validationEndpointUrl="https://localhost:9443/oidc/endpoint/my-oidc/introspect">
    </openidConnectClient>

    <openidConnectProvider id="my-oidc"
                           oauthProviderRef="OAuthConfig"
                           keyStoreRef="defaultKeyStore">
    </openidConnectProvider>
    <oauthProvider id="OAuthConfig" jwtAccessToken="true" tokenFormat="jwt">
        <localStore>
            <client name="my-api" secret="mySecret"
                    displayname="my-api"
                    scope="openid profile email"
                    preAuthorizedScope="openid profile email"
                    jwkEnabled="true"
                    allowRegexpRedirects="true"
                    enabled="true">
                <redirect>....</redirect>
        </client>
        </localStore>
    </oauthProvider>
</server>

If I request a token, the result will look like this:

{
  "sub": "myTestUser",
  "token_type": "Bearer",
  "scope": [
    "openid",
    "profile",
    "email"
  ],
  "azp": "my-api",
  "iss": "https://localhost:9443/oidc/endpoint/my-oidc",
  "exp": 1697713877,
  "iat": 1697706677,
  "realmName": "customRealm",
  "uniqueSecurityName": "myTestUser"
}

In order for our implementation to work in dev as on prod environment, we need the additional claim "preferred_username" with the same value as "uniqueSecurityName" or "sub" (username from basic registry).

I tried using "claimToUserRegistryMap" with no success.

     <openidConnectProvider id="my-oidc"
                           oauthProviderRef="OAuthConfig"
                           keyStoreRef="defaultKeyStore"
                           customClaims="preferred_username">
        <claimToUserRegistryMap preferred_username="name" />
<!--        Tried alternatives-->
<!--        <claimToUserRegistryMap preferred_username="sub" />-->
<!--        <claimToUserRegistryMap preferred_username="username" />-->
<!--        <claimToUserRegistryMap preferred_username="uniqueSecurityName" />-->
    </openidConnectProvider>

I can't figure it out from reading the documentation and feel like I'm missing something, can someone point me in the right direction?


Solution

  • For anyone stumbling over this in the future, the solution is to use the claim "principalName" in the claim mapping tag, as the username of a user in basicRegistry is stored in this property. A working snippet would look like this:

        <openidConnectProvider id="my-oidc"
                           oauthProviderRef="OAuthConfig"
                           keyStoreRef="defaultKeyStore"
                           customClaims="preferred_username">
        <claimToUserRegistryMap preferred_username="principalName"/>
    </openidConnectProvider>