類別 Win32::SSPI::NegotiateAuth
處理「協商」類型驗證。專門用於透過 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) 按一下以切換來源
取得令牌並取得協商驗證鏈中的下一個令牌。令牌可以 Base64
編碼或不編碼。令牌可以包含「協商」標頭,且會將其移除。不會指出傳回的是 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() 按一下以切換來源
取得初始協商令牌。以適合用於 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() 按一下以切換來源
根據使用者、網域或兩者取得認證。如果兩者皆為 nil,則會發生錯誤
# 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