Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Access User/Roles in GraphQL #264

Open
frisi opened this issue Apr 25, 2022 · 1 comment
Open

Access User/Roles in GraphQL #264

frisi opened this issue Apr 25, 2022 · 1 comment

Comments

@frisi
Copy link

frisi commented Apr 25, 2022

Feature description

I'd like to limit usage of certain GraphQL queries or mutations to certain roles and also access user- and role related information (eg via SecuirtyService bean) within functions exposed via GraphQL.

Currently this seems to be impossible or at least undocumented (i did not find a section/example in the docs)

There is an open (and for > 1 year unanswered) issue for supporting the @Secured annotation. (this blogpost seems to (partly) solve this problem)

There is also another ticket outlining how to access request information.
I used this approach to extract authentication information (duplicating logic of a custom AuthenticationFetcher) from the request and inject it into mutation parameters within a DataFetcherFactoryProvider via mapParameterToValue.

A nicer way would be to have a possibility to inject SecurityService but it seems request scope beans currently do not really work in the context of GraphQL

@adamkobor
Copy link

adamkobor commented Sep 19, 2022

Adding some context to @frisi's issue above: we're trying to make this work with Kotlin coroutines, using Expedia's graphql-kotlin-schema-generator.
After a thorough investigation and also trying a lot of workarounds without any success, I've found an interesting part in the docs of the schema generator library I mentioned above:
https://opensource.expediagroup.com/graphql-kotlin/docs/schema-generator/execution/async-models#structured-concurrency

graphql-java v17 introduced GraphQLContext map as the default mechanism to propagate the contextual information about the request. In order to preserve coroutine context, we need to populate GraphQLContext map with a CoroutineScope that should be used to execute any suspendable functions.

I was able to implement a MethodInterceptor that can be used to wrap the desired GraphQL queries/mutations and mimic the behavior of the built-in @Secured annotation, but I failed to get the actual HttpRequest inside this interceptor. The ServerRequestContext.currentRequest() call always returns an empty Optional here, and the same happens when I try to invoke this static method inside of a query's method. I assume the reason behind this is that the CoroutineContext is not propagated correctly from the built-in GraphQLController (or there is no CoroutineContext at all of course, if we use the built-in controller).
I've also tried to override this built-in controller with an almost identical one written in Kotlin (with suspending functions), and while the substitution was successful, I still wasn't able to pass the context or the request down the hole without re-implementing most of the built-in logic that comes from the micronaut-graphql module.
My gut feeling is that it should happen somewhere around the instantiation of ExecutionInput inside DefaultGraphQLInvocation.invoke():

ExecutionInput.Builder executionInputBuilder = ExecutionInput.newExecutionInput()
                .query(invocationData.getQuery())
                .operationName(invocationData.getOperationName())
                .variables(invocationData.getVariables());

Please take a look and let me know if this is something you would consider putting on your roadmap. Furthermore, if you could give me some context about doing this the correct way, I would be happy to contribute to the project :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants