代码之家  ›  专栏  ›  技术社区  ›  Fionn

REST和身份验证变体

  •  68
  • Fionn  · 技术社区  · 17 年前

    我目前正在为.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基本身份验证或向需要身份验证的用户的请求发送令牌的主要方法有两种。

    第一种方法(HTTP Basic Auth)存在以下问题(部分特定于web浏览器):

    • 由于密码是通过请求头传输的,因此本地攻击者很容易通过查看传输的头来获取密码。
    • 密码在浏览器内存中可用。
    • 没有标准方法使用户“会话”过期。
    • 使用浏览器登录会中断页面的外观。

    第二种方法的问题更侧重于实现和库的使用:

    • 如果每个方法实现都需要检查令牌是否有效,则需要编写更多的代码。
    • [RestGet("/get/{id}")] vs。 [RestGet("/get/{id}/{token}")] .
    • 在哪里放置令牌:在URI的末尾?根之后?其他地方?

    http:/server/user/get/1234?token=token_id .

    另一种可能是将参数作为HTTP头发送,但我想这会使普通HTTP客户端的使用变得复杂。

    令牌将在每个请求上作为自定义HTTP头(“X-Session-Id”)传递回客户端。

    这样就可以完全从接口中抽象出来,任何需要身份验证的实现都可以询问令牌(如果给定)属于哪个用户。

    你认为这会对REST有太多的侵犯吗?或者你有更好的想法吗?

    3 回复  |  直到 16 年前
        1
  •  64
  •   Community Mohan Dere    14 年前

    我倾向于认为身份验证细节属于报头,而不是URI。如果您依赖于放置在URI上的令牌,那么应用程序中的每个URI都需要编码以包含该令牌。这也会对缓存产生负面影响。具有不断变化的令牌的资源将不再能够被缓存。与资源相关的信息属于URI,而不是与应用程序相关的数据,如凭据。

    HTTP Digest access authentication 或者向客户端颁发自己的SSL证书以唯一地标识和验证它们。另外,我不认为会话cookie一定是一件坏事。尤其是当需要处理浏览器时。只要您隔离cookie处理代码并使应用程序的其余部分不依赖它,您就可以了。关键是只在会话中存储用户的身份,而不是其他。不要滥用服务器端会话状态。

    如果您的目标客户不是浏览器,那么您可以采取多种方法。我很幸运使用了亚马逊的 S3 Authentication

    RESTful Web Services 作为REST信息和方法的重要来源。

        2
  •  15
  •   LiorH    17 年前

    我同意workmad3,如果需要维护会话生存时间,您应该创建会话资源。使用用户凭据(基本身份验证或正文内容中的凭据)在该资源上发布将返回唯一的会话id。在/session/{id}上删除将注销该用户。

    cookie将包含过期时间。cookie字符串应该在服务器上加密,因此只有服务器才能打开该cookie。 对服务器的每个后续请求都将在cookie头中发送会话cookie。(如果您的客户端是浏览器,则会自动为您执行此操作)。服务器需要为每个请求“续订”cookie,即创建具有新到期时间的新cookie(延长会话超时)。 记得在用户调用会话资源上的delete时清除cookie。

    如果您希望您的应用程序更安全,您可以将客户端IP存储在cookie中,这样当请求到达时,服务器可以验证它是否是从“原始”客户端发送的。但请记住,当涉及代理时,此解决方案可能会出现问题,因为服务器可能会“看到”来自同一客户机的所有请求。

        3
  •  4
  •   workmad3    17 年前

    我看到的rest身份验证将会话视为用于创建、销毁等的rest资源,然后来回传递会话ID。我见过的人倾向于使用会话cookie来实现这一点,因为这是确保它真正安全的唯一方法。如果在URL中传递会话id,则无法真正验证它是否来自正确的客户端。

    不过,REST的身份验证是一个棘手的问题,因为它需要在URL之外保留某种形式的状态,这违反了URL表示状态所需的REST原则。