InitializeSecurityCoNtext (安全通道) 函式

InitializeSecurityCoNtext (Schannel) 函式會從認證控制碼起始用戶端的輸出安全性內容。 函式可用來建置用戶端應用程式與遠端對等之間的 安全性內容InitializeSecurityCoNtext (安全通道) 傳回用戶端必須傳遞至遠端對等的權杖,而對等接著會透過 AcceptSecurityCoNtext (Schannel) 呼叫提交至本機安全性實作。 所有呼叫端都應該將產生的權杖視為不透明。

一般而言,在建立足夠的安全性內容之前,會在迴圈中呼叫InitializeSecurityCoNtext (Schannel) 函式。

語法

SECURITY_STATUS SEC_Entry InitializeSecurityContext(
  _In_opt_    PCredHandle    phCredential,
  _In_opt_    PCtxtHandle    phContext,
  _In_opt_    SEC_CHAR       *pszTargetName,
  _In_        ULONG          fContextReq,
  _In_        ULONG          Reserved1,
  _In_        ULONG          TargetDataRep,
  _In_opt_    PSecBufferDesc pInput,
  _In_        ULONG          Reserved2,
  _Inout_opt_ PCtxtHandle    phNewContext,
  _Inout_opt_ PSecBufferDesc pOutput,
  _Out_       PULONG         pfContextAttr,
  _Out_opt_   PTimeStamp     ptsExpiry
);

參數

phCredential[in, optional]

AcquireCredentialsHandle (Schannel) 所傳回之認證的控制碼。 此控制碼是用來建置 安全性內容InitializeSecurityCoNtext (安全通道) 函式至少需要第一次呼叫的輸出認證。 在後續呼叫時,這可以是 NULL

phCoNtext[in, optional]

CtxtHandle結構的指標。 在第一次呼叫 InitializeSecurityCoNtext (Schannel) 時,此指標為 NULL 。 未來呼叫時,此參數是這個函式第一次呼叫 phNewCoNtext 參數中所傳回部分形式內容的控制碼指標。

警告

請勿在 並行呼叫 InitializeSecurityCoNtext (安全通道) 中使用相同的內容控制碼。 安全性服務提供者中的 API 實作不是安全線程。

pszTargetName[in, optional]

可唯一識別目標伺服器的 Null 終止字串指標。 安全通道會使用此值來驗證伺服器憑證。 Schannel 也會使用此值在重新建立連線時,在會話快取中找出會話。 只有在符合下列所有條件時,才會使用快取會話:

  • 目標名稱相同。
  • 快取專案尚未過期。
  • 呼叫函式的應用程式進程相同。
  • 登入會話相同。
  • 認證控制碼相同。

fCoNtextReq[in]

指出內容要求的位旗標。 並非所有套件都支援所有需求。 用於此參數的旗標前面會加上 ISC_REQ_,例如,ISC_REQ_DELEGATE。 此參數可以是下列一或多個屬性旗標。

意義
ISC_REQ_ALLOCATE_MEMORY 安全性套件會為您配置輸出緩衝區。 當您完成使用輸出緩衝區時,請呼叫 FreeCoNtextBuffer 函 式來釋放它們。
ISC_REQ_CONFIDENTIALITY 使用 EncryptMessage 函式加密訊息。
ISC_REQ_CONNECTION 安全性內容不會處理格式化訊息。
ISC_REQ_EXTENDED_ERROR 發生錯誤時,將會通知遠端合作物件。
ISC_REQ_INTEGRITY 使用 EncryptMessageMakeSignature 函式簽署訊息並驗證簽章。
ISC_REQ_MANUAL_CRED_VALIDATION 安全通道不得自動驗證服務器。
ISC_REQ_MUTUAL_AUTH 將會滿足服務的相互驗證原則。
謹慎: 這不一定表示會執行相互驗證,只會滿足服務的驗證原則。 若要確保執行相互驗證,請呼叫 QueryCoNtextAttributes (Schannel) 函式。
ISC_REQ_REPLAY_DETECT 偵測已使用 EncryptMessageMakeSignature 函式編碼的重新執行訊息。
ISC_REQ_SEQUENCE_DETECT 偵測序列外收到的訊息。
ISC_REQ_STREAM 支援資料流程導向連線。
ISC_REQ_USE_SUPPLIED_CREDS 安全通道不得嘗試自動提供用戶端的認證。

用戶端可能不支援要求的屬性。 如需詳細資訊,請參閱 pfCoNtextAttr 參數。

如需各種屬性的進一步描述,請參閱 內容需求

Reserved1[in]

此參數是保留的,而且必須設定為零。

TargetDataRep[in]

此參數不會與安全通道搭配使用。 將它設定為零。

pInput[in, optional]

SecBufferDesc結構的指標,其中包含提供做為封裝輸入之緩衝區的指標。 除非用戶端內容是由伺服器起始,否則此參數的值必須在 NULL 第一次呼叫函式時。 在後續呼叫函式或伺服器起始用戶端內容時,此參數的值是配置足夠的記憶體來保存遠端電腦所傳回之權杖的緩衝區指標。

在初始呼叫之後呼叫此函式時,必須有兩個緩衝區。 第一個具有類型 SECBUFFER_TOKEN ,且包含從伺服器收到的權杖。 第二個緩衝區的類型 為 SECBUFFER_EMPTY;將 pvBuffercbBuffer 成員都設定為零。

Reserved2[in]

此參數是保留的,而且必須設定為零。

phNewCoNtext[in, out, optional]

CtxtHandle結構的指標。 在第一次呼叫 InitializeSecurityCoNtext (Schannel) 時,此指標會收到新的內容控制碼。 第二次呼叫 時,phNewCoNtext 可以與 phCoNtext 參數中指定的控制碼相同。 phNewCoNtext 不應該是 NULL

pOutput[in, out, optional]

SecBufferDesc結構的指標,其中包含接收輸出資料的SecBuffer結構指標。 如果緩衝區在輸入中輸入為SEC_READWRITE,則會在輸出中。 如果透過ISC_REQ_ALLOCATE_MEMORY) 要求 (,系統會配置安全性權杖的緩衝區,並在安全性權杖的緩衝區描述元中填入位址。

如果指定ISC_REQ_ALLOCATE_MEMORY旗標,Schannel SSP 會配置緩衝區的記憶體,並將適當的資訊放在 SecBufferDesc中。 此外,呼叫端必須傳入類型 為 SECBUFFER_ALERT的緩衝區。 在輸出中,如果產生警示,此緩衝區會包含該警示的相關資訊,且函式會失敗。

pfCoNtextAttr[out]

要接收一組位旗標的變數指標,表示已建立內容 的屬性 。 如需各種屬性的描述,請參閱 內容需求

用於此參數的旗標前面會加上 ISC_RET,例如 ISC_RET_DELEGATE。 如需有效值的清單,請參閱 fCoNtextReq 參數。

在最終函式呼叫成功傳回之前,請勿檢查安全性相關屬性。 屬性旗標與安全性無關,例如ASC_RET_ALLOCATED_MEMORY旗標,可以在最終傳回之前檢查。

注意

特定內容屬性可以在與遠端對等交涉期間變更。

ptsExpiry[out, optional]

接收內容到期時間之 TimeStamp 結構的指標。 建議 安全性套件 一律在本機時間傳回此值。 此參數是選擇性的, NULL 應該針對短期用戶端傳遞。

傳回值

如果函式成功,函式會傳回下列其中一個成功碼。

傳回碼 描述
SEC_I_COMPLETE_AND_CONTINUE 用戶端必須呼叫 CompleteAuthToken ,然後將輸出傳遞至伺服器。 用戶端接著會等候傳回的權杖,並在另一個呼叫中將它傳遞至 InitializeSecurityCoNtext (Schannel)
SEC_I_COMPLETE_NEEDED 用戶端必須完成建置訊息,然後呼叫 CompleteAuthToken 函式。
SEC_I_CONTINUE_NEEDED 用戶端必須將輸出權杖傳送至伺服器,並等候傳回權杖。 傳回的權杖接著會傳入另一個對 InitializeSecurityCoNtext 的呼叫, (Schannel) 。 輸出權杖可以是空的。
SEC_I_INCOMPLETE_CREDENTIALS 伺服器已要求用戶端驗證,且提供的認證不包含憑證,或憑證授權單位單位未核發憑證, (CA) 由伺服器信任的憑證。 如需詳細資訊,請參閱<備註>。
SEC_E_INCOMPLETE_MESSAGE 整個訊息的資料未從網路讀取。
傳回這個值時,pInput緩衝區包含具有 bufferType成員的SecBuffer結構SECBUFFER_MISSINGSecBuffercbBuffer成員包含值,指出函式在函式成功之前,必須從用戶端讀取的額外位元組數目。 雖然這個數位不一定正確,但使用它可藉由避免多次呼叫此函式來協助改善效能。
SEC_E_OK 安全性 內容 已成功初始化。 不需要另一個 InitializeSecurityCoNtext (Schannel) 呼叫。 如果函式傳回輸出權杖,也就是說,如果 pOutput 中的SECBUFFER_TOKEN為非零長度,則必須將該權杖傳送至伺服器。

如果函式失敗,函式會傳回下列其中一個錯誤碼。

傳回碼 描述
SEC_E_INSUFFICIENT_MEMORY 記憶體不足,無法完成要求的動作。
SEC_E_INTERNAL_ERROR 未對應至 SSPI 錯誤碼的錯誤。
SEC_E_INVALID_HANDLE 傳遞至函式的控制碼無效。
SEC_E_INVALID_TOKEN 錯誤是因為格式不正確的輸入權杖,例如傳輸中損毀的權杖、大小不正確的權杖,或傳遞至錯誤 限制委派的權杖。 如果用戶端和伺服器未交涉適當的 限制委派,則可能會將權杖傳遞至錯誤的套件。
SEC_E_LOGON_DENIED 登入失敗。
SEC_E_NO_AUTHENTICATING_AUTHORITY 無法連絡授權單位以進行驗證。 驗證物件的功能變數名稱可能錯誤、無法連線到網域,或可能有信任關係失敗。
SEC_E_NO_CREDENTIALS 限制委派中沒有可用的認證。
SEC_E_TARGET_UNKNOWN 無法辨識目標。
SEC_E_UNSUPPORTED_FUNCTION 在 fCoNtextReq參數中指定了無效 (ISC_REQ_DELEGATE或ISC_REQ_PROMPT_FOR_CREDS) 的內容屬性旗標。
SEC_E_WRONG_PRINCIPAL 接收驗證要求的主體與傳入 pszTargetName 參數的主體不同。 這表示相互驗證失敗。
SEC_E_APPLICATION_PROTOCOL_MISMATCH 用戶端與伺服器之間沒有常見的應用程式通訊協定。

備註

呼叫端負責判斷最終內容屬性是否足夠。 例如,如果要求機密性,但無法建立,某些應用程式可能會選擇立即關閉連線。

如果 安全性內容 的屬性不足,用戶端必須藉由呼叫 DeleteSecurityCoNtext 函式釋放部分建立的內容。

用戶端會使用 InitializeSecurityCoNtext (Schannel) 函式來初始化輸出內容。

針對雙腳 安全性內容,呼叫順序如下所示:

  1. 用戶端會呼叫已設定 NULL為 phCoNtext的函式,並使用輸入訊息填入緩衝區描述元。
  2. 安全性套件會檢查參數,並建構不透明的權杖,並將它放在緩衝區陣列的 TOKEN 元素中。 如果 fCoNtextReq 參數包含ISC_REQ_ALLOCATE_MEMORY旗標, 安全性套件 會配置記憶體,並傳回 TOKEN 元素中的指標。
  3. 用戶端會將 pOutput 緩衝區中傳回的權杖傳送至目標伺服器。 然後,伺服器會在呼叫 AcceptSecurityCoNtext (Schannel) 函式中傳遞權杖作為輸入引數。
  4. AcceptSecurityCoNtext (Schannel) 可能會傳回權杖,如果第一次呼叫傳回SEC_I_CONTINUE_NEEDED,伺服器會傳送至用戶端,以進行 InitializeSecurityCoNtext (Schannel ) 。

針對多回合 安全性內容,例如相互驗證,呼叫順序如下所示:

  1. 如先前所述,用戶端會呼叫 函式,但封裝會傳回SEC_I_CONTINUE_NEEDED成功碼。
  2. 用戶端會將輸出權杖傳送至伺服器,並等候伺服器的回復。
  3. 收到伺服器的回應時,用戶端會再次呼叫 InitializeSecurityCoNtext (Schannel) 並將 phCoNtext 設定為上一次呼叫所傳回的控制碼。 從伺服器收到的權杖會在 pInput 參數中提供。
  4. 請勿在同時呼叫InitializeSecurityCoNtext 時使用 phCoNtext 值, (Schannel) 安全性提供者中的實作不是安全線程。

如果伺服器已成功回應, 安全性套件 會傳回SEC_E_OK並建立安全會話。

如果函式傳回其中一個錯誤回應,則不接受伺服器的回應,而且不會建立會話。

如果函式傳回SEC_I_CONTINUE_NEEDED、SEC_I_COMPLETE_NEEDED或SEC_I_COMPLETE_AND_CONTINUE,則重複步驟 2 和 3。

若要初始化 安全性內容,可能需要多次呼叫此函式,視基礎驗證機制以及 fCoNtextReq 參數中指定的選項而定。

fCoNtextReqpfCoNtextAttributes參數是代表各種內容屬性的位元遮罩。 如需各種屬性的描述,請參閱 內容需求pfCoNtextAttributes參數在任何成功傳回時都有效,但只有在最終成功傳回時,才應該檢查內容安全性層面的相關旗標。 中繼傳回可以設定,例如ISC_RET_ALLOCATED_MEMORY旗標。

如果已設定ISC_REQ_USE_SUPPLIED_CREDS旗標, 安全性套件 必須在 pInput 輸入緩衝區中尋找SECBUFFER_PKG_PARAMS緩衝區類型。 這不是一般解決方案,但可在適當時允許強式 配對的安全性套件 和應用程式。

如果指定了ISC_REQ_ALLOCATE_MEMORY,呼叫端必須呼叫 FreeCoNtextBuffer 函式來釋放記憶體。

例如,輸入權杖可能是 LAN 管理員的挑戰。 在此情況下,輸出權杖會是挑戰的 NTLM 加密回應。

用戶端所採取的動作取決於此函式的傳回碼。 如果傳回碼SEC_E_OK,就不會有第二個 InitializeSecurityCoNtext (Schannel) 呼叫,而且伺服器不會有任何回應。 如果傳回碼SEC_I_CONTINUE_NEEDED,用戶端會預期伺服器回應權杖,並在第二次呼叫 InitializeSecurityCoNtext (Schannel) 中傳遞權杖。 SEC_I_COMPLETE_NEEDED傳回碼表示用戶端必須完成建置訊息並呼叫 CompleteAuthToken 函式。 SEC_I_COMPLETE_AND_CONTINUE程式碼會併入這兩個動作。

如果 InitializeSecurityCoNtext (Schannel) 在第一個 (或只) 呼叫時傳回成功,則呼叫端最終必須在傳回的控制碼上呼叫 DeleteSecurityCoNtext 函式,即使呼叫在驗證交換的稍後時間失敗也一樣。

用戶端可能會在成功完成之後再次呼叫 InitializeSecurityCoNtext (Schannel) 。 這表示需要重新驗證 的安全性套件

核心模式呼叫端有下列差異:目標名稱是 Unicode 字串,必須使用 VirtualAlloc在虛擬記憶體中配置;它不得從集區配置。 在 pInputpOutput 中傳遞和提供的緩衝區必須位於虛擬記憶體中,而不是在集區中。

如果函式傳回SEC_I_INCOMPLETE_CREDENTIALS,請檢查您是否在認證中指定有效且受信任的憑證。 呼叫 AcquireCredentialsHandle (Schannel) 函式時,會指定憑證。 憑證必須是憑證授權單位單位所發行的用戶端驗證憑證, (CA) 由伺服器信任。 若要取得伺服器信任的 CA 清單,請呼叫 QueryCoNtextAttributes (Schannel) 函式,並指定 SECPKG_ATTR_ISSUER_LIST_EX 屬性。

用戶端應用程式從伺服器信任的 CA 收到驗證憑證之後,應用程式會呼叫 AcquireCredentialsHandle (Schannel) 函式,然後再次呼叫 InitializeSecurityCoNtext (Schannel) ,然後在 phCredential 參數中指定新的認證,以建立新的認證。

規格需求

需求
最低支援的用戶端 Windows 8.1 [僅限傳統型應用程式]
最低支援的伺服器 Windows Server 2012 R2 [僅限傳統型應用程式]
標頭 Sspi.h (包含 Security.h)
程式庫 Secur32.lib
DLL Secur32.dll

另請參閱

SSPI 函式

AcceptSecurityCoNtext (安全通道)

AcquireCredentialsHandle (安全通道)

CompleteAuthToken

DeleteSecurityCoNtext

FreeCoNtextBuffer

SecBuffer

SecBufferDesc