Class: HTTPClient::NegotiateAuth

Inherits:
Object
  • 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

Instance Method Summary collapse

Constructor Details

#initialize(scheme = "Negotiate") ⇒ NegotiateAuth

Creates new NegotiateAuth filter.



502
503
504
505
506
507
508
509
510
511
# File 'lib/httpclient/auth.rb', line 502

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

Instance Attribute Details

#ntlm_optObject (readonly)

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



499
500
501
# File 'lib/httpclient/auth.rb', line 499

def ntlm_opt
  @ntlm_opt
end

#schemeObject (readonly)

Authentication scheme.



497
498
499
# File 'lib/httpclient/auth.rb', line 497

def scheme
  @scheme
end

Instance Method Details

#challenge(uri, param_str) ⇒ Object

Challenge handler: remember URL and challenge token for response.



578
579
580
581
582
583
584
585
586
587
588
589
590
591
# File 'lib/httpclient/auth.rb', line 578

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.



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
573
574
575
# File 'lib/httpclient/auth.rb', line 541

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
      return 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.delete(domain_uri)
      return t3.encode64
    end
    nil
  }
end

#reset_challengeObject

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



515
516
517
518
519
# File 'lib/httpclient/auth.rb', line 515

def reset_challenge
  synchronize do
    @challenge.clear
  end
end

#set(uri, user, passwd) ⇒ Object

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



523
524
525
526
527
528
529
530
531
532
# File 'lib/httpclient/auth.rb', line 523

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)


535
536
537
# File 'lib/httpclient/auth.rb', line 535

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