Class: HTTPClient::SSPINegotiateAuth

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

Overview

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

SSPINegotiateAuth depends on 'win32/sspi' module.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeSSPINegotiateAuth

Creates new SSPINegotiateAuth filter.


582
583
584
585
# File 'lib/httpclient/auth.rb', line 582

def initialize
  @challenge = {}
  @scheme = "Negotiate"
end

Instance Attribute Details

#schemeObject (readonly)

Authentication scheme.


579
580
581
# File 'lib/httpclient/auth.rb', line 579

def scheme
  @scheme
end

Instance Method Details

#challenge(uri, param_str) ⇒ Object

Challenge handler: remember URL and challenge token for response.


639
640
641
642
643
644
645
646
647
648
649
650
651
652
# File 'lib/httpclient/auth.rb', line 639

def challenge(uri, param_str)
  return false unless SSPIEnabled || GSSAPIEnabled
  if param_str.nil? or @challenge[uri].nil?
    c = @challenge[uri] = {}
    c[:state] = :init
    c[:authenticator] = nil
    c[:authphrase] = ""
  else
    c = @challenge[uri]
    c[:state] = :response
    c[:authphrase] = param_str
  end
  true
end

#get(req) ⇒ Object

Response handler: returns credential. See win32/sspi for negotiation state transition.


607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
# File 'lib/httpclient/auth.rb', line 607

def get(req)
  return nil unless SSPIEnabled || GSSAPIEnabled
  target_uri = req.header.request_uri
  domain_uri, param = @challenge.find { |uri, v|
    Util.uri_part_of(target_uri, uri)
  }
  return nil unless param
  state = param[:state]
  authenticator = param[:authenticator]
  authphrase = param[:authphrase]
  case state
  when :init
    if SSPIEnabled
      authenticator = param[:authenticator] = Win32::SSPI::NegotiateAuth.new
      return authenticator.get_initial_token(@scheme)
    else # use GSSAPI
      authenticator = param[:authenticator] = GSSAPI::Simple.new(domain_uri.host, 'HTTP')
      # Base64 encode the context token
      return [authenticator.init_context].pack('m').gsub(/\n/,'')
    end
  when :response
    @challenge.delete(domain_uri)
    if SSPIEnabled
      return authenticator.complete_authentication(authphrase)
    else # use GSSAPI
      return authenticator.init_context(authphrase.unpack('m').pop)
    end
  end
  nil
end

#reset_challengeObject

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


589
590
591
# File 'lib/httpclient/auth.rb', line 589

def reset_challenge
  @challenge.clear
end

#set(*args) ⇒ Object

Set authentication credential. NOT SUPPORTED: username and necessary data is retrieved by win32/sspi. See win32/sspi for more details.


596
597
598
# File 'lib/httpclient/auth.rb', line 596

def set(*args)
  # not supported
end

#set?Boolean

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

Returns:

  • (Boolean)

601
602
603
# File 'lib/httpclient/auth.rb', line 601

def set?
  SSPIEnabled || GSSAPIEnabled
end