目前我们有Spring应用程序,包括Spring Boot,Spring Session(Redis)和Spring Security。我们使用基本身份验证。现在我想添加websocket支持。
当客户端成功登录到应用程序的其他部分时,他会获得x-auth-token。它稍后作为标题传递,并且有效。
然后,websocket客户端将此令牌作为查询参数发送,以连接到服务。
我们希望通过websocket连接中的查询参数使Spring Security和Spring Session接受令牌。我可以设置任何参数吗?或者我们是否需要编写自定义身份验证提供程如果是这样,我们如何与Spring Session集成?
答案 0 :(得分:0)
您可以使用queryString参数,但我遇到了同样的问题,我的建议是在订阅时或从JS客户端发送消息时使用标头传递令牌。
由于您有自定义过滤器来处理X-Auth-Token,因此Spring安全性不支持在Security.xml中定义的websocket拦截器上定义自定义过滤器。 您所需要的只是为入站通道实现拦截器,并通过对Presend方法的消息发送的nativeHeader,通过注册的令牌认证服务实例来处理令牌认证。
答案 1 :(得分:0)
在网络套接字连接之前使用令牌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)