我们有一个基于用户名和密码处理授权的服务。我们不把用户名和密码作为调用的一部分,而是放在SOAP头中。这个WebService安全方案有哪些潜在的问题?
在典型的情况下,Web服务在执行开始时调用授权服务,以检查是否允许调用者调用它。问题在于这些Web服务中的一些互相调用,这意味着在每个子调用中都会检查用户的权限,而且这可能非常昂贵。
我想要做的是让授权服务在第一次调用后返回一个安全令牌。然后,Web服务不必每次都调用授权服务,而是可以在本地验证安全标头。
安全头看起来像这样(C#代码 - 修剪来说明基本概念):
public sealed class SecurityHeader : SoapHeader
{
public string UserId; // Encrypted
public string Password; // Encrypted; Just realized this field isn't necessary [thanks CJP]
public DateTime TimeStamp; // Used for calculating header Expiry
public string SecurityToken;
}
总的想法是,SecurityHeader获取与每个呼叫检查。如果它存在,尚未过期,且SecurityToken有效,则Web方法正常进行。否则,它将返回一个错误,或者它将尝试重新授权并生成一个新的SecurityHeader SecurityToken基于UserId,Password和TimeStamp的盐味散列。每天更换盐以防止重放。
我所看到的一个问题是,用户可能有权访问Web服务A,但不能访问Web服务B.如果他调用A并收到安全令牌,就像现在这样,这意味着B会让他如果他使用相同的标记。我必须对其进行更改,以便安全令牌仅从Web服务到Web服务而不是Web服务即用户有效。如果用户调用A调用B,应该是可以的,但如果用户调用服务A然后调用服务D,则不是OK。解决此问题的方法是将一个公用密钥(或一组密钥)分配给逻辑上相关的服务。 (即,如果客户可以做A,那么他在逻辑上也可以做B)。
或者,我必须将用户的整个权限集编码为安全性头的一部分。我将不得不调查开销是多少。
编辑:
几个人都提到寻找其他安全方案,例如WS-Security和SAML等我已经有了。事实上,我从WS-Security获得了这个想法。问题是其他方案不提供我需要的功能(缓存授权信息并防止没有中间数据库的重放)。如果有人知道一个方案,那么我会反过来使用它。此外,这是关于认证的而不是。这是由我无法控制的另一种机制处理的。
如果事实证明无法缓存授权数据,那么这意味着我只需承担每个级别的授权开销。
SAML声明如下所示: “客户端X具有角色A和B.此声明在时间T有效,签名,AuthService”。 这不是你所需要的? – ykaganovich 2008-10-05 22:18:31
今天我将重新访问SAML和XACML。 – ilitirit 2008-10-08 12:16:24