Keycloak: AnonymousAuthenticationToken cannot be cast to KeycloakAuthenticationToken Keycloak: AnonymousAuthenticationToken cannot be cast to KeycloakAuthenticationToken spring spring

Keycloak: AnonymousAuthenticationToken cannot be cast to KeycloakAuthenticationToken


In your HttpSecurity http, add .anonymous().disable() such that you haveyour HttpSecurity like http.anonymous().disable().


I had the same problem in my microservice architecture.According to this this answer from Stian Thorgersen all ReST-Services should be bearer-only. Thus they should accept a token, but never perform a redirect to the login page.

Therefore I extracted the UI component from the service and serve it on a separate NGINX instance. The UI performs the redirect to my Keycloak login page and adds the token to every additional GET/POST/whatever request to secured services. I changed all ReST-Services to keycloak.bearer-only=true, both in the service and Keycloak configuration. It now works like a charm.

Hope this helps you.
Freddy


We want the developers to login at the API gateway to and call services form there directly. I achieved this finally by adding a Filter that extends the basic ZuulFilter:

public class KeycloakAuthorizationFilter extends ZuulFilter{private static final String AUTHORIZATION_HEADER = "Authorization";private static final String BEARER_TOKEN_TYPE = "Bearer";private static Logger log = LoggerFactory.getLogger(KeycloakAuthorizationFilter.class);@Overridepublic Object run(){    log.info("Adding authenticaton header...");    RequestContext ctx = RequestContext.getCurrentContext();    if (ctx.getZuulRequestHeaders().containsKey(AUTHORIZATION_HEADER)) return null;    KeycloakAuthenticationToken authentication = (KeycloakAuthenticationToken) SecurityContextHolder.getContext()            .getAuthentication();    if(authentication == null)    {        log.error("Could not load authenticaton from security context!");    }    else if(authentication.isAuthenticated() == false)    {        log.error("Not authenticated!");    }    else    {        Object principal = authentication.getPrincipal();        if(principal != null && principal instanceof KeycloakPrincipal)        {            @SuppressWarnings("unchecked")            KeycloakPrincipal<KeycloakSecurityContext> keycloakPrincipal = (KeycloakPrincipal<KeycloakSecurityContext>) authentication                    .getPrincipal();            log.info(String.format("Constructing Header %s for Token %s", AUTHORIZATION_HEADER, BEARER_TOKEN_TYPE));            ctx.addZuulRequestHeader(AUTHORIZATION_HEADER, String.format("%s %s", BEARER_TOKEN_TYPE, keycloakPrincipal.getKeycloakSecurityContext().getTokenString()));        }    }    return null;}@Overridepublic boolean shouldFilter(){    return true;}@Overridepublic int filterOrder(){    return 0;}@Overridepublic String filterType(){    return "pre";}}

This is just working awesome and gives you a lot more flexibility.