【问题标题】:Using plain text passwords with authenticate_or_request_with_http_digest通过 authenticate_or_request_with_http_digest 使用纯文本密码
【发布时间】:2011-11-19 06:47:45
【问题描述】:

我在尝试快速启动和运行 HTTP Digest 身份验证时遇到了一些困难,这与指南中的建议非常相似:

Ruby on Rails Guides: Action Controller Overview > HTTP Digest Authentication

class ApplicationController < ActionController::Base
  protect_from_forgery

  USERS = { "sam" => "ruby" }

  before_filter :authenticate

private
  def authenticate
    authenticate_or_request_with_http_digest do |username|
      USERS[username]
    end
  end
end

系统提示我输入用户名和密码,尽管在输入上述内容时,身份验证似乎失败并且我再次收到提示。所以我开始在这里深入研究验证请求的代码:

GitHub: http_authentication.rb > validate_digest_response

  def validate_digest_response(request, realm, &password_procedure)
    secret_key  = secret_token(request)
    credentials = decode_credentials_header(request)
    valid_nonce = validate_nonce(secret_key, request, credentials[:nonce])

    if valid_nonce && realm == credentials[:realm] && opaque(secret_key) == credentials[:opaque]
      password = password_procedure.call(credentials[:username])
      return false unless password

      method = request.env['rack.methodoverride.original_method'] || request.env['REQUEST_METHOD']
      uri    = credentials[:uri][0,1] == '/' ? request.fullpath : request.url

     [true, false].any? do |password_is_ha1|
       expected = expected_response(method, uri, credentials, password, password_is_ha1)
       expected == credentials[:response]
     end
    end
  end

我看不出它是如何将密码作为纯文本处理的。 password_is_ha1 是如何设置的?我也有点困惑 any? 块是如何工作的,这可能没有帮助:-/

同样快速说明:我知道我真的不应该将密码存储在纯文本和这样的源代码中。我只是想建立一种理解,稍后会对其进行重构。

非常感谢您提前提供的所有帮助:-D

【问题讨论】:

    标签: ruby-on-rails ruby authentication ruby-on-rails-3.1 http-digest


    【解决方案1】:

    any? 方法的作用类似于collect,除了它在其块第一次返回true 时返回true。在这里,它就像数组[true, false]上的循环:

    1. 第一次运行块时将password_is_ha1 设置为true。如果块返回trueany?立即返回true,由于这是validate_digest_response的最后一条语句,所以整个方法返回true

    2. 否则,将在 password_is_ha1 设置为 false 的情况下再次运行块。如果块返回trueany?立即返回true,由于这是validate_digest_response的最后一条语句,所以整个方法返回true

    3. 如果这些运行均未返回 true,则 any? 返回 false。由于这是validate_digest_response的最后一条语句,所以整个方法返回false

    因此,该行的效果是首先假设它是一个散列密码并检查它是否有效,然后假设它是一个明文密码并检查它是否有效。另一种更冗长的写法是:

       expected = expected_response(method, uri, credentials, password, true)
       return true if expected == credentials[:response]
    
       expected = expected_response(method, uri, credentials, password, false)
       return true if expected == credentials[:response]
    
       return false
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2023-03-03
      • 1970-01-01
      • 2010-10-31
      • 1970-01-01
      • 2014-08-10
      • 1970-01-01
      • 2013-06-21
      相关资源
      最近更新 更多