class Rack::Auth::Digest::MD5
Rack::Auth::Digest::MD5 implements the MD5 algorithm version of HTTP Digest Authentication, as per RFC 2617.
Initialize with the [Rack] application that you want protecting, and a block that looks up a plaintext password for a given username.
opaque
needs to be set to a constant base64/hexadecimal
string.
Constants
- QOP
Attributes
opaque[RW]
passwords_hashed[W]
Public Class Methods
new(app, realm = nil, opaque = nil, &authenticator)
click to toggle source
Calls superclass method
Rack::Auth::AbstractHandler.new
# File lib/rack/auth/digest/md5.rb, line 25 def initialize(app, realm = nil, opaque = nil, &authenticator) @passwords_hashed = nil if opaque.nil? and realm.respond_to? :values_at realm, opaque, @passwords_hashed = realm.values_at :realm, :opaque, :passwords_hashed end super(app, realm, &authenticator) @opaque = opaque end
Public Instance Methods
call(env)
click to toggle source
# File lib/rack/auth/digest/md5.rb, line 38 def call(env) auth = Request.new(env) unless auth.provided? return unauthorized end if !auth.digest? || !auth.correct_uri? || !valid_qop?(auth) return bad_request end if valid?(auth) if auth.nonce.stale? return unauthorized(challenge(stale: true)) else env['REMOTE_USER'] = auth.username return @app.call(env) end end unauthorized end
passwords_hashed?()
click to toggle source
# File lib/rack/auth/digest/md5.rb, line 34 def passwords_hashed? !!@passwords_hashed end
Private Instance Methods
A1(auth, password)
click to toggle source
# File lib/rack/auth/digest/md5.rb, line 113 def A1(auth, password) "#{auth.username}:#{auth.realm}:#{password}" end
A2(auth)
click to toggle source
# File lib/rack/auth/digest/md5.rb, line 117 def A2(auth) "#{auth.method}:#{auth.uri}" end
KD(secret, data)
click to toggle source
# File lib/rack/auth/digest/md5.rb, line 109 def KD(secret, data) H "#{secret}:#{data}" end
challenge(hash = {})
click to toggle source
# File lib/rack/auth/digest/md5.rb, line 78 def challenge(hash = {}) "Digest #{params(hash)}" end
digest(auth, password)
click to toggle source
# File lib/rack/auth/digest/md5.rb, line 121 def digest(auth, password) password_hash = passwords_hashed? ? password : H(A1(auth, password)) KD password_hash, "#{auth.nonce}:#{auth.nc}:#{auth.cnonce}:#{QOP}:#{H A2(auth)}" end
md5(data)
click to toggle source
# File lib/rack/auth/digest/md5.rb, line 103 def md5(data) ::Digest::MD5.hexdigest(data) end
Also aliased as: H
params(hash = {})
click to toggle source
# File lib/rack/auth/digest/md5.rb, line 67 def params(hash = {}) Params.new do |params| params['realm'] = realm params['nonce'] = Nonce.new.to_s params['opaque'] = H(opaque) params['qop'] = QOP hash.each { |k, v| params[k] = v } end end
valid?(auth)
click to toggle source
# File lib/rack/auth/digest/md5.rb, line 82 def valid?(auth) valid_opaque?(auth) && valid_nonce?(auth) && valid_digest?(auth) end
valid_digest?(auth)
click to toggle source
# File lib/rack/auth/digest/md5.rb, line 98 def valid_digest?(auth) pw = @authenticator.call(auth.username) pw && Rack::Utils.secure_compare(digest(auth, pw), auth.response) end
valid_nonce?(auth)
click to toggle source
# File lib/rack/auth/digest/md5.rb, line 94 def valid_nonce?(auth) auth.nonce.valid? end
valid_opaque?(auth)
click to toggle source
# File lib/rack/auth/digest/md5.rb, line 90 def valid_opaque?(auth) H(opaque) == auth.opaque end
valid_qop?(auth)
click to toggle source
# File lib/rack/auth/digest/md5.rb, line 86 def valid_qop?(auth) QOP == auth.qop end