I migrate from Zuul Gateway to Spring Gateway. This forced me to abandon Servlets for Webflux. I use KeyCloak and KeyCloak roles for authentication and authorization.
There is no official reactive KeyCloak implementation, so I use Spring OAuth2 instead. It works fine apart from retrieving the roles.
I cannot use servlet interceptors, because servlets are not allowed by WebFlux. Also, it seems Spring Gateway in general does not allow intercepting response bodies.
Thus my problem remains: How do I retrieve KeyCloak roles in Spring Gateway, so that they can be used by its security?
Here is some sample code I use: In class SecurityConfig.java:
@Bean public SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) { http.csrf().disable().authorizeExchange(exchanges -> exchanges.pathMatchers("/**").hasAnyRole("DIRECTOR")); }
application.yml:
spring.security.oauth2.client.provider.keycloak.issuer-uri: ..../realms/default
I am having the same problem myself. One of the problems I am getting its getting copies of things like the
JWT
tag i.e. the text thatKeycloak
has encode you settingsThis code will get you some of the values that are part of the conversation, the Token part is the
JWT
token, you can copy and paste that intojwt.io
and find out what whatKeycloak
has actually sent.This normally looks like
}
As you can see
Keycloak
supports two different types of ROLE tokens, but they are not defined in top level, but underrealm_access
andresource_access
, the difference being resource access defines ROLE that are part of a resource and real_access defines roles that are defined across all realms.To get these values defined, its necessary to define a Mapper, as follows
To load these values in to Spring security you need to define a
userAuthoritiesMapper
Bean and export the settings found in the attributes asSimpleGrantedAuthority
, as follows.Please note this code is based on a sample found at OAuth2 Login with custom granted authorities from UserInfo The access to Attributes is my own work.
Note an error message will be generated at the highest level if no
realm_access
orresource_access
is found, as I assume that wanting to decode aKeycloak
reference is the reason for using this code.When working correctly, it generates the following output