2013-04-04 86 views
2

我正在爲基於HTTP摘要驗證的用戶驗證用戶的ruby應用程序創建一個API。我決定使用Grape API庫,因爲它使得在Ruby中創建一個API清理器。葡萄文檔指出您可以使用摘要式身份驗證,如:葡萄API和HTTP摘要驗證

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

上面的葡萄實現是Rack::Auth::Digest::MD5

的包裝現在也爲安全,我讀了如RFC 2617中你不需要存儲密碼爲您存儲用戶名的MD5摘要數據庫明文:境界:密碼和authticate對抗,所以我創建了一個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 

現在用我提供什麼,我失去了對如何連接這些t我並讓它工作。

回答

3

不幸的是,Rack::Auth::Digest::MD5需要服務器端的明文密碼。

葡萄示例代碼顯示了一個硬編碼的密碼查找。

您可以用

Key.first(:username => username).password 

提供您存儲明文密碼Key類取代{ 'user1' => 'password1' }[username]。您可以存儲這些可逆加密的我想,儘管這不會增加很多安全性,除非您爲密鑰管理構建相對複雜/昂貴的方案。

不知道是否有解決方法,讓你存儲散列密碼。 MD5不是最安全的散列選擇(雖然比沒有好!)。如果安全性是您的API的重要關注點,那麼您會希望超越摘要驗證 - 例如,使用https可以提供幫助。

編輯:繼位到往復討論,葡萄的示例的以下變化允許你存儲的密碼MD5'd:

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兩次。這有點冒險,但至少你不必編寫自己的中間件,Grape仍然在處理它。這是而不是葡萄記錄的功能或覆蓋測試,所以可能無法在未來的版本。

+0

環顧四周後[機架文摘MD5(https://github.com/rack/rack/blob/master/lib/rack/auth/digest/md5.rb)我想通了,如果'attr_writer:passwords_hashed'設置爲「真」,那麼它將接受格式爲'username:realm:password'的已經哈希密碼,這很好,但即時通過Grape API封裝器設置該屬性有困難。有什麼建議麼? – ny95 2013-04-05 14:16:08

+0

通過查看葡萄碼,您可以將哈希提供給':realm'符號,其中包含':realm,:opaque,:passwords_hashed'鍵。 。 。沒有記錄或在葡萄測試,所以有點後門你想要的。我測試了它,但它對我沒有用。 – 2013-04-05 15:03:29

+0

我想去嘗試一下,看看會發生什麼,對於不透明的值,它是什麼意思,我可以將它設置爲「SecureRandom.hex(15)」嗎? – ny95 2013-04-05 15:10:57