Keycloak policy enforcement with spring security dependency

Viewed 38

I'm trying to figure out how to make work Keycloak policy enforcement in a spring boot application that contains only spring security dependency.

keycloak starter dependency is not present as the application is reactive and keycloak security starter doesn't work for reactive stack.

How can I use policy enforcement with spring security dependency ? I precise that I want to use policy enforcement with lazy path (fetched from keycloak instance)

Thanks !

1 Answers

If your "policy enforcement" is role based only, it is pretty straight-forward: map spring Authorities from Keycloak realm_access.roles private claim (and resource_access.{client-id}.roles if you activated client roles mapper). Samples here:

  • webflux-jwtauthenticationtoken uses spring-addons-webflux-jwt-resource-server only (but requires quite some java conf)
  • webflux-oauthentication uses spring-addons on top of spring-addons-webflux-jwt-resource-server (adds some default auto-configuration you can override => much less java conf)

If your policies involve more than just roles, then you might have to override Authentication converter to return an implementation of your own. I do something like that in this tutorial (it is servlet based but translating it to reactive apps is straight-forward once you understood the 2 samples linked before).

The resources above build Authentication instances from the JWT access-token only, which is very efficient. Of course, in a JwtAuthenticationConverter of yours, you can inject any service issuing requests to the authorization-server (or any other source) for additional data, which can consume a lot of resources. I personally prefer to:

  • enrich tokens with mappers so that all required security data is embedded in JWTs
  • provide Authentication implementations well adapted to business needs (if more than username and roles is required by security rules, then authentication should expose it)
  • extend spring security DSL to make @PreAuthorize and @PostFilter expressions ... very expressive. For instance: @PreAuthorize("is(#username) or isNice() or onBehalfOf(#username).can('greet')"), taken from the tutorial linked above
Related