Class: HTTPClient::NegotiateAuth

Inherits:
AuthBase
  • Object
show all
Includes:
Mutex_m
Defined in:
lib/httpclient/auth.rb

Overview

Authentication filter for handling Negotiate/NTLM negotiation. Used in WWWAuth and ProxyAuth.

NegotiateAuth depends on 'ruby/ntlm' module.

Instance Attribute Summary collapse

Attributes inherited from AuthBase

#scheme

Instance Method Summary collapse

Methods inherited from AuthBase

#reset_challenge

Methods included from Util

#argument_to_hash, hash_find_value, #http?, #https?, #keyword_argument, try_require, uri_dirname, uri_part_of, urify, #warning

Constructor Details

#initialize(scheme = "Negotiate") ⇒ NegotiateAuth

Creates new NegotiateAuth filter.


506
507
508
509
510
511
512
513
# File 'lib/httpclient/auth.rb', line 506

def initialize(scheme = "Negotiate")
  super(scheme)
  @auth = {}
  @auth_default = nil
  @ntlm_opt = {
    :ntlmv2 => true
  }
end

Instance Attribute Details

#ntlm_optObject (readonly)

NTLM opt for ruby/ntlm. => true by default.


503
504
505
# File 'lib/httpclient/auth.rb', line 503

def ntlm_opt
  @ntlm_opt
end

Instance Method Details

#challenge(uri, param_str) ⇒ Object

Challenge handler: remember URL and challenge token for response.


575
576
577
578
579
580
581
582
583
584
585
586
587
588
# File 'lib/httpclient/auth.rb', line 575

def challenge(uri, param_str)
  synchronize {
    if param_str.nil? or @challenge[uri].nil?
      c = @challenge[uri] = {}
      c[:state] = :init
      c[:authphrase] = ""
    else
      c = @challenge[uri]
      c[:state] = :response
      c[:authphrase] = param_str
    end
    true
  }
end

#get(req) ⇒ Object

Response handler: returns credential. See ruby/ntlm for negotiation state transition.


535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
# File 'lib/httpclient/auth.rb', line 535

def get(req)
  target_uri = req.header.request_uri
  synchronize {
    _domain_uri, param = @challenge.find { |uri, v|
      Util.uri_part_of(target_uri, uri)
    }
    return nil unless param
    user, passwd = Util.hash_find_value(@auth) { |uri, auth_data|
      Util.uri_part_of(target_uri, uri)
    }
    unless user
      user, passwd = @auth_default
    end
    return nil unless user
    Util.try_require('net/ntlm') || return
    domain = nil
    domain, user = user.split("\\") if user.index("\\")
    state = param[:state]
    authphrase = param[:authphrase]
    case state
    when :init
      t1 = Net::NTLM::Message::Type1.new
      t1.domain = domain if domain
      t1.encode64
    when :response
      t2 = Net::NTLM::Message.decode64(authphrase)
      param = {:user => user, :password => passwd}
      param[:domain] = domain if domain
      t3 = t2.response(param, @ntlm_opt.dup)
      @challenge[target_uri][:state] = :done
      t3.encode64
    when :done
      :skip
    else
      nil
    end
  }
end

#set(uri, user, passwd) ⇒ Object

Set authentication credential. uri == nil for generic purpose (allow to use user/password for any URL).


517
518
519
520
521
522
523
524
525
526
# File 'lib/httpclient/auth.rb', line 517

def set(uri, user, passwd)
  synchronize do
    if uri
      uri = Util.uri_dirname(uri)
      @auth[uri] = [user, passwd]
    else
      @auth_default = [user, passwd]
    end
  end
end

#set?Boolean

have we marked this as set - ie that it's valid to use in this context?

Returns:

  • (Boolean)

529
530
531
# File 'lib/httpclient/auth.rb', line 529

def set?
  @auth_default || @auth.any?
end