1

我有一个连接到 iphone 应用程序的应用程序,该应用程序又通过 http_digest 对其用户进行身份验证。

我正在使用 authlogic,在我的架构中,网站的用户是“用户”,手机应用程序的用户是“人”。所以,我有 user_sessions 和 people_sessions。为了处理 http_digest 身份验证,我使用了如下的 authenticate_or_request_with_http_digest 方法:

def digest_authenticate_person
  authenticate_or_request_with_http_digest do |email, password|
    #ldb is just a logging method i have
    ldb "email = #{email.inspect}, password = #{password.inspect}"
    person = Person.find_by_email(email)
    if person
      ldb "Authentication successful: Got person with id #{person.id}"
      @current_person_session = PersonSession.create(person)        
    else
      ldb "Authentication failed"
      @current_person_session = nil
    end
    return @current_person_session
  end
end

我可以在日志中看到密码为零:只有电子邮件被传递到 authenticate_or_request_with_http_digest 块的内部。

我用这样的 curl 调用来测试它:

curl --digest --user fakename@madeup.xyz:apass "http://localhost:3000/reports.xml"

我希望“fakename@madeup.xyz”和“apass”能够传递到块的内部。一旦我有了密码,我就可以使用电子邮件和密码的组合以正常方式查找(或不查找)用户。有谁知道我也可以访问密码吗?

感谢任何建议 - 最大

编辑 - 在进一步的谷歌搜索中,我认为我使用这种方法是错误的:我应该只返回密码或加密密码。但是,我如何将它与作为 http_digest 用户名的一部分传递的密码进行比较?

4

1 回答 1

1

找到了答案:我对 authenticate_or_request_with_http_digest 的工作原理有一个根本的误解:在阅读了文档(在 gem 的源代码中)之后,我意识到这种方法的目的不是进行身份验证,它的目的是提供“电子邮件:realm:password" 字符串到浏览器,让浏览器对其进行加密,并根据它自己计算的(或缓存的)版本检查结果。

这是我的设置方式:

def current_person
  if @current_person
    @current_person
  else
    load_current_person
  end
end 

#use in before_filter for methods that require an authenticated person (mobile app user)
def require_person
  unless current_person
    redirect_to root_path
  end   
end

def load_current_person
  #check user agent to see if we're getting the request from the mobile app
  if request.env['HTTP_USER_AGENT'] =~ /MobileAppName/
    result = digest_authenticate_person
    if result == 401
      return 401
    elsif result == true
      #make authlogic session for person
      @current_person_session = PersonSession.new(@person_from_digest_auth)
      @current_person = @person_from_digest_auth
    end
  end
end  

#this method returns either true or 401
def digest_authenticate_person
  authenticate_or_request_with_http_digest(Person::DIGEST_REALM) do |email|
    person = Person.find_by_email(email)
    @result = nil
    if person
      #need to send back ha1_password for digest_auth, but also hang on to the person in case we *do* auth them successfully
      @person_from_digest_auth = person
      @result = person.ha1_password  
    else
      @person_from_digest_auth = nil
      @result = false
    end
    @result
  end
end
于 2011-06-17T09:16:30.510 回答