我正在使用CometD,我有一个服务设置(服务器端的Java),如下所示:
http://localhost:8086/service/myService/get-player-details?params={id:1234}
这在实践中运作良好,但我担心的是任何用户都可以使用上述URL查询我的服务并检索其他玩家详细信息。
建议的防范此类问题的方法是什么?授权人会是正确的方法吗?
答案 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
放入频道,原因有两个:
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实现的核心。
在适当的SecurityPolicy
和Authorizers
到位的情况下,您的申请可以避免您的问题。
严格来说,Authorizers
可能已足够,但通常如果您希望强制执行授权策略,则还需要由SecurityPolicy
提供的身份验证。