AD FS を使用した ID 委任のシナリオ

[.NET Framework 4.5 以降、Windows Identity Foundation (WIF) は .NET Framework に完全に統合されています。 このトピックで扱う WIF のバージョンは WIF 3.5 で、これは非推奨とされており、.NET Framework 3.5 SP1 または .NET Framework 4 を前提に開発する場合にのみ使用してください。 .NET Framework 4.5 における WIF (WIF 4.5 とも呼ばれます) の詳細については、.NET Framework 4.5 開発ガイドの Windows Identity Foundation に関するドキュメントを参照してください。]

このシナリオでは、アクセス制御チェックを実行するために ID 委任チェーンが必要なバックエンド リソースにアクセスしなければならないアプリケーションについて説明します。 単純な ID 委任チェーンは通常、最初の呼び出し元に関する情報と、直前の呼び出し元の ID で構成されます。

現在、Windows プラットフォーム上の Kerberos 委任モデルでは、バックエンド リソースは、直前の呼び出し元の ID しかアクセスできず、最初の呼び出し元の ID にはアクセスできません。 このモデルは一般的に、信頼できるサブシステム モデルと呼ばれます。 WIF は、Actor プロパティを使用して、最初の呼び出し元と、委任チェーンにおける直前の呼び出し元の ID を保持します。

次の図は、Fabrikam の従業員が Contoso.com アプリケーションで公開されているリソースにアクセスする一般的な ID 委任シナリオを示しています。

Identity

このシナリオに登場する架空のユーザーは次のとおりです。

  • Frank: Contoso のリソースにアクセスしようとしている Fabrikam の従業員。
  • Daniel: 必要な変更をアプリケーションに実装する Contoso アプリケーション開発者。
  • Adam: Contoso IT 管理者。

このシナリオに関連するコンポーネントは次のとおりです。

  • web1: 最初の呼び出し元の委任された ID を必要とするバックエンド リソースへのリンクが設定されている Web アプリケーション。 このアプリケーションは ASP.NET を使用して構築されます。
  • SQL Server にアクセスする Web サービス。これには、最初の呼び出し元の委任された ID と、直前の呼び出し元の ID が必要です。 このサービスは、WCF を使用して構築されています。
  • sts1: 要求プロバイダーのロールを持つ STS。アプリケーション (web1) で必要とされる要求を生成します。 Fabrikam.com との間、およびアプリケーションとの間に信頼が確立されています。
  • sts2: Fabrikam.com に対する ID プロバイダーのロールに存在する STS。Fabrikam の従業員が認証に使用するエンドポイントを提供します。 Fabrikam の従業員が Contoso.com 上のリソースにアクセスできるように、Contoso.com との間に信頼が確立されています。

注意

このシナリオでよく使用される「ActAs トークン」という用語は、STS によって発行されるトークンを指し、ユーザーの ID が含まれます。 Actor プロパティには、STS の ID が含まれます。

上の図に示すように、このシナリオのフローは次のようになります。

  1. Contoso アプリケーションは、Fabrikam の従業員の ID と、Actor プロパティの直前の呼び出し元の ID の両方を含む ActAs トークンを取得するように構成されています。 Daniel は、この変更をアプリケーションに実装しました。
  2. Contoso アプリケーションは、ActAs トークンをバックエンド サービスに渡すように構成されています。 Daniel は、この変更をアプリケーションに実装しました。
  3. Contoso Web サービスは、sts1 を呼び出して ActAs トークンを検証するように構成されています。 Adam は、委任要求を処理するように sts1 を有効にしました。
  4. Fabrikam ユーザーである Frank は Contoso アプリケーションにアクセスし、バックエンド リソースへのアクセス権を付与されます。

ID プロバイダー (IP) を設定する

Fabrikam.com 管理者の Frank は、次の 3 つのオプションを使用できます。

  1. Active Directory® フェデレーションサービス (AD FS) などの STS 製品を購入してインストールする。
  2. LiveID STS などのクラウド STS 製品をサブスクライブする。
  3. WIF を使用してカスタム STS を構築する。

このサンプル シナリオでは、Frank がオプション 1 を選択し、IP-STS として AD FS をインストールすると想定します。 また、ユーザーを認証するために、\ windowsauth という名前のエンドポイントを構成します。 Frank は、AD FS の製品ドキュメントを参照し、Contoso IT 管理者である Adam と相談して、Contoso.com ドメインとの間に信頼を確立します。

要求プロバイダーを設定する

Contoso.com 管理者である Adam が使用できるオプションは、ID プロバイダーについて前に説明したオプションと同じです。 このサンプル シナリオで、Frank はオプション 1 を選択し、RP-STS として AD FS 2.0 をインストールすると想定します。

IP およびアプリケーションとの間に信頼を設定する

AD FS のドキュメントを参照して、Adam は Fabrikam.com とアプリケーションの間に信頼を確立します。

委任を設定する

AD FS が、委任の処理を提供します。 AD FS のドキュメントを参照して、Adam は ActAs トークンの処理を有効にします。

アプリケーション固有の変更

