web-dev-qa-db-ja.com

websocketアップグレード要求にベアラー認証を使用することは可能ですか?

WebSocket接続を開くためのアップグレード要求は、標準のHTTP要求です。サーバー側では、他のようにリクエストを認証できます。私の場合、ベアラー認証を使用したいと思います。残念ながら、ブラウザーでWebSocket接続を開くときにヘッダーを指定する方法はありません。そのため、ベアラー認証を使用してWebソケットのアップグレードリクエストを認証することは不可能だと思います。それで、私は何かを逃していますか、それとも本当に不可能ですか?それが不可能な場合、これは設計によるものですか、それともWebSocket APIのブラウザー実装における露骨な見落としですか?

22
w.brian

そうです、JavaScript WebSocket APIの設計により、今のところAuthenticationヘッダーを使用することは不可能です。詳細については、このスレッドをご覧ください。 WebsocketsクライアントAPIのHTTPヘッダー

ただし、ベアラー認証タイプでは、「access_token」という名前のリクエストパラメーターが許可されます。 http://self-issued.info/docs/draft-ietf-oauth-v2-bearer.html#query-param このメソッドWebSocket接続と互換性があります。

12
Romain F.

APIを使用すると、ヘッダー、つまりSec-WebSocket-Protocolを1つだけ設定できます。つまり、アプリケーション固有のサブプロトコルです。このヘッダーを使用して、無記名トークンを渡すことができます。例えば:

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

サーバーはいずれかのプロトコルを受け入れることが想定されているため、上記の例では、トークンを検証してヘッダーSec-WebSocket-Protocol = access_token

30
Kalle

websocket接続前のトークンサーブレット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)
0
Murali S