Share via


方法: OAuth WRAP プロトコルを使用して ACS からトークンを要求する

適用対象

  • Microsoft Azure Active Directory アクセス制御 (アクセス制御サービスまたは ACS)

概要

Web アプリケーションとサービスが ACS を使用して認証を処理する場合、クライアントは ACS によって発行されたセキュリティ トークンを取得して、アプリケーションまたはサービスにログインする必要があります。 この ACS 発行トークン (出力トークン) を取得するには、クライアントは ACS で直接認証するか、ID プロバイダーによって発行されたセキュリティ トークン (入力トークン) を ACS に送信する必要があります。 ACS は、この入力セキュリティ トークンを検証し、ACS ルール エンジンを介してこのトークン内の ID 要求を処理し、出力 ID 要求を計算し、出力セキュリティ トークンを発行します。

このトピックでは、OAuth WRAP プロトコルを使用して ACS からトークンを要求する方法について説明します。 OAuth WRAP プロトコル経由のすべてのトークン要求は、SSL 経由で送信されます。 ACS は、正しく書式設定されたトークン要求に応答して、OAuth WRAP プロトコルを介して常に簡易 Web トークン (SWT) を発行します。 OAuth WRAP プロトコル経由のすべてのトークン要求は、HTTP POST で ACS に送信されます。 HTTPS FORM POST を作成できる任意のプラットフォーム (.NET Framework、Windows Communication Foundation (WCF)、Silverlight、ASP.NET、Java、Python、Ruby、PHP、Flash などのプラットフォームから、OAuth WRAP プロトコルを介して ACS トークンを要求できます。

次の表に、OAuth WRAP プロトコルを介して ACS によって発行された SWT トークンを要求する 3 つのサポートされる方法を示します。

OAuth WRAP プロトコル経由で ACS からトークンを要求する 3 つの方法

トークンの要求方法 [説明]

パスワード トークン要求

この最も簡単な方法では、認証のために OAuth WRAP プロトコルを使用して、クライアントがサービス ID から ACS に直接ユーザー名とパスワードを送信する必要があります。

SWT トークン要求

この方法では、認証のために OAuth WRAP プロトコルを使用して、サービス ID 対称キーまたは ID プロバイダー対称キーで署名できる SWT トークンをクライアントが ACS に送信する必要があります。

SAML トークン要求

主に Active Directory フェデレーション サービス (AD FS) 2.0 統合を目的としたセキュリティ アサーション マークアップ言語 (SAML) メソッドでは、認証のために OAuth WRAP プロトコルを介して署名済みの SAML トークンを ACS に送信する必要があります。 このアプローチにより、クライアントはエンタープライズ ID を使用して ACS で認証できます。

トークン発行エンドポイント

OAuth WRAP プロトコルを介するすべての ACS トークン要求は、ACS トークン発行エンドポイントに送信されます。 このエンドポイントの URI は、Access Control名前空間によって異なります。 名前空間はトークン要求 URI に DNS 名のプレフィックスとして表示されます。 DNS 名の残りの部分はパスと同様に固定となります。 たとえば、"mysnservice" という名前のAccess Control名前空間からトークンを要求する場合は、トークン要求を次の URI https://mysnservice.accesscontrol.windows.net/WRAPv0.9に送信できます。

パスワード トークン要求

パスワード トークン要求を使用すると、クライアントは、認証のために OAuth WRAP プロトコルを使用して、サービス ID からユーザー名とパスワードを ACS に直接送信できます。 これは、OAuth WRAP プロトコルを使用して ACS からトークンを要求する最も簡単な方法です。 SSL 接続を確立する以外、この手法は暗号化機能を必要としません。 実際には、REST Web サービスで一般的なユーザー名/パスワードのモデルに似ています。 この種類のトークン要求は実際には HTTPS FORM 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

次のパラメーターのキーを検証します。 このパラメーターの値を、Access Control名前空間内のサービス ID の名前に設定します。 [サービス ID] ページから適切なサービス ID を選択することで、ACS 管理ポータルからこの値 ([名前] フィールド) を取得できます。

  • 最小長: 1 文字。

  • 最大長: 128 文字。

  • URL エンコードされている。

wrap_password

受信要求を認証します。 このパラメーターの値を、Access Control名前空間内のサービス ID のパスワードに設定します。 ACS 管理ポータルからこの値 ([資格情報の編集] ページの [パスワード] フィールド) を取得するには、まずサービス ID ページで適切なサービス ID を選択し、[サービス ID の編集] ページの [資格情報] テーブルで適切なパスワード選択します。

  • 文字列、長さが最小 1 文字、最大 64 文字。

  • URL エンコードされている。

これらのパラメーターの値は、ACS に要求を送信する前に URL エンコードする必要があります。 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 FORM 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 に送信される入力トークンです。

  • 入力要求に発行者と HMACSHA256 パラメーターが含まれる署名付き SWT トークンです。

  • 最大長: 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 トークン パラメーターの名前と説明を次の表に示します。

パラメーター名 説明

発行者

ACS で、トークンの署名に使用されたキーを検索します。 署名が有効な場合は、この値は出力要求を計算するために使用されます。

このパラメーターは、Access Control名前空間内の ID プロバイダーの領域の値、またはAccess Control名前空間内のサービス ID の名前に設定できます。 この値は、ACS 管理ポータルを使用して ([ID プロバイダーの編集] ページの [領域] フィールドで) [ID プロバイダー] ページで適切な ID プロバイダーを選択することで取得できます。 または、ACS 管理サービスを使用してこの値を取得することもできます。これは、ID プロバイダーごとに作成される "Issuer" レコードの名前プロパティです。

HMACSHA256

ACS で SWT 署名を検証し、 Issuer パラメーターで指定された発行者キーを検索します。

SWT 署名は、Access Control名前空間内のサービス ID または ID プロバイダーにアタッチされた対称署名キーを使用して作成されます。

対象ユーザー

存在する場合、ACS はこの値を使用して、ACS が SWT トークンの目的のターゲットであることを確認します。 これは、たとえば、Access Control名前空間の URL です。https://contoso.accesscontrol.windows.net/

ExpiresOn

(エポック時間に) 存在する場合、トークンの有効期限が切れているかどうかを示します。 たとえば、このパラメーターの値を 1324300962 に設定できます。

その他の要求

存在する場合、ACS はこれらのパラメーターを使用して出力要求の計算を実行します。 要求タイプはそれぞれ 1 回だけ現れます。 同じ要求タイプの複数の要求値は「,」 (コンマ) 文字で連結する必要があります。 ACS での要求のアサートの詳細については、「OAuth WRAP プロトコルを使用した要求アサーション」を参照してください。

次のコード サンプルは、 を利用して SWT トークンを生成する方法を示しています。 発行者パラメーターと HMACSHA256 パラメーターを含む 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 統合を目的としており、クライアントがエンタープライズ ID (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 トークンは、トークンの制限として、少なくとも 1 つの入力要求を必要とします。 これは、ID プロバイダーまたは要求対応サービス ID のいずれかを SAML 1.1 トークン認証に使用する必要があることを意味します。 SAML 2.0 トークンは、暗黙的 NameIdentifier 要求だけでなく、サービス ID に対する認証に入力要求を必要としません。そのため、SAML 2.0 トークンを使用し、要求対応ではない通常のサービス ID に対して認証できます。

  • 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 ID プロバイダーとして登録します。

推奨される方法は、アサートするアプリケーションまたはサービスを ACS の ID プロバイダーとして登録することです。 次に、アプリケーションまたはサービスは、アサートする要求を含む SAML または SWT トークンを提示して ACS からトークンを要求し、このトークンは ACS に格納されている ID プロバイダー キーを使用して署名されます。 たとえば、AD FS 2.0 から OAuth WRAP プロトコルを使用して、アサートされた要求を含む SAML トークン要求を ACS に送信したり、WINDOWS Identity Foundation (WIF) を使用して構築され、WS-Federation ID プロバイダーとして ACS に登録されているカスタム セキュリティ トークン サービス (STS) を送信したりすることができます。

ACS 管理ポータルを使用して、WS-Federation メタデータを使用して ID プロバイダーを登録することも、ACS 管理サービスを使用して ID プロバイダーのプロパティ、アドレス、キーを個別に設定することもできます。 (たとえば、「方法: ACS 管理サービスを使用して AD FS 2.0 を Enterprise ID プロバイダーとして構成する」を参照してください)。 トークン要求で要求をアサートするこのメソッドではサービス ID は必要ありません。 この方法は、ACS でサポートされているすべてのプロトコルを介して機能します。

ラップの解除と Web アプリケーションまたはサービスへのトークン送信

トークン要求が正常に認証された場合、ACS は 2 つの形式でエンコードされたパラメーター (wrap_tokenwrap_token_expires_in) を返します。 これらのパラメーターの値は実際の SWT トークンです。クライアントはそれを利用し、Web アプリケーションまたはサービスとこのトークンの残り有効時間概算 (秒) にそれぞれアクセスできます。

SWT トークンを Web アプリケーションまたはサービスに送信する前に、クライアントは ACS 応答から SWT トークンを抽出して 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 エラーには失敗した内容に関するコンテキストも含まれていますSubCodeDetail。 エラー形式は、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 の利用方法