Spring security Spring会话基本身份验证令牌作为Spring Websocket中的查询参数传递

Spring security Spring会话基本身份验证令牌作为Spring Websocket中的查询参数传递,spring-security,spring-websocket,spring-session,Spring Security,Spring Websocket,Spring Session,目前我们有带Spring引导、Spring会话(Redis)和Spring安全性的Rest应用程序。我们使用基本身份验证。现在我想添加websocket支持 当客户端成功登录到应用程序的其他部分时,他将获得x-auth-token。它稍后作为标头传递,并且可以工作 然后websocket客户端将此令牌作为查询参数发送到服务 我们希望通过websocket连接中的查询参数使Spring安全性和Spring会话接受令牌。有什么参数可以设置吗?或者我们需要编写自定义身份验证提供程序。如果是这样,我们如

目前我们有带Spring引导、Spring会话(Redis)和Spring安全性的Rest应用程序。我们使用基本身份验证。现在我想添加websocket支持

  • 当客户端成功登录到应用程序的其他部分时,他将获得x-auth-token。它稍后作为标头传递,并且可以工作

  • 然后websocket客户端将此令牌作为查询参数发送到服务


  • 我们希望通过websocket连接中的查询参数使Spring安全性和Spring会话接受令牌。有什么参数可以设置吗?或者我们需要编写自定义身份验证提供程序。如果是这样,我们如何与Spring会话集成?

    您可以使用queryString参数来实现这一点,但我也遇到了同样的问题,我的建议是在订阅时或从JS客户端发送消息时,使用头传递您的令牌

    由于您有一个自定义筛选器来处理X-Auth-Token,Spring security不支持在security.xml中定义的websocket拦截器上定义自定义筛选器。
    您只需为入站通道实现拦截器,并通过访问与messages at Presend方法一起发送的nativeHeader来处理令牌身份验证,通过您的令牌身份验证服务的注入实例。

    在websocket连接之前使用令牌servlet http请求头进行基本身份验证的示例:

    ****ws://localhost:8081/remoteservice/id?access\u token=tokenValue****

    验证您的令牌返回true(如果有效),否则返回false

    端点配置:

    @Configuration
    @EnableWebSocket
    public class WebSocketConfiguration implements WebSocketConfigurer{
    
        @Autowired
        RemoteServiceHandler rsHandler;
    
    public void registerWebSocketHandlers(WebSocketHandlerRegistry registry){
            registry.addHandler(rsHandler, "/remoteservice/{vin}").setAllowedOrigins("*").addInterceptors(new HttpHandshakeInterceptor());
        }   
    }
    
    在建立websocket连接之前验证令牌:

    public class HttpHandshakeInterceptor implements HandshakeInterceptor{
    
    @Override
    public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler,  Map attributes) throws Exception 
    {
    ServletServerHttpRequest servletRequest = (ServletServerHttpRequest) request;
    String token = servletRequest.getServletRequest().getHeader("access_token");
    try {
                Claims claims = Jwts.parser().setSigningKey(secret).parseClaimsJws(token).getBody();
    
                if (claims!=null) {
                    return true;
                }
            } catch (Exception e) {
    
                return false;
            }
            return false;
    }
    
    跳过http安全端点

    @Configuration
    @EnableWebSecurity
    public class SecurityConfiguration extends WebSecurityConfigurerAdapter{
    
        @Override 
        public void configure(WebSecurity web) throws Exception {
            web.ignoring().anyRequest(); 
        }
    
    }
    
    pom.xml

    <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-security</artifactId>
            </dependency>
    
            <dependency>
                <groupId>io.jsonwebtoken</groupId>
                <artifactId>jjwt</artifactId>
                <version>0.9.0</version>
            </dependency>
    
    var request = URLRequest(url: URL(string: "ws://localhost:8081/remoteservice")!)
    request.timeoutInterval = 5 // Sets the timeout for the connection
    request.setValue("someother protocols", forHTTPHeaderField: "Sec-WebSocket-Protocol")
    request.setValue("14", forHTTPHeaderField: "Sec-WebSocket-Version")
    request.setValue("chat,superchat", forHTTPHeaderField: "Sec-WebSocket-Protocol")
    request.setValue("Everything is Awesome!", forHTTPHeaderField: "My-Awesome-Header")
    let socket = WebSocket(request: request)