NaikSoftware / StompProtocolAndroid

STOMP protocol via WebSocket for Android
MIT License
597 stars 265 forks source link

A small issue in the example-client #170

Open CallMeZhou opened 4 years ago

CallMeZhou commented 4 years ago

I'm sort of a beginner in Java/Web service programming, so not sure if this is a real issue or not. Correct me if I'm wrong.

In the example-client program, the StompClient instance is initialized as below:

mStompClient = Stomp.over(Stomp.ConnectionProvider.OKHTTP, "ws://" + ANDROID_EMULATOR_LOCALHOST + ":" + RestClient.SERVER_PORT + "/example-endpoint/websocket");

Later on, when it connects to the server, it carries a user name and a password in the request header to perform a basic-auth-like authorization:

List<StompHeader> headers = new ArrayList<>();
headers.add(new StompHeader(LOGIN, "guest"));
headers.add(new StompHeader(PASSCODE, "guest"));
...
mStompClient.connect(headers);

The thing is that, if a server (or backend) requires authorization in communication, it usually requires any request to be authorized except for the login request --- it means the protocol upgrading request must also be authorized.

However, it seems that the StompClient class does not propagate the authorization header to the connection provider. In my test, my Spring boot web server received no authorization header in the protocol upgrading request:

...
2020-06-09 00:08:04.197  INFO 16924 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet        : Completed initialization in 9 ms
OncePerRequestFilter: request.getServletPath=/authentication
OncePerRequestFilter: request.getServletPath=/broadcast/websocket
>>>>>>>>>>>>>>>>>>>>
connection:Upgrade
host:192.168.0.101:8080
sec-websocket-key:+hOUmkV5KHtRttJ0vbF1gQ==
sec-websocket-version:13
upgrade:websocket
<<<<<<<<<<<<<<<<<<<<

I reviewed StompClient's source code and realized that I have to provide the authorization header to the Stomp.over() like the following shows:

Map<String, String> connHeaders = new HashMap<>();
connHeaders.put("Authorization", "Bearer " + token);
stompClient = Stomp.over(Stomp.ConnectionProvider.JWS, url, connHeaders);
...

I had a quick look at the ConnectionProvider interface, but I didn't see a chance to set the authorization header once the instance is created, so it seems the new XXXXConnectionProvider() in the Stomp.over() is the only chance to provide the header.

I think it would be better if the example-client could do it when calling the over() method. It would be a good reminder for the users.