Question

The upgrade request for opening a websocket connection is a standard HTTP request. On the server side, I can authenticate the request like any other. In my case, I would like to use Bearer authentication. Unfortunately, there is no way to specify headers when opening a websocket connection in the browser, which would lead me to believe that it's impossible to use bearer authentication to authenticate a web socket upgrade request. So -- Am I missing something, or is it really impossible? If it is impossible, is this by design, or is this a blatant oversight in the browser implementation of the websocket API?

Was it helpful?

Solution 2

You are right, it is impossible for now to use Authentication header, because of the design of Javascript WebSocket API. More information can be found in this thread: HTTP headers in Websockets client API

However, Bearer authentication type allows a request parameter named "access_token": http://self-issued.info/docs/draft-ietf-oauth-v2-bearer.html#query-param This method is compatible with websocket connection.

OTHER TIPS

The API allows you to set exactly one header, namely Sec-WebSocket-Protocol, i.e. the application specific subprotocol. You could use this header for passing the bearer token. For example:

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

The server is expected to accept one of the protocols, so for the example above, you can just validate the token and respond with header Sec-WebSocket-Protocol=access_token.

Example for basic authentication using token servlet http request header before websocket connection:

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

verify your token return true if valid else return false

endpoint configuration:

@Configuration
@EnableWebSocket
public class WebSocketConfiguration implements WebSocketConfigurer{

    @Autowired
    RemoteServiceHandler rsHandler;

public void registerWebSocketHandlers(WebSocketHandlerRegistry registry){
        registry.addHandler(rsHandler, "/remoteservice/{vin}").setAllowedOrigins("*").addInterceptors(new HttpHandshakeInterceptor());
    }   
}

validate the token before established websocket connectin:

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;
}

skip the http security endpoint

@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>

add the request header in js file as you like

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)
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top