Mattlangsenkamp
12/12/2020, 7:05 AMShane Myrick
12/15/2020, 4:22 PMMattlangsenkamp
12/15/2020, 6:53 PMShane Myrick
12/15/2020, 8:30 PMGraphQLContext
There are multiple ways you can get the context data but it needs to be set by using the GraphQLContextFactory
https://expediagroup.github.io/graphql-kotlin/docs/spring-server/spring-graphql-contextRobert
01/30/2021, 1:52 PM@Component
internal class JwtAuthenticationConverter :
Converter<Jwt, Mono<AbstractAuthenticationToken>> {
override fun convert(jwt: Jwt): Mono<AbstractAuthenticationToken> {
val authorities = extractAuthorities(jwt)
val authentication = UsernamePasswordAuthenticationToken(userName, null, authorities)
authentication.details = AuthenticationDetails(username = userName, name = name, eMail = email)
return Mono.just(authentication)
}
/**
* Provide GraphQLSecurityContext
*/
@Component
class GraphQLSecurityContextFactory : GraphQLContextFactory<GraphQLSecurityContext> {
override suspend fun generateContext(
request: ServerHttpRequest,
response: ServerHttpResponse
): GraphQLSecurityContext {
val reactorContext =
coroutineContext[ReactorContext]?.context ?: throw RuntimeException("Reactor Context unavailable")
val securityContext = reactorContext.getOrDefault<Mono<SecurityContext>>(
SecurityContext::class.java,
Mono.empty()
)!!
return GraphQLSecurityContext(securityContext = securityContext.awaitFirstOrNull())
}
}
for my use-case, I created a custom directive, which acts on the JWT claims
class AuthorizationDataFetcher(
/**
* Original Data fetcher which should be executed
*/
private val originalDataFetcher: DataFetcher<*>,
/**
* Required Permission for this Data Fetcher Field
*/
private val requiredPermission: GraphQLPermission
) : DataFetcher<Any> {
override fun get(environment: DataFetchingEnvironment): Any {
val context: GraphQLSecurityContext? = environment.getContext<GraphQLSecurityContext>()
val securityContext: SecurityContext =
context?.securityContext ?: throw AccessDeniedException("SecurityContext not present")
checkRoles(securityContext)
return originalDataFetcher.get(environment)
}
*
* Wraps the original Data Fetcher
* Check the Security Context for the required permission
*/
class AuthorizationDataFetcher(
/**
* Original Data fetcher which should be executed
*/
private val originalDataFetcher: DataFetcher<*>,
/**
* Required Permission for this Data Fetcher Field
*/
private val requiredPermission: GraphQLPermission
) : DataFetcher<Any> {
override fun get(environment: DataFetchingEnvironment): Any {
val context: GraphQLSecurityContext? = environment.getContext<GraphQLSecurityContext>()
val securityContext: SecurityContext =
context?.securityContext ?: throw AccessDeniedException("SecurityContext not present")
checkRoles(securityContext)
return originalDataFetcher.get(environment)
}