CometD安全请求

时间:2014-10-23 09:05:19

标签: java comet cometd

我正在使用CometD,我有一个服务设置(服务器端的Java),如下所示:

http://localhost:8086/service/myService/get-player-details?params={id:1234}

这在实践中运作良好,但我担心的是任何用户都可以使用上述URL查询我的服务并检索其他玩家详细信息。

建议的防范此类问题的方法是什么?授权人会是正确的方法吗?

1 个答案:

答案 0 :(得分:0)

如果您发布的网址已映射到CometD,那么我强烈建议您不要使用这些网址在网址中传递params等信息。

首先,如果您使用非HTTP的其他传输,例如WebSocket,这将无效。

其次,当您注意到URL可能会暴露您不想公开的信息。

我建议您更改从服务器检索信息的方式,使用网址,而只使用网址。

如果您与服务器的所有通信都是通过消息发生的,那么server already validates上的CometD消息来自允许握手的客户端。您只需要使用SecurityPolicy在握手时执行正确的身份验证检查,如authentication section中所述。

使用CometD JavaScript客户端库,消息将具有此表单:

cometd.publish("/service/player", { action:"get", playerId: 1234 });

这种模式可能会有各种变化,你想把"动作"进入渠道本身,例如:

cometd.publish("/service/player/get", { playerId: 1234 });

通过这种方式,您可以获得更少的服务(每个服务都响应不同的频道,因此也可以响应不同的action),这可能是理想的。

阅读服务部分的examples可能会为您提供更多信息。

我不建议将playerId放入频道,原因有两个:

  • 避免创建太多频道
  • 在代码中及时提供此信息,因此您不需要解析该频道(尽管CometD支持use of parameters in channels);解析比仅仅message.get("playerId")更为昂贵。

要将响应发送到客户端,服务器只需调用:

@Service
public class GetPlayer
{
    @Session
    private LocalSession sender;

    @Listener("/service/player/get")
    public void perform(ServerSession session, ServerMessage message)
    {
        Map<String, Object> player = retrievePlayerInfo(message.get("playerId"));
        session.deliver(sender, message.getChannel(), player);
    }
}

请注意使用ServerSession.deliver()将响应返回给该特定客户端。

以上内容保证您(使用正确的SecurityPolicy)只有经过身份验证的客户端才能发送和接收消息。

您现在需要做的是设置正确的授权,特别是玩家123无法通过黑客攻击它发送的CometD消息来扮演玩家789。 这是Authorizers的工作,请参阅Authorizers documentation中的部分和示例。

您必须做的是在用她允许查看的playerIds进行身份验证的用户之间建立关系。这是特定于应用程序的,它是Authorizer实现的核心。

在适当的SecurityPolicyAuthorizers到位的情况下,您的申请可以避免您的问题。

严格来说,Authorizers可能已足够,但通常如果您希望强制执行授权策略,则还需要由SecurityPolicy提供的身份验证。