Reputation: 95
I have this simple oauth2 spring configuration where the JWT gets validated with an issuer uri.
@EnableWebSecurity
class WebSecurityConfiguration {
@Bean
fun filterChain(http: HttpSecurity): SecurityFilterChain {
http.authorizeRequests()
.antMatchers("/actuator/health").permitAll()
.antMatchers("/**").hasAnyRole("User", "Client")
.anyRequest().authenticated()
.and()
.oauth2ResourceServer()
.jwt()
.jwtAuthenticationConverter(jwtAuthenticationConverter())
return http.build()
}
private fun jwtAuthenticationConverter(): Converter<Jwt?, out AbstractAuthenticationToken?> {
val jwtConverter = JwtAuthenticationConverter()
jwtConverter.setJwtGrantedAuthoritiesConverter(KeycloakRealmRoleConverter())
return jwtConverter
}
}
Now for 1 endpoint i need custom token validation. I see 2 ways.
Anyways i need a custom token. Lets say i go for solution 1. How can i for an antmatcher have custom check. So that i can check if the token is the secret saved as environment variable.
antMatchers("/api/custom/players").CHECK with System.env("PLAYERS_TOKEN")
Upvotes: 0
Views: 1082
Reputation: 12694
You did not provide enough details about what your access-control rules should be from the business point of view, so I'll provide more concepts than specific implementation details.
As you are using JWTs, I would say that all the data required for access-control should be stored in the token. This requires you to configure authorization-server (Keycloak) to add relevant data in private claims. In Keycloak this is done with "mappers". Sample in this project (pay attention to Maven dependencies, implemented interfaces and resource files).
What I understand from your need is you have "players" who subscribe for a time limited access
Once you have all of required player data in the access-token, you can provide your own implementation of AbstractAuthenticationToken
(using jwtAuthenticationConverter
bean as you already do, just returning your own impl instead of JwtAuthenticationToken
). An implementation of your own would permit to hide private claims parsing from the rest of the code and help to write "readable" @PreAuthorize
security expressions. Sample of such a custom authentication implementation in this other module of the same repo. Sample usage in security expression (username
is a @PathVariable
):
@PreAuthorize("is(#username) or isNice() or onBehalfOf(#username).can('GREET')")
If you want to authenticate trusted clients without the context of a resource-owner ("real user") then this clients should use client-credentials flow to fetch access tokens from Keycloak:
From resource-server point of view, there will be no difference: all of the requests will be authorized with access-tokens issued by the same authorization-server.
Upvotes: 1