Parent

Files

HTTPClient::DigestAuth

Authentication filter for handling DigestAuth negotiation. Used in WWWAuth.

Attributes

scheme[R]

Authentication scheme.

Public Class Methods

new() click to toggle source

Creates new DigestAuth filter.

     # File lib/httpclient/auth.rb, line 268
268:     def initialize
269:       @auth = {}
270:       @challenge = {}
271:       @nonce_count = 0
272:       @scheme = "Digest"
273:     end

Public Instance Methods

challenge(uri, param_str) click to toggle source

Challenge handler: remember URL and challenge token for response.

     # File lib/httpclient/auth.rb, line 309
309:     def challenge(uri, param_str)
310:       @challenge[uri] = parse_challenge_param(param_str)
311:       true
312:     end
get(req) click to toggle source

Response handler: returns credential. It sends cred only when a given uri is;

  • child page of challengeable(got *Authenticate before) uri and,

  • child page of defined credential

     # File lib/httpclient/auth.rb, line 294
294:     def get(req)
295:       target_uri = req.header.request_uri
296:       param = Util.hash_find_value(@challenge) { |uri, v|
297:         Util.uri_part_of(target_uri, uri)
298:       }
299:       return nil unless param
300:       user, passwd = Util.hash_find_value(@auth) { |uri, auth_data|
301:         Util.uri_part_of(target_uri, uri)
302:       }
303:       return nil unless user
304:       uri = req.header.request_uri
305:       calc_cred(req.header.request_method, uri, user, passwd, param)
306:     end
reset_challenge() click to toggle source

Resets challenge state. Do not send ’*Authorization’ header until the server sends ’*Authentication’ again.

     # File lib/httpclient/auth.rb, line 277
277:     def reset_challenge
278:       @challenge.clear
279:     end
set(uri, user, passwd) click to toggle source

Set authentication credential. uri == nil is ignored.

     # File lib/httpclient/auth.rb, line 283
283:     def set(uri, user, passwd)
284:       if uri
285:         uri = Util.uri_dirname(uri)
286:         @auth[uri] = [user, passwd]
287:       end
288:     end

Private Instance Methods

calc_cred(method, uri, user, passwd, param) click to toggle source

this method is implemented by sromano and posted to tools.assembla.com/breakout/wiki/DigestForSoap Thanks! supported algorithm: MD5 only for now

     # File lib/httpclient/auth.rb, line 320
320:     def calc_cred(method, uri, user, passwd, param)
321:       a_1 = "#{user}:#{param['realm']}:#{passwd}"
322:       a_2 = "#{method}:#{uri.path}"
323:       nonce = param['nonce']
324:       cnonce = generate_cnonce()
325:       @nonce_count += 1
326:       message_digest = []
327:       message_digest << Digest::MD5.hexdigest(a_1)
328:       message_digest << nonce
329:       message_digest << ('%08x' % @nonce_count)
330:       message_digest << cnonce
331:       message_digest << param['qop']
332:       message_digest << Digest::MD5.hexdigest(a_2)
333:       header = []
334:       header << "username=\"#{user}\""
335:       header << "realm=\"#{param['realm']}\""
336:       header << "nonce=\"#{nonce}\""
337:       header << "uri=\"#{uri.path}\""
338:       header << "cnonce=\"#{cnonce}\""
339:       header << "nc=#{'%08x' % @nonce_count}"
340:       header << "qop=\"#{param['qop']}\""
341:       header << "response=\"#{Digest::MD5.hexdigest(message_digest.join(":"))}\""
342:       header << "algorithm=\"MD5\""
343:       header << "opaque=\"#{param['opaque']}\"" if param.key?('opaque')
344:       header.join(", ")
345:     end
generate_cnonce() click to toggle source

cf. WEBrick::HTTPAuth::DigestAuth#generate_next_nonce(aTime)

     # File lib/httpclient/auth.rb, line 348
348:     def generate_cnonce
349:       now = "%012d" % Time.now.to_i
350:       pk = Digest::MD5.hexdigest([now, self.__id__, Process.pid, rand(65535)].join)[0, 32]
351:       [now + ':' + pk].pack('m*').chop
352:     end
parse_challenge_param(param_str) click to toggle source
     # File lib/httpclient/auth.rb, line 354
354:     def parse_challenge_param(param_str)
355:       param = {}
356:       param_str.scan(/\s*([^\,]+(?:\\.[^\,]*)*)/).each do |str|
357:         key, value = str[0].scan(/\A([^=]+)=(.*)\z/)[0]
358:         if /\A"(.*)"\z/ =~ value
359:           value = $1.gsub(/\\(.)/, '\1')
360:         end
361:         param[key] = value
362:       end
363:       param
364:     end

Disabled; run with --debug to generate this.

[Validate]

Generated with the Darkfish Rdoc Generator 1.1.6.