简体   繁体   English

如何在Play的2.0 WebSocket中验证用户身份?

[英]How can I authenticate user in Play's 2.0 WebSocket?

ellou' 你好

I have common Play WebSocket method which is working as expected, but I need to authenticate user. 我有可以正常使用的通用Play WebSocket方法,但是我需要对用户进行身份验证。 Unfortunately when trying even simplest way to identify user in the method: 不幸的是,当尝试使用该方法中甚至最简单的方法来标识用户时:

public class Application extends Controller {
    public static WebSocket<JsonNode> connect() {
        return new WebSocket<JsonNode>() {

            @Override
            public void onReady(final WebSocket.In<JsonNode> in, final WebSocket.Out<JsonNode> out) {
                User logged = User.findByUsername(Http.Context.current().request().username());
                // ...
            }
        };
    }
}

I get an error: 我收到一个错误:

java.lang.RuntimeException: There is no HTTP Context available from here.

My current workaround is to pass random, unique identifier to view and saving it in User model, than I can connect to the socket from the view and find user with the given identifier, but this is no perfect as there can be only one WebSocket connection per user and also doesn't prevent the spoof. 我当前的解决方法是传递随机的唯一标识符以查看并将其保存在User模型中,然后我可以从视图连接到套接字并查找具有给定标识符的用户,但这并不完美,因为只能有一个WebSocket连接每个用户,并且也不会阻止欺骗。

How should I authenticate the user and prevent spoof attack? 我应该如何验证用户身份并防止欺骗攻击?

I don't know where comes your piece of code, but you should be able to access the HTTP request on the initialization of the Websocket (first connection), ie you should be able to check for authentication only when you initiate the websocket socket connection (subsequent call will not be using HTTP, it is how Webscokets works). 我不知道您的代码在哪里,但是您应该能够在Websocket初始化(第一个连接)时访问HTTP请求,即,只有在启动Websocket套接字连接时,您才应该能够检查身份验证(后续调用将不会使用HTTP,这是Webscokets的工作方式)。

So for instance, in your controller, you could have something like this: 因此,例如,在您的控制器中,您可能会有类似以下内容:

public class Application extends Controller {

   public static WebSocket<JsonNode> connect() {

        Logger.info("Username from request = " + request().username());

        return new WebSocket<JsonNode>() {

            @Override
            public void onReady(final WebSocket.In<JsonNode> in, final WebSocket.Out<JsonNode> out) {
                // ....

            }

        };
    }

}

Have you tried retrieving the authenticated user ID from the HTTP Session instead? 您是否尝试过从HTTP会话检索经过身份验证的用户ID? The context seems to be available at that point. 此时似乎可以使用上下文。

As data I want to send are sensitive and in this case security is more important to me than performance, finally I used two-step messages, first sending via WebSocket id of the message and some not important data and then fetching via AJAX and secured action message body after user's authentication. 由于我要发送的数据很敏感,在这种情况下,安全性对我而言比性能更重要,所以最后我使用了两步消息,首先通过消息的WebSocket ID和一些不重要的数据发送,然后通过AJAX和安全操作进行获取用户验证后的消息正文。

Question remains opened: Of course if there will be other suggestions I will change my vote :) 问题仍然悬而未决:当然,如果还有其他建议,我将更改表决权:)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM