Skip to content

Chapter 34: Configure subscription Pre-Auth spring security #7

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

Merged
merged 5 commits into from
Apr 18, 2021

Conversation

philip-jvm
Copy link
Owner

@philip-jvm philip-jvm commented Apr 17, 2021

  • Set the Spring Security Context in the ApolloSubscriptionConnectionListener#onStart callback. As the GraphQLSubscriptionResolver will execute in the same thread, we can therefore enforce method level security via @PreAuthorize.

  • Upon a failure/stop, the failed response is first pushed to the client's socket, then the ApolloSubscriptionConnectionListener#onStop callback executes in a different thread (vs onConnect). This is why we do not clear the SecurityContextHolder in onStop.

@philip-jvm philip-jvm changed the title Chapter 33: Configure subscription Pre-Auth spring security Chapter 34: Configure subscription Pre-Auth spring security Apr 17, 2021
@philip-jvm
Copy link
Owner Author

philip-jvm commented Apr 17, 2021

EDIT:

If the start frame is not sent directly with the connection_init then the two frames may be serviced on different threads.
The thread servicing connection_init will check the socket for any further inbound frames, if false the thread will move onto another websocket. Another thread is then free to service the start frame. In this case, that thread not have the security context of the correct session/thread.

Same scenario happens for onStop. (Message can be executed on different thread).

This seems to be why some users are reporting intermittent failures with spring security.
E.g. graphql-java-kickstart/graphql-java-servlet#134 (comment)

With the NIO connector, a small number of threads will check sessions for new frames. If the session has a frame available, the session will be passed to another thread pool which will read frame, execute it, check for another frame, execute it. The session will be released when there are no further frames available. With this, we know that at most one thread will concurrently access one socket, therefore frames will be read sequentially. We can therefore extract the auth credentials from onConnect and add them to the session.getUserProperties(). These properties are available in the onStart and onStop callbacks. Inside these callbacks, we can add the token to the SecurityContextHolder if we decide to use method level security, or simply access the credentials inside the subscription resolver via DataFetchingEnvironment

session.getUserProperties().put("AUTH", token);

@philip-jvm philip-jvm merged commit 2fb18ca into master Apr 18, 2021
@philip-jvm philip-jvm deleted the feature/chapter-33-graphql-subscription-security branch April 18, 2021 10:23
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

Successfully merging this pull request may close these issues.

1 participant