Class: HTTPClient::SSPINegotiateAuth

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

Instance Method Summary collapse

Constructor Details

#initializeSSPINegotiateAuth

Creates new SSPINegotiateAuth filter.



637
638
639
640
641
# File 'lib/httpclient/auth.rb', line 637

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

Instance Attribute Details

#schemeObject (readonly)

Authentication scheme.



634
635
636
# File 'lib/httpclient/auth.rb', line 634

def scheme
  @scheme
end

Instance Method Details

#challenge(uri, param_str) ⇒ Object

Challenge handler: remember URL and challenge token for response.



699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
# File 'lib/httpclient/auth.rb', line 699

def challenge(uri, param_str)
  return false unless SSPIEnabled || GSSAPIEnabled
  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.



665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
# File 'lib/httpclient/auth.rb', line 665

def get(req)
  return nil unless SSPIEnabled || GSSAPIEnabled
  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
    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.



645
646
647
648
649
# File 'lib/httpclient/auth.rb', line 645

def reset_challenge
  synchronize do
    @challenge.clear
  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.



654
655
656
# File 'lib/httpclient/auth.rb', line 654

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)


659
660
661
# File 'lib/httpclient/auth.rb', line 659

def set?
  SSPIEnabled || GSSAPIEnabled
end