我目前正在构建一个使用Spring来利用websocket支持和安全性的Web应用程序。问题是,我不想使用STOMP。它现在还没有更新大约4个,我不需要它。所以我按照另一个Stackoverflow question的答案来配置带有SockJS但没有STOMP的websockets的Spring。
现在我想将Spring Security集成到websocket身份验证和授权中。不幸的是,documentation必然会为STOMP-websockets配置Spring Security。
我非常感谢为我的案例配置Spring Security的任何帮助。有人可能知道任何教程或示例吗?我还没找到。
Websocket消息传递会话以Http请求开始,因此可以使用spring安全性,因为它是保护http请求的框架。在Spring中,经过身份验证的用户及其关联的安全上下文存储在会话中。可以从Websocket握手访问Authenticated,因为它传输http请求。 Spring Websocket定义了HttpSessionHandshakeInterceptor,它可以使用addInterceptors方法在您的配置中注册
@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();
}
}
您还可以在Handler上验证存储在websocket会话中的经过身份验证的使用
我只会添加上面的答案,指定我设法解决它。
我的问题是request.getPrinciple()
返回null
。从标题的观看发挥,我发现cookie
价值。并且将相同的cookie id
值替换为websocket请求,服务器为此请求找到principle
。
例如,当我们授权时,我向/auth/principal
发出请求,从数据库中获取有关玩家的数据。
@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);
}
然后,在客户端,当我想连接到websocket时,我指定请求的标头,定义cookie(cookie:COOKIE-ID)