Class: Tilia::Http::Auth::Digest

Inherits:
AbstractAuth show all
Defined in:
lib/tilia/http/auth/digest.rb

Overview

HTTP Digest Authentication handler

Use this class for easy http digest authentication. Instructions:

1. Create the object
2. Call the set_realm method with the realm you plan to use
3. Call the init method function.
4. Call the user_name function. This function may return null if no
   authentication information was supplied. Based on the username you
   should check your internal database for either the associated password,
   or the so-called A1 hash of the digest.
5. Call either validate_password or validate_a1. This will return true
   or false.
6. To make sure an authentication prompt is displayed, call the
    method.

Constant Summary collapse

QOP_AUTH =

These constants are used in qop

1
QOP_AUTHINT =
2

Instance Attribute Summary collapse

Attributes inherited from AbstractAuth

#realm

Instance Method Summary collapse

Constructor Details

#initialize(realm = 'TiliaTooth', request, response) ⇒ Digest

Initializes the object



37
38
39
40
41
42
43
# File 'lib/tilia/http/auth/digest.rb', line 37

def initialize(realm = 'TiliaTooth', request, response)
  @qop = self.class::QOP_AUTH

  @nonce = ::Digest::SHA1.hexdigest((Time.now.to_f + rand).to_s)[0..14]
  @opaque = ::Digest::MD5.hexdigest(realm)
  super(realm, request, response)
end

Instance Attribute Details

#qop=(value) ⇒ void

This method returns an undefined value.

Sets the quality of protection value.

Possible values are:

Sabre\HTTP\DigestAuth::QOP_AUTH
Sabre\HTTP\DigestAuth::QOP_AUTHINT

Multiple values can be specified using logical OR.

QOP_AUTHINT ensures integrity of the request body, but this is not supported by most HTTP clients. QOP_AUTHINT also requires the entire request body to be md5’ed, which can put strains on CPU and memory.

Parameters:

  • int

    qop



69
70
71
# File 'lib/tilia/http/auth/digest.rb', line 69

def qop=(value)
  @qop = value
end

Instance Method Details

#digestObject

This method returns the full digest string.

It should be compatibile with mod_php format and other webservers.

If the header could not be found, null will be returned

Returns:

  • mixed



160
161
162
# File 'lib/tilia/http/auth/digest.rb', line 160

def digest
  @request.header('Authorization')
end

#initvoid

This method returns an undefined value.

Gathers all information from the headers

This method needs to be called prior to anything else.



50
51
52
53
# File 'lib/tilia/http/auth/digest.rb', line 50

def init
  digest = self.digest || ''
  @digest_parts = parse_digest(digest)
end

#require_loginvoid

This method returns an undefined value.

Returns an HTTP 401 header, forcing login

This should be called when username and password are incorrect, or not supplied at all



138
139
140
141
142
143
144
145
146
147
148
149
150
151
# File 'lib/tilia/http/auth/digest.rb', line 138

def 
  qop = ''
  case @qop
  when self.class::QOP_AUTH
    qop = 'auth'
  when self.class::QOP_AUTHINT
    qop = 'auth-int'
  when self.class::QOP_AUTH | self.class::QOP_AUTHINT
    qop = 'auth,auth-int'
  end

  @response.add_header('WWW-Authenticate', "Digest realm=\"#{@realm}\",qop=\"#{qop}\",nonce=\"#{@nonce}\",opaque=\"#{@opaque}\"")
  @response.status = 401
end

#usernameString

Returns the username for the request

Returns:

  • (String)


97
98
99
# File 'lib/tilia/http/auth/digest.rb', line 97

def username
  @digest_parts['username']
end

#validate_a1(a1) ⇒ Object

Validates the user.

The A1 parameter should be md5(username . ‘:’ . realm . ‘:’ . password)

Parameters:

  • a1 (String)

Returns:

  • bool



77
78
79
80
# File 'lib/tilia/http/auth/digest.rb', line 77

def validate_a1(a1)
  @a1 = a1
  validate
end

#validate_password(password) ⇒ Object

Validates authentication through a password. The actual password must be provided here. It is strongly recommended not store the password in plain-text and use validateA1 instead.

Parameters:

  • password (String)

Returns:

  • bool



87
88
89
90
91
92
# File 'lib/tilia/http/auth/digest.rb', line 87

def validate_password(password)
  return false unless @digest_parts.any? # RUBY

  @a1 = ::Digest::MD5.hexdigest(@digest_parts['username'] + ':' + @realm + ':' + password)
  validate
end