"principal-attribute": "preferred_username" is null

Hello! I developed a custom User Storage for Keycloak, which validates users by communicating with a servlet, so the users are not stored in Keycloak, and it works without issues during testing.

Now, in a second phase, I am configuring an app on WildFly 26.0.1 with Elytron OIDC (configuring it from within the app with oidc.json and web.xml).

When I try to access the protected resource, it redirects me to Keycloak, I log in, and it redirects me back to the protected resource where I want to call user.getName() from the Principal of the request, but it comes back as null.

This is the configuration of my oidc.json:

{
“client-id”: “client”,
“provider-url”: “http://localhost:8180/realms/master”,
“public-client”: false,
“credentials”: {
“secret”: “client_Secret”
},
“principal-attribute”: “preferred_username”,
“ssl-required”: “EXTERNAL”,
“confidential-port”: 0,
“use-resource-role-mappings”: false
}

As you can see, in the principal-attribute I use preferred_username (which I understand should be the username of the UserModel from my custom provider). I tried changing that property to, for example, “name” and it gives me the correct information for that property. Unfortunately, I need the username.

One interesting thing is that if I create a user via the admin console for my realm and use that user to log in, user.getName() gives me the username. Knowing that, I believe it may be some configuration issue in my custom provider.

i read many guides, stackoverflow question, but i didnt found anithing usefull, because most examples create the user in keycloak and thats not my case.

Did you override method getUsername in your custom User class? Also try to override getName and you can set to return from attribute.

Also check getAttribute methods and make sure that they are implemented. like:

 @Override
    public String getUsername() {
        return username;
    }

@Override
    public Map<String, List<String>> getAttributes() {
        MultivaluedHashMap<String, String> attributes = new MultivaluedHashMap<>();
        attributes.add(UserModel.USERNAME, getUsername());
        ......
        return attributes;
} 

    @Override
    public String getFirstAttribute(String name) {
        List<String> list = getAttributes().getOrDefault(name, List.of());
        return list.isEmpty() ? null : list.get(0);
    }

also I am not sure that there is getName in User model, there is getFrstName and getUsername…

Hello @djordje,

I have overridden the getUsername method in my CustomUserModel. The issue was, as you mentioned, that I had not implemented the getAttributes() method. Once I added that, the problem was resolved.

Regarding my previous mention of user.getName(), I was actually referring to the userPrincipal of the request:

Principal user = req.getUserPrincipal();
user.getName();

I apologize if this caused any confusion. Thank you for your help!

Best regards,

1 Like