Class: Net::HTTP::DigestAuth

### Home Classes Methods

### In Files

- lib/net/http/digest_auth.rb

### Parent

Object

### Namespace

- CLASS Net::HTTP::DigestAuth::Error

### Methods

- ::new
- #auth_header
- #make_cnonce
- #next_nonce

### Included Modules

- MonitorMixin

### Files

- History.txt
- Manifest.txt
- README.txt

### Class/Module Index

Quicksearch

- Net
- Net::HTTP
- Net::HTTP::DigestAuth
- Net::HTTP::DigestAuth::Error

No matching classes.

# Net::HTTP::DigestAuth

An implementation of RFC 2617 Digest Access Authentication.

www.rfc-editor.org/rfc/rfc2617.txt

Here is a sample usage of DigestAuth on Net::HTTP:

    require 'uri'
    require 'net/http'
    require 'net/http/digest_auth'

    digest_auth = Net::HTTP::DigestAuth.new

    uri = URI.parse 'http://localhost:8000/'
    uri.user = 'username'
    uri.password = 'password'

    h = Net::HTTP.new uri.host, uri.port

    req = Net::HTTP::Get.new uri.request_uri

    res = h.request req
    # res is a 401 response with a WWW-Authenticate header

    auth = digest_auth.auth_header uri, res['www-authenticate'], 'GET'

    # create a new request with the Authorization header
    req = Net::HTTP::Get.new uri.request_uri
    req.add_field 'Authorization', auth

    # re-issue request with Authorization
    res = h.request req

### Constants

VERSION

  Version of Net::HTTP::DigestAuth you are using

### Public Class Methods

new(ignored = :ignored) click to toggle source

Creates a new DigestAuth header creator.

    # File lib/net/http/digest_auth.rb, line 57
    def initialize ignored = :ignored
      mon_initialize
      @nonce_count = -1
    end

### Public Instance Methods

auth_header(uri, www_authenticate, method, iis = false) click to toggle source

Creates a digest auth header for `uri` from the `www_authenticate` header for HTTP method `method`.

The result of this method should be sent along with the HTTP request as the "Authorization" header. In Net::HTTP this will look like:

    request.add_field 'Authorization', digest_auth.auth_header # ...

See Net::HTTP::DigestAuth for a complete example.

IIS servers handle the "qop" parameter of digest authentication differently so you may need to set `iis` to true for such servers.

    # File lib/net/http/digest_auth.rb, line 76
    def auth_header uri, www_authenticate, method, iis = false
      nonce_count = next_nonce

      user     = CGI.unescape uri.user
      password = CGI.unescape uri.password

      www_authenticate =~ /^(\w+) (.*)/

      challenge = $2

      params = {}
      challenge.gsub(/(\w+)="(.*?)"/) { params[$1] = $2 }

      challenge =~ /algorithm="?(.*?)"?([, ]|$)/

      params['algorithm'] = $1 || 'MD5'

      if params['algorithm'] =~ /(.*?)(-sess)?$/
        algorithm = case $1
                    when 'MD5'    then Digest::MD5
                    when 'SHA1'   then Digest::SHA1
                    when 'SHA2'   then Digest::SHA2
                    when 'SHA256' then Digest::SHA256
                    when 'SHA384' then Digest::SHA384
                    when 'SHA512' then Digest::SHA512
                    when 'RMD160' then Digest::RMD160
                    else raise Error, "unknown algorithm \"#{$1}\""
                    end
        sess = $2
      end

      qop = params['qop']
      cnonce = make_cnonce if qop or sess

      a1 = if sess then
             [ algorithm.hexdigest("#{user}:#{params['realm']}:#{password}"),
               params['nonce'],
               cnonce,
             ].join ':'
           else
             "#{user}:#{params['realm']}:#{password}"
           end

      ha1 = algorithm.hexdigest a1
      ha2 = algorithm.hexdigest "#{method}:#{uri.request_uri}"

      request_digest = [ha1, params['nonce']]
      request_digest.push(('%08x' % nonce_count), cnonce, qop) if qop
      request_digest << ha2
      request_digest = request_digest.join ':'

      header = [
        "Digest username=\"#{user}\"",
        "realm=\"#{params['realm']}\"",
        "algorithm=#{params['algorithm']}",
        if qop.nil? then
        elsif iis then
          "qop=\"#{qop}\""
        else
          "qop=#{qop}"
        end,
        "uri=\"#{uri.request_uri}\"",
        "nonce=\"#{params['nonce']}\"",
        if qop then
          [
            "nc=#{'%08x' % @nonce_count}",
            "cnonce=\"#{cnonce}\"",
          ]
        end,
        "response=\"#{algorithm.hexdigest(request_digest)[0, 32]}\"",
        if params.key? 'opaque' then
          "opaque=\"#{params['opaque']}\""
        end
      ].compact

      header.join ', '
    end

make_cnonce() click to toggle source

Creates a client nonce value that is used across all requests based on the current time, process id and a random number

    # File lib/net/http/digest_auth.rb, line 158
    def make_cnonce
      Digest::MD5.hexdigest [
        Time.now.to_i,
        $$,
        SecureRandom.random_number(2**32),
      ].join ':'
    end

next_nonce() click to toggle source

    # File lib/net/http/digest_auth.rb, line 166
    def next_nonce
      synchronize do
        @nonce_count += 1
      end
    end

[Validate]

Generated with the Darkfish Rdoc Generator 2.