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

Spring WebSockets should support token-based authentication [SPR-14690] #19254

Closed
spring-issuemaster opened this issue Sep 10, 2016 · 10 comments

Comments

Projects
None yet
2 participants
@spring-issuemaster
Copy link
Collaborator

commented Sep 10, 2016

Raman Gupta opened SPR-14690 and commented

There seems to be an inconsistency in the way Spring Messaging WebSocket is implemented and reality, when using token based authentication.

From the discussion on issue #17761 it is clear that Spring expects the authentication to be done during the HTTP message that establishes the web socket. This is fine for cookie-based auth, but when one is using a token, the token cannot be sent to the server in the headers, because SockJS does not support this (because browsers do not support it). See: sockjs/sockjs-client#196.

Now, one has two options: 1) send the token in a query parameter (which has some security issues), or 2) as suggested in #17761, configure a ChannelInterceptor on the "clientInboundChannel" and pass the token as a Stomp message header. Neither approach seems to be a complete solution.

The first approach, besides having security issues with server-side logging of the token and possible referral leaks, does not seem to work for SockJS fallbacks -- for fallbacks, the determineUser method to extract the user from the query parameter is never called.

The second approach works well up to a point: Spring Security sees the Principal set here and sets the security context properly (awesome!). However, the Principal is never set in the websocket session, and so it is not possible to send messages to a specific user, because Spring cannot tie the username to a session id.


Affects: 4.3.2

Issue Links:

  • #18953 Better documentation on WebSockets and support for token based authentication
  • #17761 Improve web socket header support

1 votes, 5 watchers

@spring-issuemaster

This comment has been minimized.

Copy link
Collaborator Author

commented Sep 12, 2016

Raman Gupta commented

I've found a hackish solution which seems to work: http://stackoverflow.com/a/39456274/430128. Would still be nice to see support for this in Spring proper.

@spring-issuemaster

This comment has been minimized.

Copy link
Collaborator Author

commented Nov 22, 2016

Karthik Astra commented

Hi Raman Gupta,

Do you have a sample code of your hackish solution?. I tried what you have provided in http://stackoverflow.com/a/39456274/430128, but its not working for me.

thanks,
Karthik

@spring-issuemaster

This comment has been minimized.

Copy link
Collaborator Author

commented Nov 22, 2016

Raman Gupta commented

@Karthik Astra, I've provided sample code on stackoverflow. If it isn't working, please comment there and explain what issue you are having. Thanks.

@spring-issuemaster

This comment has been minimized.

Copy link
Collaborator Author

commented Nov 22, 2016

Rossen Stoyanchev commented

We'll have look at making this easier in 5.0 with a possible backport to 4.3.x depending on the actual changes.

@spring-issuemaster

This comment has been minimized.

Copy link
Collaborator Author

commented Nov 23, 2016

Karthik Astra commented

@Raman Gupta, I followed stack overflow example. Here is what i am getting

CONNECT
X-Authorization:eyJhbGciOiJIUzUxMiJ9.eyJqdGkiOiIxZmZiMDMyMC0yNGEzLTQwM2UtYTNmNi0zZGI3YjU3YzliZDUiLCJzdWIiOiJyYWppQGFzdHJhbWludC5jb20iLCJjb21wYW55SWQiOjIsInJvbGVJZCI6NCwiaWF0IjoxNDc5ODgyMDI0LCJleHAiOjE0Nzk4ODU2MjR9.74ryd9Yu_m3huG8QrAUKlGHlOQ9_lOgcXjcTaP_zbpYiujicWv4sAK_XMk9KsWjuOrr-jbYx5A14MAKcCE4EJg
accept-version:1.1,1.0
heart-beat:10000,10000

<<< CONNECTED
version:1.1
heart-beat:0,0

SUBSCRIBE
X-Authorization:eyJhbGciOiJIUzUxMiJ9.eyJqdGkiOiIxZmZiMDMyMC0yNGEzLTQwM2UtYTNmNi0zZGI3YjU3YzliZDUiLCJzdWIiOiJyYWppQGFzdHJhbWludC5jb20iLCJjb21wYW55SWQiOjIsInJvbGVJZCI6NCwiaWF0IjoxNDc5ODgyMDI0LCJleHAiOjE0Nzk4ODU2MjR9.74ryd9Yu_m3huG8QrAUKlGHlOQ9_lOgcXjcTaP_zbpYiujicWv4sAK_XMk9KsWjuOrr-jbYx5A14MAKcCE4EJg
accept-version:1.1,1.0
heart-beat:10000,10000
id:sub-0
destination:/user/queue/notifications

In the backend code, i have

this.simpMessagingTemplate.convertAndSendToUser(super.getCurrentUser().getUserName(),"/queue/notifications", messageResponseInfo);

but i am not receiving the messageResponseInfo in the client side

@spring-issuemaster

This comment has been minimized.

Copy link
Collaborator Author

commented Nov 23, 2016

Karthik Astra commented

@Raman Gupta, it worked for me. My mistake the backend code should be

this.simpMessagingTemplate.convertAndSendToUser(messageResponseInfo.getReceiver().getUserName(),"/queue/notifications", messageResponseInfo);
@spring-issuemaster

This comment has been minimized.

Copy link
Collaborator Author

commented Dec 9, 2016

Rossen Stoyanchev commented

Raman Gupta, the ChannelInterceptor approach can be significantly simpler if you mutate the message headers, just this should work:

accessor = MessageHeaderAccessor.getAccessor(message, StompHeaderAccessor.class);
accessor.setUser(user);

The mutability is explained in the MessageHeaderAccessor Javadoc. When a WebSocket message is decoded into a Spring Message, the headers are left mutable until just before the message goes out on the clientInboutChannel at which point they're flipped to immutable. This allows interceptors to modify the headers as shown above. As a result the published events which the DefaultSimpUserRegistry picks up should also work with the updated user header.

That said I do intend to experiment with providing a more explicit mechanism for doing this.

@spring-issuemaster

This comment has been minimized.

Copy link
Collaborator Author

commented Dec 9, 2016

Raman Gupta commented

@Rossen Stoyanchev, thanks for your comment. I'll update the SO post accordingly, as soon as I have a chance to test the change.

@spring-issuemaster

This comment has been minimized.

Copy link
Collaborator Author

commented Dec 9, 2016

Rossen Stoyanchev commented

I've created a PR to enable support of STOMP level authentication. The PR contains a documentation update so that may be the best place to start.

robwinch, would you take a look? This may also address spring-projects/spring-security#3217.

@spring-issuemaster

This comment has been minimized.

Copy link
Collaborator Author

commented Dec 13, 2016

Rossen Stoyanchev commented

This is now in master and also in the 4.3.x branch.

See the new section Token-Based Authentication for more context and instructions. I've also revamped the Authentication section just above it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.