當CLIENT或用戶在KEYCLOAK中成功登錄后,會返回JWT字符串,其中默認含有權限的信息,但此信息以內嵌的方式呈現,非常不方便。
"resource_access": {
"app-springboot-confidential": {
"roles": [
"user"
]
},
"test-employee-service": {
"roles": [
"READ_EMPLOYEE"
]
},
"service-springboot": {
"roles": [
"READ_PRODUCTS"
]
},
"account": {
"roles": [
"manage-account",
"manage-account-links"
]
},
"test-department-service": {
"roles": [
"READ_DEPARTMENT"
]
}
}
- 需要將權限的信息輸出到一個KEY中,這時可以新增自定義CLIENT SCOPE。Mapper中新增KEYCLOAK已內置的【realm roles/client roles】,定義輸出到JTW的字段名:my-roles。
- 授權哪些CLIENT可以讀取此CLIENT SCOPE.
- 在登錄參數scope中,加入此值:my-roles,這樣在輸出的JWT就會以平面的方式輸出所有roles
"my-roles": [
"user",
"READ_EMPLOYEE",
"READ_PRODUCTS",
"manage-account",
"manage-account-links",
"READ_DEPARTMENT",
"offline_access",
"user"
]
@Bean
public ReactiveJwtAuthenticationConverter jwtAuthenticationConverter(ObjectMapper objectMapper) {
JwtGrantedAuthoritiesConverter jwtGrantedAuthoritiesConverter = new JwtGrantedAuthoritiesConverter();
jwtGrantedAuthoritiesConverter.setAuthorityPrefix("ROLE_");
jwtGrantedAuthoritiesConverter.setAuthoritiesClaimName("my-roles");
// KeycloakRealmRoleConverter keycloakRealmRoleConverter = new KeycloakRealmRoleConverter(objectMapper);
ReactiveJwtGrantedAuthoritiesConverterAdapter reactiveJwtGrantedAuthoritiesConverterAdapter =
new ReactiveJwtGrantedAuthoritiesConverterAdapter(
// new KeycloakRealmRoleConverter(objectMapper);
jwtGrantedAuthoritiesConverter
);
ReactiveJwtAuthenticationConverter jwtConverter = new ReactiveJwtAuthenticationConverter();
jwtConverter.setJwtGrantedAuthoritiesConverter(reactiveJwtGrantedAuthoritiesConverterAdapter);
return jwtConverter;
}
ServerHttpSecurity
.authorizeExchange(
a -> a.pathMatchers("/", "/error").permitAll()
.matchers(PathRequest.toStaticResources().atCommonLocations()).permitAll()
.pathMatchers(HttpMethod.GET, "/protected/**").hasRole("READ_DEPARTMENT")
.anyExchange()
.authenticated()
)