如何在 Spring Websocket 支持但没有 STOMP 的情况下使用 Spring 安全性?
How to use Spring Security with Spring Websocket support but without STOMP?
我目前正在构建一个 Web 应用程序,该应用程序使用 Spring 来利用 websocket 支持和安全性。问题是,我不想使用 STOMP。它现在大约有 4 个没有更新,我不需要它。所以我按照另一个 Whosebug question 的答案为带有 SockJS 但没有 STOMP 的 websockets 配置 Spring。
现在我想集成 Spring websocket 身份验证和授权的安全性。不幸的是,documentation 必须为 STOMP-websockets 配置 Spring 安全性。
如果您能帮助我配置 Spring 安全性,我将不胜感激。有人可能知道任何教程或示例吗?我还没有找到。
Websocket 消息传递会话以 Http 请求开始,因此 spring 安全性可以用作保护 http 请求的框架。在 spring 中,经过安全身份验证的用户及其关联的安全上下文存储在会话中。 Authenticated 可以从 Websocket 握手访问,因为它传输 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();
}
}
您还可以在存储在 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 时,我指定请求的 headers,定义 cookie (cookie: COOKIE-ID)
我目前正在构建一个 Web 应用程序,该应用程序使用 Spring 来利用 websocket 支持和安全性。问题是,我不想使用 STOMP。它现在大约有 4 个没有更新,我不需要它。所以我按照另一个 Whosebug question 的答案为带有 SockJS 但没有 STOMP 的 websockets 配置 Spring。
现在我想集成 Spring websocket 身份验证和授权的安全性。不幸的是,documentation 必须为 STOMP-websockets 配置 Spring 安全性。
如果您能帮助我配置 Spring 安全性,我将不胜感激。有人可能知道任何教程或示例吗?我还没有找到。
Websocket 消息传递会话以 Http 请求开始,因此 spring 安全性可以用作保护 http 请求的框架。在 spring 中,经过安全身份验证的用户及其关联的安全上下文存储在会话中。 Authenticated 可以从 Websocket 握手访问,因为它传输 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();
}
}
您还可以在存储在 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 时,我指定请求的 headers,定义 cookie (cookie: COOKIE-ID)