class Rack::Auth::Digest::MD5 - rack-1.6.1 Documentation

# 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 24
    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 37
    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 33
    def passwords_hashed?
      !!@passwords_hashed
    end

### Private Instance Methods

A1(auth, password) click to toggle source

    # File lib/rack/auth/digest/md5.rb, line 112
    def A1(auth, password)
      [ auth.username, auth.realm, password ] * ':'
    end

A2(auth) click to toggle source

    # File lib/rack/auth/digest/md5.rb, line 116
    def A2(auth)
      [ auth.method, auth.uri ] * ':'
    end

H(data)
Alias for: md5
KD(secret, data) click to toggle source

    # File lib/rack/auth/digest/md5.rb, line 108
    def KD(secret, data)
      H([secret, data] * ':')
    end

challenge(hash = {}) click to toggle source

    # File lib/rack/auth/digest/md5.rb, line 77
    def challenge(hash = {})
      "Digest #{params(hash)}"
    end

digest(auth, password) click to toggle source

    # File lib/rack/auth/digest/md5.rb, line 120
    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 102
    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 66
    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 81
    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 97
    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 93
    def valid_nonce?(auth)
      auth.nonce.valid?
    end

valid_opaque?(auth) click to toggle source

    # File lib/rack/auth/digest/md5.rb, line 89
    def valid_opaque?(auth)
      H(opaque) == auth.opaque
    end

valid_qop?(auth) click to toggle source

    # File lib/rack/auth/digest/md5.rb, line 85
    def valid_qop?(auth)
      QOP == auth.qop
    end