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.



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

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

Instance Attribute Details

#schemeObject (readonly)

Authentication scheme.



511
512
513
# File 'lib/httpclient/auth.rb', line 511

def scheme
  @scheme
end

Instance Method Details

#challenge(uri, param_str) ⇒ Object

Challenge handler: remember URL and challenge token for response.



571
572
573
574
575
576
577
578
579
580
581
582
583
584
# File 'lib/httpclient/auth.rb', line 571

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.



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
# File 'lib/httpclient/auth.rb', line 539

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.



521
522
523
# File 'lib/httpclient/auth.rb', line 521

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.



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

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)


533
534
535
# File 'lib/httpclient/auth.rb', line 533

def set?
  SSPIEnabled || GSSAPIEnabled
end