在authenticate_or_request_with_http_digest中获取密码

发布于 2024-11-15 16:32:17 字数 1470 浏览 8 评论 0原文

我有一个连接到 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 [email protected]:apass "http://localhost:3000/reports.xml"

我希望“[email protected]< /a>" 和 "apass" 传递到内部块。一旦我有了密码,我就可以以正常方式使用电子邮件和密码的组合来查找(或不查找)用户。有谁知道我如何才能访问密码?

感谢任何建议 - 最大

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

I have an app which connects to an iphone app, which in turn authenticates it's users via http_digest.

I'm using authlogic, and in my schema users of the website are "users" and users of the phone app are "people". So, i have user_sessions and people_sessions. To handle the http_digest auth, i'm using the authenticate_or_request_with_http_digest method like this:

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

I can see in the logs that password is nil: only email is passed through to the inside of the authenticate_or_request_with_http_digest block.

Im testing this with a curl call like so:

curl --digest --user [email protected]:apass "http://localhost:3000/reports.xml"

I'd expect "[email protected]" and "apass" to get passed through to the inside of the block. Once i have the password then i can use a combination of email and password to find (or not) a user, in the normal way. Does anyone know how i can get access to the password as well?

grateful for any advice - max

EDIT - on further googling, i think i'm using this method wrong: i'm supposed to just return the password, or the crypted password. But then how do i compare that against the password passed as part of the http_digest username?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

吾家有女初长成 2024-11-22 16:32:17

找到答案:我对authenticate_or_request_with_http_digest的工作原理有一个根本性的误解:阅读文档(在gem的源代码中)后,我意识到这个方法的目的不是进行身份验证,它的目的是向浏览器提供“email: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

Found the answer: i had a fundamental misunderstanding of how authenticate_or_request_with_http_digest works: after reading the documentation (in the source code of the gem) i realised that the purpose of this method is not to do the authentication, its purpose is to provide the "email:realm:password" string to the browser, let the browser encrypt it, and check the result against it's own calculated (or cached) version of this.

Here's how i set it up:

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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文