Reputation: 1078
I'm currently Building a web application that uses Spring to leverage websocket Support and security. The thing is, I don't want to use STOMP. It has not been updated for about 4 yours now and I don't need it. So I followed the answer to another Stackoverflow question to configure Spring for websockets with SockJS but without STOMP.
Now I want to integrate Spring Security for websocket authentication and authorisateion. Unfortunately the documentation is bound to configure Spring Security for STOMP-websockets.
I would highly appreciate any help with configuring Spring Security for my case. Does someone maybe know any tutorial or example for that? I did not find any yet.
Upvotes: 7
Views: 4904
Reputation: 109
I will only add the answer above, having specified as I managed to solve it.
My problem was that request.getPrinciple()
returned null
. Having played from viewings of headings, I found cookie
value. And having substituted the same cookie id
value to websocket request, the server finds principle
for this request.
For example, when we authorized, I make request to /auth/principal
, to get data about player from database.
@GetMapping(value="/auth/principal")
public ResponseEntity principal(HttpServletRequest request,
Principal principal) {
Player player = playerService.findByEmail(principal.getName());
String jsonString = new JSONObject()
.put("id", player.getId())
.put("nickname", player.getNickname())
.put("cookie", request.getHeader("cookie")).toString();
return new ResponseEntity(jsonString, HttpStatus.OK);
}
Then, on client side, when I want to connect to websocket, I specify headers of request, defining cookie (cookie: COOKIE-ID)
Upvotes: 1
Reputation: 506
Websocket messaging session starts with a Http request , therefore spring security can be used as it's a framework for securing http requests. In spring security authenticated user and its associated security context are stored in session. Authenticated is accessible from Websocket handshake because it transports http request. Spring Websocket defines HttpSessionHandshakeInterceptor which can be registred in your configuration using addInterceptors method
@EnableWebSocket
@Configuration
public class WebSocketConfig implements WebSocketConfigurer {
@Override
public void registerWebSocketHandlers(WebSocketHandlerRegistry
webSocketHandlerRegistry) {
webSocketHandlerRegistry.addHandler(createHandler(),
"/handler").addInterceptors(new HttpSessionHandshakeInterceptor()
{
@Override
public void afterHandshake(ServerHttpRequest request,
ServerHttpResponse response, WebSocketHandler wsHandler,
@Nullable Exception ex) {
super.afterHandshake(request, response, wsHandler, ex);
}
@Override
public boolean beforeHandshake(ServerHttpRequest request,
ServerHttpResponse response, WebSocketHandler wsHandler,
Map<String, Object> attributes) throws Exception {
boolean b = super.beforeHandshake(request, response,
wsHandler, attributes) &&
((UsernamePasswordAuthenticationToken)
request.getPrincipal()).isAuthenticated();
return b;
}
}).withSockJS();
}
@Bean
public WebSocketHandler createHandler() {
return new MyHandler();
}
}
you can also verify authenticated use at Handler which is stored in websocket session
Upvotes: 3