3

I am trying to fetch a custom attribute (phone_number) in the form of a claim from Keycloak. I am following the steps given here. Below are attached screenprints of the steps I have executed.

  1. Adding attribute to user

Adding attribute to user

  1. Protocol mapper

Protocol mapper

  1. Protocol mapper is available in Client scope -> evaluate for the above-mentioned client Client scope

I am now trying to access this attribute in a filter as follows.


public class FilterTest extends OncePerRequestFilter {
    
    public static final String PHONE_NUMBER = "phone_number";    

    public FilterTest() {
    }

    @Override
    protected void doFilterInternal(
            final HttpServletRequest request,
            final HttpServletResponse response,
            final FilterChain filterChain) throws ServletException, IOException {

        final Authentication authentication = SecurityContextHolder.getContext().getAuthentication();

        if( !AnonymousAuthenticationToken.class.isAssignableFrom(authentication.getClass()) ){
            Principal principal = (Principal) authentication.getPrincipal();
            if (principal instanceof KeycloakPrincipal) {
                KeycloakPrincipal<KeycloakSecurityContext> kp = (KeycloakPrincipal<KeycloakSecurityContext>) principal;
                AccessToken token = kp.getKeycloakSecurityContext().getToken();
                Map<String, Object> otherClaims = token.getOtherClaims();
                System.out.println("Phone number => "+otherClaims.get(PHONE_NUMBER); // null pointer
            }
        }    
        filterChain.doFilter(request, response);

    }

}

Additional things that I have tried.

  1. Clear the realm cache.
  2. Add the built-in phone number protocol mapper.

The above two steps also didn't yield any results for me.

I am not sure what I am missing here. Any help is appreciated.

1 Answers1

3

Keycloak is mapping some of the common fields from the custom attributes directly to the fields of IDToken class. In my case, phone number was a field in the IDToken class and I was trying to fetch it from otherClaims map. The following is the change in code snip that got me up and running.

                AccessToken token = kp.getKeycloakSecurityContext().getToken();
                phoneNumber = token.getPhoneNumber();