I am having a spring webflux based GraphQL application. The application is configured as resourceServer and I am able to access the /graphql endpoint by passing JWT token.
Within the JWT token there are claims that I want to access. I am trying to use the ReactiveSecurityContextHolder.getContext() but getting null every time.
ReactiveSecurityContextHolder.getContext()
.map(SecurityContext::getAuthentication)
.map(Authentication::getPrincipal)
.cast(Jwt.class)
The above code is in the GraphqlQueryResolver class. For graphql I are using the below dependency.
<dependency>
<groupId>com.graphql-java-kickstart</groupId>
<artifactId>graphql-spring-boot-starter</artifactId>
<version>12.0.0</version>
</dependency>
Below is the security configuration.
@Configuration
@EnableWebFluxSecurity
@EnableReactiveMethodSecurity
public class SecurityConfig {
@Bean
public SecurityWebFilterChain securityWebFilterChain(ServerHttpSecurity http) {
return http
.csrf(spec -> spec.disable())
.authorizeExchange().pathMatchers("/api/**").permitAll()
.anyExchange().authenticated().and()
.oauth2Login()
.and()
.oauth2ResourceServer()
.jwt().and().and().build();
}
}
Now I am getting a UUID as part of the access token claim which I want to access on my graphql resolver class. But every time I try to get the JWT using the above code I am getting null.
If I try to get the same in @RestController with @AutheticationPrincipal it works perfectly. But I want to access the same using the SecurityContext in graphql resolver class.
Here is a simple resolver
public class CustomerResolver implements GraphQLQueryResolver {
public Mono<String> getCustomerById (){
return ReactiveSecurityContextHolder.getContext()
.map(ctx -> ctx.getAuthentication())
.map(authentication -> {
if(authentication instanceof OAuth2AuthenticationToken){
return ((OAuth2AuthenticationToken) authentication).getPrincipal().getAttributes();
} else if(authentication instanceof JwtAuthenticationToken){
return ((JwtAuthenticationToken) authentication).getTokenAttributes();
}
return null;
}).map(jwt -> String.valueOf(jwt));
}
}
And the corresponding schema file for graphql
type Query {
getCustomerById: String
}
Try to create minimal example to isolate the issue. The following worked for me with your security configuration but without
Okta.configureResourceServer401ResponseBody(http);
Here is a test using
org.springframework.security:spring-security-test