Reputation: 315
I am wondering if it is possible to obtain the Authentication
from within the onField
function contained in a SchemaDirectiveWiring
.
I've looked into using the ReactiveSecurityContextHolder
and SecurityContextHolder.getContext().getAuthentication()
and ReactiveSecurityContextHolder.getContext().block().getAuthentication()
, but both return null (which does make sense since its being called from within an asynchronous thread).
I therefore looked into using the [ReactiveDgsContext][1]
which looks promising as when debugging the code, I can see within the reactorContext that there is a SecurityContext key/value, but I don't know how to access it/retrieve it properly.
Currently, my code looks as follows:
DataFetcher<?> authDataFetcher = DataFetcherFactories
.wrapDataFetcher(originalFetcher, ((dataFetchingEnvironment, value) -> {
ReactiveDgsContext context = ReactiveDgsContext.from(dataFetchingEnvironment);
if(context != null){
ContextView reactiveContext = context.getReactorContext();
...
}
Any help would be much appreciated!
Upvotes: 0
Views: 753
Reputation: 315
I wasn't able to figure out a way of getting the Authentication out of the ReactiveDgsContext object, but as a workaround, I created a custom context.
public record CustomContext(ServerRequest webExchange, SecurityContext securityContext) {
}
And then registered it as follows:
@Configuration
public class DgsConfiguration {
@Bean
public DgsReactiveCustomContextBuilderWithRequest<CustomContext> dgsReactiveCustomContextBuilder() {
return (map, httpHeaders, serverRequest) -> ReactiveSecurityContextHolder.getContext()
.map(securityContext -> new CustomContext(serverRequest, securityContext))
.defaultIfEmpty(new CustomContext(serverRequest, null));
}
}
Then you can access it as follows:
DataFetcher<?> authDataFetcher = DataFetcherFactories
.wrapDataFetcher(originalFetcher, ((dataFetchingEnvironment, value) -> {
ReactiveDgsContext context = ReactiveDgsContext.from(dataFetchingEnvironment);
if (context != null) {
CustomContext customContext = (CustomContext) context.getCustomContext();
if (customContext != null) {
Authentication authentication = customContext.securityContext().getAuthentication();
....
}
}
Alternatively, you can also get the JWT token from the headers and check it again, but given this has already been done, I didn't want to do it again (using Firebase so would be multiple calls to the oauth server).
Credit to ChatGPT for the help on this one - if anyone has a better way to do this (maybe using ReactiveDgsContext I would be interested in seeing it!)
Upvotes: 1