跳到主要内容
版本:7.0.3

令牌认证

Hunyuan 7b 中英对照 Token Authentication

Spring Security OAuth 支持基于令牌的安全机制,包括 JSON Web Token (JWT)。您可以在 Web 应用程序中使用这种机制进行身份验证,包括在 WebSocket 交互中的 STOMP 协议(即,通过基于 Cookie 的会话来维护用户身份)。

同时,基于cookie的会话并不总是最佳选择(例如,在不维护服务器端会话的应用程序中,或者在通常使用头部信息进行身份验证的移动应用程序中)。

WebSocket协议,RFC 6455“并未规定服务器在WebSocket握手过程中验证客户端的任何特定方式。”然而,在实践中,浏览器客户端只能使用标准的身份验证头(即基本的HTTP身份验证)或cookie,无法(例如)提供自定义头。同样,SockJS JavaScript客户端也不提供通过SockJS传输请求发送HTTP头的方法。请参见sockjs-client问题196。不过,它确实允许发送查询参数来传递令牌,但这也有其自身的缺点(例如,令牌可能会无意中与URL一起被记录在服务器日志中)。

备注

上述限制适用于基于浏览器的客户端,不适用于基于Spring Java的STOMP客户端,后者支持在WebSocket和SockJS请求中同时发送头部信息。

因此,那些希望避免使用cookies的应用程序在HTTP协议层面可能没有其他好的身份验证替代方案。它们可能更倾向于在STOMP消息协议层面通过请求头来进行身份验证。这样做只需要两个简单的步骤:

  1. 在连接时使用STOMP客户端传递身份验证头。
  2. 使用ChannelInterceptor处理这些身份验证头。

下一个示例使用服务器端配置来注册一个自定义的身份验证拦截器。请注意,拦截器只需要在 CONNECT Message 上进行身份验证并设置用户头部信息即可。Spring 会记录并保存经过身份验证的用户,并将其与同一会话中的后续 STOMP 消息关联起来。以下示例展示了如何注册一个自定义的身份验证拦截器:

@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfiguration implements WebSocketMessageBrokerConfigurer {

@Override
public void configureClientInboundChannel(ChannelRegistration registration) {
registration.interceptors(new ChannelInterceptor() {
@Override
public Message<?> preSend(Message<?> message, MessageChannel channel) {
StompHeaderAccessor accessor = MessageHeaderAccessor.getAccessor(message, StompHeaderAccessor.class);
if (StompCommand.CONNECT.equals(accessor.getCommand())) {
// Access authentication header(s) and invoke accessor.setUser(user)
}
return message;
}
});
}
}

另外,请注意,当您对消息使用Spring Security的授权功能时,目前需要确保认证ChannelInterceptor的配置顺序在Spring Security的配置之前。最佳做法是在自定义拦截器中声明它自己实现WebSocketMessageBrokerConfigurer,并使用@Order(Ordered.HIGHEST_PRECEDENCE + 99)进行标记。