是否可以对网络套接字升级请求使用承载身份验证?

问题描述 投票:24回答:3

用于打开websocket连接的升级请求是标准的HTTP请求。在服务器端,我可以像其他请求一样对请求进行身份验证。就我而言,我想使用承载身份验证。不幸的是,在浏览器中打开websocket连接时无法指定标头,这使我认为无法使用承载身份验证来验证Web套接字升级请求。所以-我错过了什么吗,还是真的不可能?如果不可能,这是设计使然,还是对websocket API的浏览器实现的公然监督?

authentication websocket authorization
3个回答
13
投票

是的,由于Javascript WebSocket API的设计,现在无法使用Authentication标头。在此线程中可以找到更多信息:HTTP headers in Websockets client API

但是,承载认证类型允许名为“ access_token”的请求参数:http://self-issued.info/docs/draft-ietf-oauth-v2-bearer.html#query-param此方法与websocket连接兼容。


33
投票

API允许您设置一个标头,即Sec-WebSocket-Protocol,即特定于应用程序的子协议。您可以使用此标头传递承载令牌。例如:

new WebSocket("ws://www.example.com/socketserver", ["access_token", "3gn11Ft0Me8lkqqW2/5uFQ="]);

服务器应该接受其中一种协议,因此对于上面的示例,您只需验证令牌并使用标头Sec-WebSocket-Protocol = access_token进行响应。


0
投票

Websocket连接之前使用令牌Servlet HTTP请求标头的基本身份验证示例:

**** ws:// localhost:8081 / remoteservice / id?access_token = tokenValue ****

验证令牌是否有效,否则返回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)
© www.soinside.com 2019 - 2024. All rights reserved.