1

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

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

  2. 然后 websocket 客户端将此令牌作为查询参数发送以连接到服务。

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

4

2 回答 2

0

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

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

于 2015-07-27T07:13:05.983 回答
0

在 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)
于 2020-03-20T10:23:44.453 回答