类 Win32::SSPI::NegotiateAuth
处理“Negotiate”类型身份验证。 旨在通过 HTTP 与代理服务器进行身份验证
常量
属性
context[RW]
contextAttributes[RW]
credentials[RW]
domain[RW]
user[RW]
公共类方法
new(user = nil, domain = nil) 点击切换源代码
创建一个新的实例,准备以给定域中的给定用户身份进行身份验证。 如果没有提供参数,则默认为当前用户和域,如 ENV 和 ENV 所定义。
# File ext/win32/lib/win32/sspi.rb, line 245 def initialize(user = nil, domain = nil) if user.nil? && domain.nil? && ENV["USERNAME"].nil? && ENV["USERDOMAIN"].nil? raise "A username or domain must be supplied since they cannot be retrieved from the environment" end @user = user || ENV["USERNAME"] @domain = domain || ENV["USERDOMAIN"] end
proxy_auth_get(http, path, user = nil, domain = nil) 点击切换源代码
给定连接和请求路径,以当前用户身份执行身份验证,并返回来自 GET 请求的响应。 连接应为 Net::HTTP
对象,并且应使用 Net::HTTP.Proxy 方法构建,但任何响应“get”的方法都将起作用。 如果提供用户和域,则将以给定用户身份进行身份验证。 返回从 get 方法接收到的响应(通常为 Net::HTTPResponse
)
# File ext/win32/lib/win32/sspi.rb, line 230 def NegotiateAuth.proxy_auth_get(http, path, user = nil, domain = nil) raise "http must respond to :get" unless http.respond_to?(:get) nego_auth = self.new user, domain resp = http.get path, { "Proxy-Authorization" => "Negotiate " + nego_auth.get_initial_token } if resp["Proxy-Authenticate"] resp = http.get path, { "Proxy-Authorization" => "Negotiate " + nego_auth.complete_authentication(resp["Proxy-Authenticate"].split(" ").last.strip) } end resp end
公共实例方法
complete_authentication(token) 点击切换源代码
接收一个令牌,获取 Negotiate 身份验证链中的下一个令牌。令牌可以是 Base64
编码或未编码。令牌可以包含“Negotiate”头,它将被剥离。不指示是否返回了 SEC_I_CONTINUE 或 SEC_E_OK。返回的令牌是 Base64
编码的,所有换行符都已删除。
# File ext/win32/lib/win32/sspi.rb, line 278 def complete_authentication(token) raise "This object is no longer usable because its resources have been freed." if @cleaned_up # Nil token OK, just set it to empty string token = "" if token.nil? if token.include? "Negotiate" # If the Negotiate prefix is passed in, assume we are seeing "Negotiate <token>" and get the token. token = token.split(" ").last end if token.include? B64_TOKEN_PREFIX # indicates base64 encoded token token = token.strip.unpack("m")[0] end outputBuffer = SecurityBuffer.new result = SSPIResult.new(API::InitializeSecurityContext.call(@credentials.to_p, @context.to_p, nil, REQUEST_FLAGS, 0, SECURITY_NETWORK_DREP, SecurityBuffer.new(token).to_p, 0, @context.to_p, outputBuffer.to_p, @contextAttributes, TimeStamp.new.to_p)) if result.ok? then return encode_token(outputBuffer.token) else raise "Error: #{result.to_s}" end ensure # need to make sure we don't clean up if we've already cleaned up. clean_up unless @cleaned_up end
get_initial_token() 点击以切换源代码
获取初始 Negotiate 令牌。将其作为适合在 HTTP 中使用的 base64 编码字符串返回。但是,可以轻松解码。
# File ext/win32/lib/win32/sspi.rb, line 256 def get_initial_token raise "This object is no longer usable because its resources have been freed." if @cleaned_up get_credentials outputBuffer = SecurityBuffer.new @context = CtxtHandle.new @contextAttributes = "\0" * 4 result = SSPIResult.new(API::InitializeSecurityContextA.call(@credentials.to_p, nil, nil, REQUEST_FLAGS,0, SECURITY_NETWORK_DREP, nil, 0, @context.to_p, outputBuffer.to_p, @contextAttributes, TimeStamp.new.to_p)) if result.ok? then return encode_token(outputBuffer.token) else raise "Error: #{result.to_s}" end end
私有实例方法
clean_up() 点击以切换源代码
# File ext/win32/lib/win32/sspi.rb, line 312 def clean_up # free structures allocated @cleaned_up = true API::FreeCredentialsHandle.call(@credentials.to_p) API::DeleteSecurityContext.call(@context.to_p) @context = nil @credentials = nil @contextAttributes = nil end
encode_token(t) 点击以切换源代码
# File ext/win32/lib/win32/sspi.rb, line 332 def encode_token(t) # encode64 will add newlines every 60 characters so we need to remove those. [t].pack("m").delete("\n") end
get_credentials() 点击以切换源代码
根据用户、域或两者获取凭据。如果两者都为空,则会发生错误。
# File ext/win32/lib/win32/sspi.rb, line 323 def get_credentials @credentials = CredHandle.new ts = TimeStamp.new @identity = Identity.new @user, @domain result = SSPIResult.new(API::AcquireCredentialsHandleA.call(nil, "Negotiate", SECPKG_CRED_OUTBOUND, nil, @identity.to_p, nil, nil, @credentials.to_p, ts.to_p)) raise "Error acquire credentials: #{result}" unless result.ok? end