class HTTPClient::WWWAuth
SSPINegotiateAuth requires ‘win32/sspi’ module (rubysspi gem).
NegotiateAuth requires ‘ruby/ntlm’ module (rubyntlm gem).
SSPINegotiateAuth) and delegates some operations to it.
WWWAuth has sub filters (BasicAuth, DigestAuth, NegotiateAuth and
traps HTTP request header for inserting necessary authentication header.
It traps HTTP response header and maintains authentication state, and
Authentication filter is implemented using request filter of HTTPClient.
generates ‘Authorization’ header in request.
Web server. Parses ‘WWW-Authentication’ header in response and
Authentication filter for handling authentication negotiation between
def filter_request(req)
Filter API implementation. Traps HTTP request and insert
def filter_request(req) @authenticator.each do |auth| next unless auth.set? # hasn't be set, don't use it if cred = auth.get(req) if cred == :skip # some authenticator (NTLM and Negotiate) does not # need to send extra header after authorization. In such case # it should block other authenticators to respond and :skip is # the marker for such case. return end req.header.set('Authorization', auth.scheme + " " + cred) return end end end
def filter_response(req, res)
available to the client. On the subsequent retry of the request,
This remembers the challenges for all authentication methods
'WWW-Authenticate' header.
Filter API implementation. Traps HTTP response and parses
def filter_response(req, res) command = nil if res.status == HTTP::Status::UNAUTHORIZED if challenge = parse_authentication_header(res, 'www-authenticate') uri = req.header.request_uri challenge.each do |scheme, param_str| @authenticator.each do |auth| next unless auth.set? # hasn't be set, don't use it if scheme.downcase == auth.scheme.downcase challengeable = auth.challenge(uri, param_str) command = :retry if challengeable end end end # ignore unknown authentication scheme end end command end
def initialize
def initialize @basic_auth = BasicAuth.new @digest_auth = DigestAuth.new @negotiate_auth = NegotiateAuth.new @ntlm_auth = NegotiateAuth.new('NTLM') @sspi_negotiate_auth = SSPINegotiateAuth.new @oauth = OAuth.new # sort authenticators by priority @authenticator = [@oauth, @negotiate_auth, @ntlm_auth, @sspi_negotiate_auth, @digest_auth, @basic_auth] end
def reset_challenge
def reset_challenge @authenticator.each do |auth| auth.reset_challenge end end
def set_auth(uri, user, passwd)
def set_auth(uri, user, passwd) @authenticator.each do |auth| auth.set(uri, user, passwd) end reset_challenge end