【问题标题】:Spring Session Basic Auth token passed as query parameter in Spring-WebsocketSpring Session Basic Auth token 在 Spring-Websocket 中作为查询参数传递
【发布时间】:2015-05-28 06:43:59
【问题描述】:

目前我们有带有 Spring Boot、Spring Session (Redis) 和 Spring Security 的 Rest 应用程序。我们使用基本身份验证。现在我想添加 websocket 支持。

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

  2. 然后websocket客户端发送这个token作为查询参数连接到服务。

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

【问题讨论】:

    标签: spring-security spring-websocket spring-session


    【解决方案1】:

    您可以为此使用 queryString 参数,但我遇到了同样的问题,我的建议是在订阅时或在从您的 JS 客户端发送消息时传递带有标头的令牌。

    由于您有一个自定义过滤器来处理您的 X-Auth-Token,因此 Spring 安全性不支持在 Security.xml 中定义的 websocket 拦截器上定义自定义过滤器。 您只需要为入站通道实现拦截器,并通过访问在 Presend 方法中随消息一起发送的 nativeHeader,通过令牌身份验证服务的注入实例来处理令牌身份验证。

    【讨论】:

      【解决方案2】:

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

      ****ws://localhost:8081/remoteservice/id?access_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>
      

      在js文件中随意添加请求头

      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)
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-10-15
        • 1970-01-01
        • 2017-02-12
        • 2015-09-17
        • 1970-01-01
        • 2016-08-12
        • 1970-01-01
        • 2019-05-18
        相关资源
        最近更新 更多