このドキュメントはアーカイブされており、メンテナンスされていません。

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

更新日: 2015年6月

  • 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 プロトコル経由で Simple Web Token (SWT) を発行します。OAuth WRAP プロトコル経由のすべてのトークン要求は HTTP POST で ACS に送信されます。.NET Framework、Windows Communication Foundation (WCF)、Silverlight、ASP.NET、Java、Python、Ruby、PHP、Flash など、HTTPS FORM POST を実行できるあらゆるプラットフォームから、OAuth WRAP プロトコル経由で ACS トークンを要求できます。

次の表に、OAuth WRAP 経由で ACS 発行 SWT トークンを要求するための 3 つの方法を示します。

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

トークンの要求方法 説明

パスワード トークン要求

最も簡単な方法は、クライアントが直接、OAuth WRAP プロトコル経由でサービス ID からユーザー名とパスワードを ACS に送信し、認証することです。

SWT トークン要求

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

SAML トークン要求

主に Active Directory フェデレーション サービス (AD FS) 2.0 の統合のために設計された Security Assertion Markup Language (SAML) 方法では、クライアントは、署名付き SAML トークンを OAuth WRAP プロトコル経由で ACS に送信し、認証します。この手法では、クライアントはエンタープライズ ID を利用し、ACS で認証できます。

OAuth WRAP プロトコル経由のすべての ACS トークン要求は ACS トークン発行エンドポイントに対して行われます。このエンドポイントの URI は アクセス制御名前空間 によって異なります。名前空間はトークン要求 URI に DNS 名のプレフィックスとして表示されます。DNS 名の残りの部分はパスと同様に固定となります。たとえば、アクセス制御名前空間 に「mysnservice」という名前のトークンを要求した場合、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

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

  • 最小長:1 文字。

  • 最大長: 128 文字。

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

wrap_password

受信要求を認証します。このパラメーターの値を アクセス制御名前空間 内のサービス 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 アプリケーションまたはサービスに送信する方法については、「Unwrapping and sending the token to a web application or service」を参照してください。

対称キーで署名された 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 アプリケーションまたはサービスに送信する方法については、「Unwrapping and sending the token to a web application or service」を参照してください。

SWT トークンは、発行者キー (対称キー) で署名されているキー/値ペアのセットです。SWT トークン要求で ACS に送信される SWT トークンには、発行者パラメーターと HMACSHA256 パラメーターと、ExpiresOn対象ユーザー、およびその他のクライアント雇用要求など、追加パラメーターを含める必要があります。SWT トークン パラメーターの名前と説明を次の表に示します。

 

パラメーター名 説明

Issuer

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

このパラメーターは、アクセス制御名前空間 内の ID プロバイダーの領域の値または アクセス制御名前空間 内のサービス ID の名前に設定できます。([ID プロバイダーの編集] ページの [領域] フィールドの) この値は ACS 管理ポータル経由で取得できます。[ID プロバイダー] ページで適切な ID プロバイダーを選択します。あるいは、ACS 管理サービス経由でこの値を取得できます。これは、各 ID プロバイダーに対して作成される「発行者」レコードの name プロパティです。

HMACSHA256

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

SWT 署名は、アクセス制御名前空間 内のサービス ID または ID プロバイダーに添付されている対称署名キーを使用して作成されます。

対象ユーザー

存在する場合、ACS はこの値を使用し、ACS を SWT トークンの対象にします。これは アクセス制御名前空間 の 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 トークン要求方法は主に AD FS 2.0 統合を意図しており、クライアントはエンタープライズ ID (Active Directory) を使用し、ACS で認証します。SAML トークン要求方法では、AD FS 2.0 により発行された署名付き SAML 1.1 または SAML 2.0 トークン (入力トークン) を OAuth WRAP 経由で 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 アプリケーションまたはサービスへのトークン送信」を参照してください。

ACS 1.0 トークン要求の動作との下位互換性を有効にするために、ACS では、トークン要求の一部として要求をアサートできます。

推奨される方法は、アサートするアプリケーションまたはサービスを ACS の ID プロバイダーとして登録することです。アプリケーションまたはサービスは ACS にトークンを要求します。その際、それがアサートする要求を含む SAML または SWT トークンを提示します。このトークンは ACS に保存されている ID プロバイダー キーを利用して署名されます。たとえば、要求がアサートされた SAML トークンを AD FS 2.0 または Windows Identity Foundation (WIF) を利用して構築され、WS フェデレーション ID プロバイダーとして ACS に登録されたカスタムの Security Token Service (STS) から OAuth WRAP プロトコル経由で ACS に送信できます。

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

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

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 は、トークン要求を満たせないときにエラーを返します。REST の設計に合わせて、エラーには HTTP 応答コードが含まれます。多くの場合、ACS エラーには、エラーの状況を説明する SubCodeDetail も含まれます。エラーの形式は、エラー:コード:<http ステータス>:サブコード:<コード>:詳細:<メッセージ> です。エラーの 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
}

関連項目

表示: