共用方式為


如何:透過 OAuth WRAP 通訊協定向 ACS 要求權杖

套用至

  • Microsoft Azure Active Directory 存取控制服務 (也稱為「存取控制服務」或 ACS)

概觀

當您的 Web 應用程式和服務使用 ACS 處理驗證時,用戶端必須取得 ACS 所簽發的安全性權杖,才能登入您的應用程式或服務。 若要 (輸出權杖) 取得此 ACS 發行的權杖,用戶端必須直接向 ACS 進行驗證,或傳送 ACS 由其識別提供者所簽發的安全性權杖, (輸入權杖) 。 ACS 會驗證此輸入安全性權杖、透過 ACS 規則引擎處理此權杖中的身分識別宣告、計算輸出身分識別宣告,以及發出輸出安全性權杖。

本主題描述透過 OAuth WRAP 通訊協定向 ACS 要求權杖的方法。 透過 OAuth WRAP 通訊協定的所有權杖要求都會透過 SSL 傳輸。 ACS 一律會透過 OAuth WRAP 通訊協定發出簡單 Web 權杖 (SWT) ,以回應格式正確的權杖要求。 透過 OAuth WRAP 通訊協定的所有權杖要求都會傳送至 HTTP POST 中的 ACS。 您可以從任何可建立 HTTPS FORM POST 的平臺,透過 OAuth WRAP 通訊協定要求 ACS 權杖:.NET Framework、Windows Communication Foundation (WCF) 、Silverlight、ASP.NET、JAVA、Python、Ruby、PHP、Flash 和其他平臺。

下表列出透過 OAuth WRAP 通訊協定要求 ACS 發行 SWT 權杖的三種支援方法。

透過 OAuth WRAP 通訊協定向 ACS 要求權杖的三種方法

權杖要求方法 描述

密碼權杖要求

這個最簡單的方法需要用戶端透過 OAuth WRAP 通訊協定,將使用者名稱和密碼直接從服務身分識別傳送至 ACS 以進行驗證。

SWT 權杖要求

此方法需要用戶端傳送 SWT 權杖,此權杖可以使用服務識別對稱金鑰或識別提供者對稱金鑰簽署至 ACS,透過 OAuth WRAP 通訊協定進行驗證。

SAML 權杖要求

主要用於 Active Directory 同盟服務 (AD FS) 2.0 整合,安全性聲明標記語言 (SAML) 方法需要用戶端透過 OAuth WRAP 通訊協定將已簽署的 SAML 權杖傳送至 ACS 以進行驗證。 此方法可讓用戶端使用企業身分識別向 ACS 進行驗證。

權杖簽發端點

透過 OAuth WRAP 通訊協定的所有 ACS 權杖要求都會導向 ACS 權杖發行端點。 此端點的 URI 取決於存取控制命名空間。 命名空間會顯示為權杖要求 URI 中的 DNS 名稱前置詞。 DNS 名稱的其餘部分是固定的,與路徑相同。 例如,如果您想要從名為 「mysnservice」 的存取控制命名空間要求權杖,您可以將權杖要求導向至下列 URI: https://mysnservice.accesscontrol.windows.net/WRAPv0.9

密碼權杖要求

透過密碼權杖要求,用戶端可以直接透過 OAuth WRAP 通訊協定,將使用者名稱和密碼從服務身分識別傳送至 ACS 以進行驗證。 這是使用 OAuth WRAP 通訊協定向 ACS 要求權杖的最簡單方式。 除了建立 SSL 連線以外,此方法並不需要任何密碼編譯功能。 實際上,此方法很類似 REST Web 服務中相當常用的使用者名稱/密碼模型。 此類型的權杖要求實際上是 HTTPS 表單 POST。 密碼權杖要求中的參數是以表單編碼的。

下列範例說明對命名空間 “mysnservice” 之純文字要求的網路追蹤。

POST /WRAPv0.9/ HTTP/1.1
Host: mysnservice.accesscontrol.windows.net
Content-Type: application/x-www-form-urlencoded

wrap_scope=http%3A%2F%2Fmysnservice.com%2Fservices%2F&
wrap_name=mysncustomer1&
wrap_password=5znwNTZDYC39dqhFOTDtnaikd1hiuRa4XaAj3Y9kJhQ%3D

下表列出必須存在於密碼權杖要求中之參數的名稱、說明和值需求:

參數名稱 描述 值需求

wrap_scope

根據一組規則比對權杖要求。 請將此參數的值設為信賴憑證者應用程式領域的值。 您可以從 [信賴憑證者應用程式] 頁面選取適當的信賴憑證者應用程式,以透過 ACS 管理入口網站,在 [領域] 欄位中取得此值) (。

  • HTTP 或 HTTP(S) URI

  • 沒有查詢參數或錨點。

  • 路徑區段 < = 32。

  • 最大長度:256 個字元。

  • 必須以 URL 編碼。

wrap_name

驗證下一個參數的金鑰。 將此參數的值設定為存取控制命名空間內的服務識別名稱。 您可以從 [服務識別] 頁面選取適當的服務識別,以在 [名稱] 欄位中取得 (此值) ) 。

  • 長度下限:1 個字元。

  • 最大長度:128 個字元。

  • 必須以 URL 編碼。

wrap_password

驗證內送要求。 將此參數的值設定為存取控制命名空間內服務識別的密碼。 您可以透過 ACS 管理入口網站,在 [編輯認證] 頁面) 的 [密碼] 欄位中取得此值 (,方法是先在 [服務識別] 頁面上選取適當的服務識別,然後在 [編輯服務識別] 頁面上的 [認證] 資料表中選取適當的密碼。

  • 長度介於 1 到 64 個字元之間的字串。

  • 必須以 URL 編碼。

這些參數的值必須經過 URL 編碼,才能將要求傳送至 ACS。 您的 Web 應用程式或服務可以提供 用戶端wrap_scope 的值,或者用戶端可以決定將 wrap_scope 參數的值設定為 Web 應用程式或服務資源目標的 URI。

透過 OAuth WRAP 通訊協定的密碼權杖要求也可以包含 ACS 可在輸出宣告計算程式期間使用的其他參數。 這些參數的名稱和值必須以 URL 編碼,且值不可加上引號。

透過 可以輕鬆地使用密碼權杖要求方法。

WebClient client = new WebClient();
client.BaseAddress = string.Format("https://mysnservice.accesscontrol.windows.net");

NameValueCollection values = new NameValueCollection();
values.Add("wrap_name", "mysncustomer1");
values.Add("wrap_password", "5znwNTZDYC39dqhFOTDtnaikd1hiuRa4XaAj3Y9kJhQ=");
values.Add("wrap_scope", "http://mysnservice.com/services");

// WebClient takes care of the URL Encoding
byte[] responseBytes = client.UploadValues("WRAPv0.9", "POST", values);

// the raw response from ACS
string response = Encoding.UTF8.GetString(responseBytes);

如需如何從 ACS 解除封裝輸出權杖並將其傳送至 Web 應用程式或服務的相關資訊,請參閱解除包裝並將權杖傳送至 Web 應用程式或服務。

SWT 權杖要求

您也可以使用對稱金鑰簽署的 SWT 權杖,透過 OAuth WRAP 通訊協定向 ACS 要求權杖。 所有 SWT 權杖要求都是透過 HTTPS 表單 POST 執行的。 此權杖要求方法中的參數值是以表單編碼的。

下列範例說明對 “mysnservice” 命名空間之 SWT 權杖要求的網路追蹤。

POST /WRAPv0.9/ HTTP/1.1
Host: mysnservice.accesscontrol.windows.net
Content-Type: application/x-www-form-urlencoded

wrap_scope=http%3A%2F%2Fmysnservice.com%2Fservices%2F&
wrap_assertion_format=SWT&
wrap_assertion=Issuer%3dmysncustomer1%26HMACSHA256%3db%252f%252bJFwbngGdufECFjQb8qhb9YH0e32Cf9ABMDZFiPPA%253d

SWT 權杖要求必須有下列參數和值:

參數名稱 描述 值需求

wrap_scope

根據一組規則比對權杖要求。

  • 請將此參數的值設為信賴憑證者應用程式領域的值。 您可以從 [信賴憑證者應用程式] 頁面選取適當的信賴憑證者應用程式,以透過 ACS 管理入口網站,在 [領域] 欄位中取得此值) (。

  • HTTP 或 HTTP(S) URI。

  • 沒有查詢參數或錨點。

  • 路徑區段 < = 32。

  • 最大長度:256 個字元。

  • 必須以 URL 編碼。

wrap_assertion

這是傳送至 ACS 的輸入權杖。

  • 具有輸入宣告的已簽署 SWT 權杖,且宣告中包含簽發者和 HMACSHA256 參數。

  • 最大長度:2048 個字元。

  • 必須以 URL 編碼。

wrap_assertion_format

這是傳送至 ACS 的輸入權杖格式。

SWT

下列範例所示,發出 SWT 權杖要求所需的程式碼,類似於發出密碼權杖要求所需的程式碼。

WebClient client = new WebClient();
client.BaseAddress = string.Format("https://mysnservice.accesscontrol.windows.net");

NameValueCollection values = new NameValueCollection();
// add the wrap_scope
values.Add("wrap_scope", "http://mysnservice.com/services");
// add the format
values.Add("wrap_assertion_format", "SWT");
// add the SWT
values.Add("wrap_assertion", "Issuer=mysncustomer1&HMACSHA256=b%2f%2bJFwbngGdufECFjQb8qhb9YH0e32Cf9ABMDZFiPPA%3d");
// WebClient takes care of the remaining URL Encoding
byte[] responseBytes = client.UploadValues("WRAPv0.9", "POST", values);

// the raw response from ACS
string response = Encoding.UTF8.GetString(responseBytes);

如需如何解除封裝 ACS 回應並將其傳送至 Web 應用程式或服務的相關資訊,請參閱解除包裝權杖並將其傳送至 Web 應用程式或服務。

建立 SWT 權杖

SWT 權杖是一組使用簽發者金鑰 (對稱金鑰) 進行簽署的金鑰/值組。 在 SWT 權杖要求中傳送至 ACS 的 SWT 權杖必須包含 簽發者和HMACSHA256 參數,以及其他參數,例如 ExpiresOnAudience和其他用戶端特定宣告。 下表提供 SWT 權杖參數的名稱與描述:

參數名稱 描述

Issuer

在 ACS 中,查閱用來簽署權杖的金鑰。 如果簽章有效,則會使用此值執行輸出宣告計算。

您可以將此參數設定為存取控制命名空間內識別提供者領域的值,或存取控制命名空間內服務識別的名稱。 您可以透過 ACS 管理入口網站,在 [編輯識別提供者] 頁面) 的 [領域] 欄位中取得此值 (,方法是在 [識別提供者] 頁面上選取適當的識別提供者。 或者,您可以透過 ACS 管理服務取得此值 – 這是為每個識別提供者建立的「簽發者」記錄名稱屬性。

HMACSHA256

在 ACS 中,驗證 SWT 簽章,並在 Issuer 參數中查閱名為 的 簽發者 金鑰。

SWT 簽章是使用附加至服務識別的對稱簽署金鑰,或您存取控制命名空間內的識別提供者來建立。

目標對象

如果存在,ACS 會使用此值來確保 ACS 是 SWT 權杖的預期目標。 這是存取控制命名空間的 URL,例如https://contoso.accesscontrol.windows.net/

ExpiresOn

如果存在 (在 Epoch 時間),會指出權杖是否過期。 例如,此參數的值可以是 1324300962

其他宣告

如果有的話,ACS 會使用這些參數來執行輸出宣告計算。 每個宣告類型都只能出現一次。 相同宣告類型的多個宣告值必須以 "," (逗號) 字元串連在一起。 如需有關在 ACS 中判斷提示宣告的詳細資訊,請參閱透過 OAuth WRAP 通訊協定的宣告判斷提示。

下列程式碼範例說明如何使用 產生 SWT 權杖。 其中包含的類型,會建置含有 IssuerHMACSHA256 參數的 SWT 權杖。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Web;

public class TokenFactory
{
    string signingKey;   
    string issuer;
    
    public TokenFactory(string issuer, string signingKey)
    {
        this.issuer = issuer;
        this.signingKey = signingKey;
    }

    public string CreateToken()
    {
        StringBuilder builder = new StringBuilder();

        // add the issuer name
        builder.Append("Issuer=");
        builder.Append(HttpUtility.UrlEncode(this.issuer));

        string signature = this.GenerateSignature(builder.ToString(), this.signingKey);
        builder.Append("&HMACSHA256=");
        builder.Append(signature);

        return builder.ToString();
    }

   
    private string GenerateSignature(string unsignedToken, string signingKey)
    {
        HMACSHA256 hmac = new HMACSHA256(Convert.FromBase64String(signingKey));

        byte[] locallyGeneratedSignatureInBytes = hmac.ComputeHash(Encoding.ASCII.GetBytes(unsignedToken));

        string locallyGeneratedSignature = HttpUtility.UrlEncode(Convert.ToBase64String(locallyGeneratedSignatureInBytes));

        return locallyGeneratedSignature;
    }
}

SAML 權杖要求

SAML 權杖要求方法主要用於 AD FS 2.0 整合,並允許用戶端使用企業身分識別 (Active Directory) 向 ACS 進行驗證。 使用 SAML 權杖要求方法,您可以透過 OAuth WRAP 通訊協定將已簽署的 SAML 1.1 或 AD FS 2.0 所發行的 SAML 2.0 權杖傳送至 ACS (輸入權杖) 。

ACS 會使用其規則來計算輸出宣告、將宣告分組為 SWT 權杖 (輸出權杖)、加以簽署,然後透過 OAuth WRAP 通訊協定將其傳回至用戶端。

SAML 權杖要求必須有下列參數和值:

參數名稱 描述 值需求

wrap_scope

根據一組規則比對權杖要求。

  • 請將此參數的值設為信賴憑證者應用程式領域的值。 您可以從 [信賴憑證者應用程式] 頁面選取適當的信賴憑證者應用程式,以透過 ACS 管理入口網站,在 [領域] 欄位中取得此值) (。

  • HTTP 或 HTTP(S) URI。

  • 沒有查詢參數或錨點。

  • 路徑區段 < = 32。

  • 最大長度:256 個字元。

  • 必須以 URL 編碼。

wrap_assertion

這是傳送至 ACS 的輸入權杖。

  • 具有輸入宣告的已簽署 SAML 1.1 或 2.0 權杖。 根據權杖限制,SAML 1.1 權杖至少要有一個輸入宣告。 這表示在驗證 SAML 1.1 權杖時,必須使用身分識別提供者或已啟用宣告的服務身分識別。 除了隱含的 NameIdentifier 宣告以外,SAML 2.0 權杖並不需要任何輸入宣告即可對服務身分識別進行驗證,因此,SAML 2.0 權杖可以用來對未啟用宣告的一般服務身分識別進行驗證。

  • 必須以 URL 編碼。

wrap_assertion_format

這是傳送至 ACS 的輸入權杖格式。

SAML

以下是執行 SAML 權杖要求時所需之程式碼的範例。

private static string SendSAMLTokenToACS(string samlToken)
{
 try
 {
  WebClient client = new WebClient();
  client.BaseAddress = string.Format("https://mysnservice.accesscontrol.windows.net");
  NameValueCollection parameters = new NameValueCollection();
  parameters.Add("wrap_assertion_format", "SAML");
  parameters.Add("wrap_assertion", samlToken);
  parameters.Add("wrap_scope", "http://mysnservice.com/services");

  byte[] responseBytes = client.UploadValues("WRAPv0.9", parameters);
  string response = Encoding.UTF8.GetString(responseBytes);

  return response
   .Split('&')
   .Single(value => value.StartsWith("wrap_access_token=", StringComparison.OrdinalIgnoreCase))
   .Split('=')[1];
 }
 catch (WebException wex)
 {
  string value = new StreamReader(wex.Response.GetResponseStream()).ReadToEnd();
  throw;
 }
}  

如需如何解除封裝 ACS 回應並將其傳送至 Web 應用程式或服務的相關資訊,請參閱解除包裝權杖並將其傳送至 Web 應用程式或服務。

透過 OAuth WRAP 通訊協定的宣告判斷提示

為了啟用與 ACS 1.0 權杖要求行為的回溯相容性,ACS 支援判斷宣告為權杖要求的一部分。

將判斷提示應用程式或服務註冊為 ACS 身分識別提供者。

若要這麼做,建議的方式是將判斷提示應用程式或服務註冊為 ACS 身分識別提供者。 然後,應用程式或服務會藉由呈現 SAML 或 SWT 權杖,其中包含其想要判斷提示的宣告,並使用儲存在 ACS 中的識別提供者金鑰來簽署此權杖。 例如,您可以透過來自 AD FS 2.0 的 OAuth WRAP 通訊協定,或任何使用 Windows Identity Foundation (WIF) ,並在 ACS 中註冊為WS-Federation識別提供者建置的自訂安全性權杖) (服務,將 SAML 權杖要求傳送至 ACS。

您可以使用 ACS 管理入口網站,使用WS-Federation中繼資料來註冊識別提供者,也可以使用 ACS 管理服務個別設定識別提供者屬性、位址和金鑰。 (例如,請參閱如何:使用 ACS 管理服務將 AD FS 2.0 設定為Enterprise識別提供者.) 使用此方法在權杖要求中判斷提示宣告時不需要服務身分識別。 此方法可透過所有 ACS 支援的通訊協定運作。

解除包裝權杖並將其傳送至 Web 應用程式或服務

如果權杖要求已成功驗證,ACS 會傳回兩個表單編碼的參數: wrap_tokenwrap_token_expires_in。 這些參數的值分別是用戶端可用來存取您的 Web 應用程式或服務的實際 SWT 權杖,以及此權杖約略估算的剩餘存留期 (以秒為單位)。

將 SWT 權杖傳送至 Web 應用程式或服務之前,用戶端必須從 ACS 回應擷取和 URL 解碼。 如果 Web 應用程式或服務需要將權杖顯示在 HTTP Authorization 標頭中,此權杖前面必須加上配置 WRAPv0.9

下列程式碼範例說明如何解除封裝權杖以及格式化 Authorization 標頭。

WebClient client = new WebClient();
client.BaseAddress = string.Format("https://mysnservice.accesscontrol.windows.net");

NameValueCollection values = new NameValueCollection();
values.Add("wrap_name", "mysncustomer1");
values.Add("wrap_password", "5znwNTZDYC39dqhFOTDtnaikd1hiuRa4XaAj3Y9kJhQ=");
values.Add("wrap_scope", "http://mysnservice.com/services");

// WebClient takes care of the URL Encoding
byte[] responseBytes = client.UploadValues("WRAPv0.9", "POST", values);

// the raw response from ACS
string response = Encoding.UTF8.GetString(responseBytes);

string token = response
    .Split('&')
    .Single(value => value.StartsWith("wrap_token=", StringComparison.OrdinalIgnoreCase))
    .Split('=')[1];

string.Format("WRAP access_token=\"{0}\"", HttpUtility.UrlDecode(token));

ACS 錯誤碼與描述

ACS 在無法滿足權杖要求時傳回錯誤。 依據 REST 設計,錯誤會包含 HTTP 回應碼。 在許多情況下,ACS 錯誤也包含 , SubCode 並提供 Detail 失敗內容。 錯誤格式為:Error:Code: < HTTPStatus > :Sub-Code: < code > :D etail: < message > 。 錯誤的 Content-Type 一律為文字/純文字。

HTTP/1.1 401 Access Forbidden
Content-Type: text/plain; charset=us-ascii

Error:Code:401:SubCode:T0:Detail:ACS50009: SWT token is invalid. :TraceID:<trace id value>:TimeStamp:<timestamp value>

如需 ACS 錯誤碼的詳細資訊,請參閱 ACS 錯誤碼

偵錯或從 ACS 傳回的錯誤復原時,通常需要讀取回應本文。 下列程式碼範例示範如何從 WebException 物件讀取錯誤訊息。

try
{
    WebClient client = new WebClient();
    client.BaseAddress = string.Format("https://mysnservice.accesscontrol.windows.net");

    NameValueCollection values = new NameValueCollection();
    values.Add("wrap_name", "mysncustomer1");
    values.Add("wrap_password", "5znwNTZDYC39dqhFOTDtnaikd1hiuRa4XaAj3Y9kJhQ=");
    values.Add("wrap_scope", "http://mysnservice.com/services");

    // WebClient takes care of the URL Encoding
    byte[] responseBytes = client.UploadValues("WRAPv0.9", "POST", values);

    // the raw response from ACS
    string response = Encoding.UTF8.GetString(responseBytes);

    string token = response
        .Split('&')
        .Single(value => value.StartsWith("wrap_access_token=",       StringComparison.OrdinalIgnoreCase))
        .Split('=')[1];
}
catch (WebException wex)
{
    if (wex.Response != null)
    {
        // the response Stream contains the error message
        StreamReader reader = new StreamReader(wex.Response.GetResponseStream());
        string message = reader.ReadToEnd();
    }
    // Throw as appropriate
}

另請參閱

概念

ACS 的作法