Class: HTTPClient::SSPINegotiateAuth

Inherits:
AuthBase
  • Object
show all
Includes:
Mutex_m
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

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

#initializeSSPINegotiateAuth

Creates new SSPINegotiateAuth filter.


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

def initialize
  super('Negotiate')
end

Instance Method Details

#challenge(uri, param_str) ⇒ Object

Challenge handler: remember URL and challenge token for response.


655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
# File 'lib/httpclient/auth.rb', line 655

def challenge(uri, param_str)
  synchronize {
    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.


618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
# File 'lib/httpclient/auth.rb', line 618

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
    Util.try_require('win32/sspi') || Util.try_require('gssapi') || return
    state = param[:state]
    authenticator = param[:authenticator]
    authphrase = param[:authphrase]
    case state
    when :init
      if defined?(Win32::SSPI)
        authenticator = param[:authenticator] = Win32::SSPI::NegotiateAuth.new
        authenticator.get_initial_token(@scheme)
      else # use GSSAPI
        authenticator = param[:authenticator] = GSSAPI::Simple.new(domain_uri.host, 'HTTP')
        # Base64 encode the context token
        [authenticator.init_context].pack('m').gsub(/\n/,'')
      end
    when :response
      @challenge[target_uri][:state] = :done
      if defined?(Win32::SSPI)
        authenticator.complete_authentication(authphrase)
      else # use GSSAPI
        authenticator.init_context(authphrase.unpack('m').pop)
      end
    when :done
      :skip
    else
      nil
    end
  }
end

#set(*args) ⇒ Object

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


607
608
609
# File 'lib/httpclient/auth.rb', line 607

def set(*args)
  # not supported
end

#set?Boolean

Check always (not effective but it works)

Returns:

  • (Boolean)

612
613
614
# File 'lib/httpclient/auth.rb', line 612

def set?
  !@challenge.empty?
end