既存のアプリケーションに ID 委任のサポートを追加するには、次の変更を行う必要があります。 Daniel が、WIF を使用してこれらの変更を行います。

  • Web1 が sts1 から受け取るブートストラップ トークンをキャッシュします。
  • 発行済みトークンと共に CreateChannelActingAs を使用して、バックエンド Web サービスへのチャネルを作成します。
  • バックエンド サービスのメソッドを呼び出します。

ブートストラップ トークンをキャッシュする

ブートストラップ トークンは STS によって発行される最初のトークンであり、アプリケーションはそこから要求を抽出します。 このサンプル シナリオでは、このトークンはユーザー Frank の sts1 によって発行され、アプリケーションによってキャッシュされます。 次のコード サンプルは、ASP.NET アプリケーションでブートストラップ トークンを取得する方法を示しています。

// Get the Bootstrap Token
SecurityToken bootstrapToken = null;

IClaimsPrincipal claimsPrincipal = Thread.CurrentPrincipal as IClaimsPrincipal;
if ( claimsPrincipal != null )
{
    IClaimsIdentity claimsIdentity = (IClaimsIdentity)claimsPrincipal.Identity;
    bootstrapToken = claimsIdentity.BootstrapToken;
}

WIF には、CreateChannelActingAs というメソッドが用意されています。このメソッドは、指定されたセキュリティ トークンを ActAs 要素として使用してトークン発行要求を補強する、指定された種類のチャネルを作成します。 ブートストラップ トークンをこのメソッドに渡すと、返されるチャネルで必要なサービス メソッドを呼び出すことができます。 このサンプル シナリオでは、Frank の ID で Actor プロパティを web1 の ID に設定しています。

次のコード スニペットは、CreateChannelActingAs を使用して Web サービスを呼び出してから、返されたチャネルでサービスのメソッドの 1 つ ComputeResponse を呼び出す方法を示しています。

// Get the channel factory to the backend service from the application state
ChannelFactory<IService2Channel> factory = (ChannelFactory<IService2Channel>)Application[Global.CachedChannelFactory];

// Create and setup channel to talk to the backend service
IService2Channel channel;
lock (factory)
{
// Setup the ActAs to point to the caller's token so that we perform a
// delegated call to the backend service
// on behalf of the original caller.
    channel = factory.CreateChannelActingAs<IService2Channel>(callerToken);
}

string retval = null;

// Call the backend service and handle the possible exceptions
try
{
    retval = channel.ComputeResponse(value);
    channel.Close();
} catch (Exception exception)
{
    StringBuilder sb = new StringBuilder();
    sb.AppendLine("An unexpected exception occurred.");
    sb.AppendLine(exception.StackTrace);
    channel.Abort();
    retval = sb.ToString();
}

Web Service-固有の変更

Web サービスは WCF を使用して構築され、WIF に対して有効になるため、適切な発行者アドレスで IssuedSecurityTokenParameters を使用してバインドを構成すると、ActAs の検証が WIF によって自動的に処理されます。

Web サービスは、アプリケーションで必要な特定のメソッドを公開します。 サービスに特定のコード変更は必要ありません。 次のコード サンプルは、IssuedSecurityTokenParameters を使用した Web サービスの構成を示しています。

// Configure the issued token parameters with the correct settings
IssuedSecurityTokenParameters itp = new IssuedSecurityTokenParameters( "http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV1.1" );
itp.IssuerMetadataAddress = new EndpointAddress( "http://localhost:6000/STS/mex" );
itp.IssuerAddress = new EndpointAddress( "http://localhost:6000/STS" );

// Create the security binding element
SecurityBindingElement sbe = SecurityBindingElement.CreateIssuedTokenForCertificateBindingElement( itp );
sbe.MessageSecurityVersion = MessageSecurityVersion.WSSecurity11WSTrust13WSSecureConversation13WSSecurityPolicy12BasicSecurityProfile10;

// Create the HTTP transport binding element
HttpTransportBindingElement httpBE = new HttpTransportBindingElement();

// Create the custom binding using the prepared binding elements
CustomBinding binding = new CustomBinding( sbe, httpBE );

using ( ServiceHost host = new ServiceHost( typeof( Service2 ), new Uri( "http://localhost:6002/Service2" ) ) )
{
    host.AddServiceEndpoint( typeof( IService2 ), binding, "" );
    host.Credentials.ServiceCertificate.SetCertificate( "CN=localhost", StoreLocation.LocalMachine, StoreName.My );

// Enable metadata generation via HTTP GET
    ServiceMetadataBehavior smb = new ServiceMetadataBehavior();
    smb.HttpGetEnabled = true;
    host.Description.Behaviors.Add( smb );
    host.AddServiceEndpoint( typeof( IMetadataExchange ), MetadataExchangeBindings.CreateMexHttpBinding(), "mex" );

// Configure the service host to use WIF
    ServiceConfiguration configuration = new ServiceConfiguration();
    configuration.IssuerNameRegistry = new TrustedIssuerNameRegistry();

    FederatedServiceCredentials.ConfigureServiceHost( host, configuration );

    host.Open();

    Console.WriteLine( "Service2 started, press ENTER to stop ..." );
    Console.ReadLine();

    host.Close();
}

次の手順

AD FS の開発