REST和身份验证变体
我目前正在为.net开发一个REST库,并且我想听听关于我有一个开放点的一些意见:REST和身份验证。
以下是与库一起使用的RESTful接口的示例:
[RestRoot("/user")]
public interface IUserInterface
{
[RestPut("/")]
void Add(User user);
[RestGet("/")]
int[] List();
[RestGet("/get/{id}")]
User Get(int id);
[RestDelete("/delete/{id}")]
void Delete(int id);
}
服务器代码然后只是实现接口,客户端可以通过工厂获得相同的接口。 或者,如果客户端不使用该库,则标准HTTP请求也可以使用。
我知道使用HTTP Basic Auth或向需要认证用户的请求发送令牌的主要方式。
第一种方法(HTTP Basic Auth)具有以下问题(部分是Web浏览器特定的):
第二种方法的问题更侧重于实现和库的使用:
[RestGet("/get/{id}")]
与[RestGet("/get/{id}/{token}")]
。 我的想法是将标记作为参数传递给URL,如http:/server/user/get/1234?token=token_id
。
另一种可能性是将参数作为HTTP标头发送,但这会使我用普通HTTP客户端的使用复杂化。
该令牌将作为每个请求上的自定义HTTP标头(“X-Session-Id”)传递回客户端。
然后这可以从界面完全抽象出来,并且任何需要认证的实现都可以询问令牌(如果给定)属于哪个用户。
你认为这会违反REST吗?或者你有更好的想法?
我倾向于认为认证细节属于标题,而不是URI。 如果您依赖于放置在URI上的令牌,则应用程序中的每个URI都需要进行编码以包含该令牌。 这也会对缓存产生负面影响。 具有不断变化的标记的资源将不再能够被缓存。 与资源相关的信息属于URI,而不是与应用相关的数据,例如凭证。
看起来您必须将Web浏览器定位为客户端? 如果是这样,您可以使用HTTP摘要访问身份验证或向客户端颁发自己的SSL证书来唯一标识和验证身份验证。 另外,我不认为会话cookie肯定是坏事。 特别是在处理浏览器时。 只要你隔离了cookie处理代码,并让其他应用程序不依赖它,你就没事了。 关键只是在会话中存储用户的身份,没有别的。 不要滥用服务器端会话状态。
如果您的目标客户不是浏览器,那么您可以采取多种方法。 我已经使用亚马逊的S3认证机制。
这当然是非常主观的。 纯度和跟随REST到信有时可能是不切实际的。 只要您尽量减少并隔离这些行为,应用程序的核心仍然可以是RESTful。 我强烈建议将RESTful Web服务作为REST信息和方法的重要来源。
我同意workmad3,如果会话生存时间需要维护,您应该创建一个会话资源。 使用用户凭证(基本身份验证或身份内容中的凭证)在该资源上发布将返回唯一的会话ID。 删除/会话/ {id}会注销用户。
如果你想控制会话到期时间。 当创建新会话时(在会话资源上发布),服务器将在响应上设置一个cookie(使用标准的set-cookie头)。 该cookie将包含到期时间。 cookie字符串应该在服务器上加密,所以只有服务器才能打开该cookie。 每一个对服务器的后续请求都会发送cookie头中的会话cookie。 (如果你的客户端是浏览器,它会自动完成)。 服务器需要为每个请求“更新”cookie,即使用新的到期时间(扩展会话超时)创建新的cookie。 请记得在用户呼叫会话资源上的删除时清除cookie。
如果您希望您的应用程序更安全,则可以将客户端IP存储在Cookie本身中,因此,当请求到达时,服务器可以验证它是从“原始”客户端发送的。 但请记住,当涉及代理时,此解决方案可能会有问题,因为服务器可能会“看到”来自同一客户端的所有请求。
我见过的其他身份验证将会话视为创建,销毁等的REST资源,然后会话标识被传递来回传递。 我见过的人倾向于使用会话cookie,因为这是确保安全的唯一方法。 如果您在URL中传递会话标识,则您无法通过正确的客户端进行真正的身份验证。
认证对于REST来说是一个棘手的问题,因为它需要某种形式的状态保存在URL之外,这违反了URL的REST原则,这些原则都是表示状态所需的。
链接地址: http://www.djcxy.com/p/22035.html