【问题标题】:Grape API and HTTP Digest AuthenticationGrape API 和 HTTP 摘要认证
【发布时间】:2013-03-27 04:47:12
【问题描述】:

我正在为我的 ruby​​ 应用程序创建一个 API,它基于 HTTP Digest 身份验证对用户进行身份验证。我决定使用 Grape API 库,因为它可以在 ruby​​ 中创建 API 清洁器。 Grape 文档指出您可以使用摘要式身份验证,例如:

http_digest({ :realm => 'Test Api', :opaque => 'app secret' }) do |username|
  # lookup the user's password here
  { 'user1' => 'password1' }[username]
end

上面的 Grape 实现是 Rack::Auth::Digest::MD5 的包装器

现在,为了安全起见,我读到,从 RFC 2617 开始,您不需要将密码作为纯文本存储在数据库中,您可以存储用户名的 MD5 摘要:领域:密码并针对它进行身份验证,因此我创建了一个 DataMapper型号:

class Key
  include DataMapper::Resource

  property :id,              Serial

  property :username,        String
  property :password,        String

  property :active,          Boolean, :default => true
  property :created_at,      DateTime, :default => DateTime.now
  property :updated_at,      DateTime
end

现在有了我提供的内容,我不知道如何连接这两者并使其工作。

【问题讨论】:

    标签: ruby rubygems rack datamapper grape-api


    【解决方案1】:

    不幸的是,Rack::Auth::Digest::MD5 在服务器端需要一个明文密码。

    Grape 示例代码显示了对密码的硬编码查找。

    你可以用

    替换 { 'user1' => 'password1' }[username]
    Key.first( :username => username ).password
    

    假设您将 明文 密码存储在 Key 类中。我想你可以存储这些可逆加密的,尽管这不会增加太多安全性,除非你为密钥管理构建相对复杂/昂贵的方案。

    不确定是否有办法让您存储散列密码。 MD5 不是最安全的散列选择(尽管总比没有好!)。如果安全性是您的 API 的一个重要问题,您将希望超越摘要式身份验证 - 例如,使用 https 会有所帮助。

    编辑:经过一些反复讨论,Grape 示例的以下变体确实允许您存储 MD5 密码:

    auth :http_digest, { :realm => { :realm => 'Llama', :passwords_hashed => true, :opaque => "7302c32d39bbacb5ed0ace096723fd" } } do |username|
      Digest::MD5.hexdigest( 'fred:Llama:654321' )
    end
    

    该示例给出了一个硬编码的用户名:'fred',密码:'654321' 响应。所以我认为你的目标代码是这样的:

    auth :http_digest, { :realm => { :realm => 'Llama', :passwords_hashed => true, :opaque => "7302c32d39bbacb5ed0ace096723fd" } } do |username|
      k = Key.first( :username => username )
      k ? k.password : nil
    end
    

    然后您将Digest::MD5.hexdigest( "#{username}:#{realm}:#{password}" ) 的结果存储在每个用户的密码属性中。

    注意使用:realm 两次的双层哈希。这有点hacky,但至少您不必编写自己的中间件,Grape 仍在处理它。这不是 Grape 的记录功能或包含测试,因此在未来的版本中可能无法使用。

    【讨论】:

    • 在环顾Rack Digest MD5 之后,我发现如果attr_writer :passwords_hashed 设置为true,那么它将接受username:realm:password 格式的已散列密码,这很好,但我无法设置Grape API 包装器中的该属性。有什么建议吗?
    • 查看 Grape 代码,您可能会为 :realm 符号提供一个哈希,其中包含 :realm, :opaque, :passwords_hashed 键。 . .不过,没有在 Grape 中记录或测试,所以有点你想要的后门。我测试了它,但它对我不起作用。
    • 我也想看看会发生什么,对于不透明的值,它是什么重要的,我可以将它设置为SecureRandom.hex(15)吗?
    • 不完全确定:opaque 做了什么,示例只是显示客户端将其反射回服务器。但是,我刚刚在我的电脑上尝试了一个迷你葡萄应用程序,你的建议对我来说很好。
    • 好的,谢谢,我正在查看葡萄 api 和 rack 源,但我不知道在哪里添加修改。
    猜你喜欢
    • 2011-05-03
    • 2020-09-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-12
    • 2019-07-30
    • 2012-05-26
    • 1970-01-01
    相关资源
    最近更新 更多