フェデレーション
ここでは、フェデレーション セキュリティの概念について簡単に説明します。また、フェデレーション セキュリティ アーキテクチャを展開する際の Windows Communication Foundation (WCF) のサポートについても説明します。フェデレーションのサンプル アプリケーションについては、「フェデレーション サンプル」を参照してください。
フェデレーション セキュリティの定義
フェデレーション セキュリティにより、クライアントがアクセスするサービスと、関連する認証および承認の手順を明確に分離できます。また、フェデレーション セキュリティを使用すると、異なる信頼レルムに属する複数のシステム、ネットワーク、および組織間のコラボレーションが可能になります。
WCF は、フェデレーション セキュリティを使用する分散システムの構築と展開をサポートします。
フェデレーション セキュリティ アーキテクチャの要素
次の表に示すように、フェデレーション セキュリティ アーキテクチャには 3 つの主要な要素があります。
要素 | 説明 |
---|---|
ドメイン/レルム |
セキュリティ管理または信頼の単位。ドメインには通常、1 つの組織が含まれます。 |
フェデレーション |
信頼が確立されたドメインのコレクション。信頼のレベルはさまざまですが、通常は認証レベルが含まれ、ほとんどの場合に承認レベルが含まれます。典型的なフェデレーションには、一連のリソースへの共有アクセスを可能にする信頼を確立した多くの組織が含まれます。 |
STS (セキュリティ トークン サービス) |
セキュリティ トークンを発行する Web サービス。つまり、信頼できる証拠に基づいて、サービスを信頼する任意の相手に対してアサーションを行います。これによりドメイン間における信頼の橋渡しの基礎が形成されます。 |
サンプル シナリオ
フェデレーション セキュリティの例を次の図に示します。
このシナリオでは、A と B の 2 つの組織があります。組織 B には、組織 A の一部のユーザーにとって有用な Web リソース (Web サービス) があります。
注 : |
---|
このセクションでは、"リソース"、"サービス"、および "Web サービス" を相互に置き換え可能な用語として使用します。 |
通常、組織 B は、組織 A のユーザーに対して、サービスにアクセスする前になんらかの有効な形式の認証を行うことを要求します。さらに、組織 B では、当該の特定リソースにアクセスするためにユーザーが承認されることを要求する場合もあります。この問題に対処し、組織 A のユーザーが組織 B のリソースにアクセスできるようにする 1 つの方法として、次のような方法があります。
組織 A のユーザーは、各自の資格情報 (ユーザー名とパスワード) を組織 B に登録します。
組織 A のユーザーがリソースにアクセスするには、リソースにアクセスする前に自分の資格情報を組織 B に提示して認証を受けます。
この方法には、次の 3 つの重大な欠点があります。
組織 B では、ローカル ユーザーの資格情報の管理に加えて、組織 A のユーザーの資格情報の管理も必要になります。
組織 A のユーザーは、組織 A 内のリソースにアクセスするために通常使用する資格情報以外に、別の資格情報セットを保持する (つまり、別のユーザー名とパスワードを覚えておく) 必要があります。通常、これは、複数のサービス サイトで同じユーザー名とパスワードが使用される可能性を高めるため、脆弱なセキュリティ対策と言えます。
組織 B にあるリソースの価値を認識する組織の数が増えても、アーキテクチャを拡張できません。
上記の欠点に対処する別の方法として、フェデレーション セキュリティの使用があります。この方法では、組織 A と組織 B が信頼関係を確立し、セキュリティ トークン サービス (STS: Security Token Service) を使用して、確立された信頼を仲介できるようにします。
フェデレーション セキュリティ アーキテクチャでは、組織 A のユーザーが、組織 B の Web サービスにアクセスする場合に、組織 B の STS から発行された有効なセキュリティ トークンを提示する必要があることを認識しています。この STS が、特定のサービスへのアクセスを認証および承認します。
STS B に接続したユーザーは、STS に関連付けられたポリシーから別のレベルの間接指定を受け取ります。このユーザーは、STS B がセキュリティ トークンを発行する前に、STS A (クライアントの信頼レルム) の有効なセキュリティ トークンを提示しておく必要があります。これは、2 つの組織間で確立された信頼関係から生じた結果であり、組織 B には組織 A のユーザーの ID を管理する必要がないことを意味します。実際には、STS B の issuerAddress と issuerMetadataAddress は、通常 null になります。詳細については、次のトピックを参照してください。、「方法 : ローカル発行者を設定する」を参照してください。この場合、クライアントは STS A を見つけるためにローカル ポリシーを調べます。この構成は、"ホーム レルム フェデレーション" と呼ばれ、STS B は STS A に関する情報を管理する必要がないため、拡張性が高まります。
ユーザーは、組織 A の STS に接続し、組織 A 内の他のリソースにアクセスする際に通常使用する認証資格情報を提示して、セキュリティ トークンを取得します。これにより、ユーザーが複数の資格情報セットを保持する必要があるという問題や、複数のサービス サイトで同じ資格情報セットを使用するという問題が、ある程度解決されます。
STS A からセキュリティ トークンを取得したユーザーは、このトークンを STS B に提示します。組織 B はユーザーの要求の承認手順を進め、独自のセキュリティ トークン セットからユーザーにセキュリティ トークンを発行します。ユーザーは、このトークンを組織 B のリソースに提示し、サービスにアクセスします。
WCF におけるフェデレーション セキュリティのサポート
WCF は、wsFederationHttpBinding elementを使用して、フェデレーション セキュリティ アーキテクチャの展開を設定不要でサポートします。
wsFederationHttpBinding elementは、安全で信頼性が高く相互運用可能なバインディングを提供します。このバインディングでは、要求/応答形式の通信を実現するための基盤となるトランスポート機構として HTTP を使用する必要があり、エンコーディングのワイヤ形式としてテキストと XML を使用します。
フェデレーション セキュリティ シナリオで wsFederationHttpBinding elementを使用する場合、次のセクションで説明するように、論理的に独立した 2 つのフェーズに分けることができます。
第 1 フェーズ : 設計
設計フェーズでは、クライアントは ServiceModel メタデータ ユーティリティ ツール (Svcutil.exe) を使用してサービス エンドポイントが公開するポリシーを読み取り、サービスの認証と承認の要件を収集します。次のフェデレーション セキュリティの通信パターンをクライアントで作成するために、適切なプロキシが構築されます。
クライアント信頼レルムにある STS からセキュリティ トークンを取得する。
サービス信頼レルムにある STS にトークンを提示する。
サービス信頼レルムにある STS からセキュリティ トークンを取得する。
サービスにトークンを提示してサービスにアクセスする。
第 2 フェーズ : 実行時
実行時フェーズでは、クライアントは WCF クライアント クラスのオブジェクトをインスタンス化し、この WCF クライアントを使用して呼び出しを行います。WCF の基盤となるフレームワークにより、フェデレーション セキュリティの通信パターンにおける前述の手順が処理され、クライアントがシームレスにサービスを利用できるようにします。
WCF を使用した実装のサンプル
WCF のネイティブ サポートを使用したフェデレーション セキュリティ アーキテクチャの実装サンプルを次の図に示します。
MyService の例
MyService
サービスは、MyServiceEndpoint
を介して単一のエンドポイントを公開します。このエンドポイントに関連付けられたアドレス、バインディング、およびコントラクトを次の図に示します。
サービス エンドポイント MyServiceEndpoint
は、wsFederationHttpBinding elementを使用し、STS B によって発行された accessAuthorized クレームを含む有効な SAML (Security Assertions Markup Language) トークンを要求します。これは、サービス構成で宣言によって指定されます。
<system.serviceModel>
<services>
<service type="FederationSample.MyService"
behaviorConfiguration='MyServiceBehavior'>
<endpoint address=""
binding=" wsFederationHttpBinding"
bindingConfiguration='MyServiceBinding'
contract="Federation.IMyService" />
</service>
</services>
<bindings>
<wsFederationHttpBinding>
<!-- This is the binding used by MyService. It redirects
clients to STS-B. -->
<binding name='MyServiceBinding'>
<security mode="Message">
<message issuedTokenType=
"http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV1.1">
<issuer address="https://localhost/FederationSample/STS-B/STS.svc" />
<issuerMetadata
address=
"https://localhost/FederationSample/STS-B/STS.svc/mex" />
<requiredClaimTypes>
<add claimType="http://tempuri.org:accessAuthorized" />
</requiredClaimTypes>
</message>
</security>
</binding>
</wsFederationHttpBinding>
</bindings>
<behaviors>
<behavior name='MyServiceBehavior'>
<serviceAuthorization
operationRequirementType="FederationSample.MyServiceOperationRequirement, MyService" />
<serviceCredentials>
<serviceCertificate findValue="CN=FederationSample.com"
x509FindType="FindBySubjectDistinguishedName"
storeLocation='LocalMachine'
storeName='My' />
</serviceCredentials>
</behavior>
</behaviors>
</system.serviceModel>
注 : |
---|
MyService が要求するクレームについては、細かい点に注意が必要です。2 番目の図は、MyService が accessAuthorized クレームを含む SAML トークンを要求していることを示しています。より正確には、これで、MyService が必要とするクレームの種類が指定されます。このクレームの種類の完全修飾名は http://tempuri.org:accessAuthorized (関連する名前空間を含みます) で、この名前がサービス構成ファイルで使用されます。このクレームの値は、このクレームが存在することが示しており、STS B によって true に設定されると想定されます。
|
このポリシーは、MyService
の一部として実装されている MyServiceOperationRequirement
クラスによって実行時に適用されます。
Imports System
Imports System.Collections.Generic
Imports System.IdentityModel.Claims
Imports System.IdentityModel.Policy
Imports System.IdentityModel.Tokens
Imports System.Security.Cryptography.X509Certificates
Imports System.Security.Permissions
Imports System.ServiceModel
Imports System.ServiceModel.Channels
Imports System.ServiceModel.Security.Tokens
Imports System.Text
...
Public Class myServiceAuthorizationManager
Inherits ServiceAuthorizationManager
' Override the CheckAccess method to enforce access control requirements.
Public Overloads Overrides Function CheckAccess(ByVal operationContext As OperationContext) As Boolean
Dim authContext = operationContext.ServiceSecurityContext.AuthorizationContext
If authContext.ClaimSets Is Nothing Then
Return False
End If
If authContext.ClaimSets.Count <> 1 Then
Return False
End If
Dim myClaimSet = authContext.ClaimSets(0)
If Not IssuedBySTS_B(myClaimSet) Then
Return False
End If
If myClaimSet.Count <> 1 Then
Return False
End If
Dim myClaim = myClaimSet(0)
If myClaim.ClaimType = "http://www.tmpuri.org:accessAuthorized" Then
Dim resource = TryCast(myClaim.Resource, String)
If resource Is Nothing Then
Return False
End If
If resource <> "true" Then
Return False
End If
Return True
Else
Return False
End If
End Function
' This helper method checks whether SAML Token was issued by STS-B.
' It compares the Thumbprint Claim of the Issuer against the
' Certificate of STS-B.
Private Function IssuedBySTS_B(ByVal myClaimSet As ClaimSet) As Boolean
Dim issuerClaimSet = myClaimSet.Issuer
If issuerClaimSet Is Nothing Then
Return False
End If
If issuerClaimSet.Count <> 1 Then
Return False
End If
Dim issuerClaim = issuerClaimSet(0)
If issuerClaim.ClaimType <> ClaimTypes.Thumbprint Then
Return False
End If
If issuerClaim.Resource Is Nothing Then
Return False
End If
Dim claimThumbprint() = CType(issuerClaim.Resource, Byte())
' It is assumed that stsB_Certificate is a variable of type
' X509Certificate2 that is initialized with the Certificate of
' STS-B.
Dim stsB_Certificate = GetStsBCertificate()
Dim certThumbprint() = stsB_Certificate.GetCertHash()
If claimThumbprint.Length <> certThumbprint.Length Then
Return False
End If
For i = 0 To claimThumbprint.Length - 1
If claimThumbprint(i) <> certThumbprint(i) Then
Return False
End If
Next i
Return True
End Function
STS B
STS B を次の図に示します。前述のように、セキュリティ トークン サービス (STS) も Web サービスであり、エンドポイントやポリシーなどを関連付けることができます。
STS B は、セキュリティ トークンを要求する際に使用できる STSEndpoint
という単一のエンドポイントを公開します。具体的には、STS B は、accessAuthorized クレームを含む SAML トークンを発行します。このトークンは、サービスにアクセスするために MyService
サービス サイトで提示できます。ただし、STS B は、STS A によって発行された userAuthenticated クレームを含む有効な SAML トークンを提示することをユーザーに要求します。これは、STS 構成で宣言によって指定されます。
<system.serviceModel>
<services>
<service type="FederationSample.STS_B" behaviorConfiguration=
"STS-B_Behavior">
<endpoint address=""
binding="wsFederationHttpBinding"
bindingConfiguration='STS-B_Binding'
contract="FederationSample.ISts" />
</service>
</services>
<bindings>
<wsFederationHttpBinding>
<!-- This is the binding used by STS-B. It redirects clients to
STS-A. -->
<binding name='STS-B_Binding'>
<security mode='Message'>
<message issuedTokenType="http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV1.1">
<issuer address='https://localhost/FederationSample/STS-A/STS.svc' />
<issuerMetadata address='https://localhost/FederationSample/STS-A/STS.svc/mex'/>
<requiredClaimTypes>
<add claimType='http://tempuri.org:userAuthenticated'/>
</requiredClaimTypes>
</message>
</security>
</binding>
</wsFederationHttpBinding>
</bindings>
<behaviors>
<behavior name='STS-B_Behavior'>
<serviceAuthorization operationRequirementType='FederationSample.STS_B_OperationRequirement, STS_B' />
<serviceCredentials>
<serviceCertificate findValue='CN=FederationSample.com'
x509FindType='FindBySubjectDistinguishedName'
storeLocation='LocalMachine'
storeName='My' />
</serviceCredentials>
</behavior>
</behaviors>
</system.serviceModel>
注 : |
---|
この場合も、userAuthenticated クレームは、STS B が必要とするクレームの種類です。このクレームの種類の完全修飾名は http://tempuri.org:userAuthenticated (関連する名前空間を含みます) で、この名前が STS 構成ファイルで使用されます。このクレームの値は、このクレームが存在することを示しており、STS A によって true に設定されると想定されます。
|
STS B の一部として実装されているこのポリシーは、STS_B_OperationRequirement
クラスによって実行時に適用されます。
Public Class STS_B_AuthorizationManager
Inherits ServiceAuthorizationManager
' Override AccessCheck to enforce access control requirements.
Public Overloads Overrides Function CheckAccess(ByVal operationContext As OperationContext) As Boolean
Dim authContext = operationContext.ServiceSecurityContext.AuthorizationContext
If authContext.ClaimSets Is Nothing Then
Return False
End If
If authContext.ClaimSets.Count <> 1 Then
Return False
End If
Dim myClaimSet = authContext.ClaimSets(0)
If Not IssuedBySTS_A(myClaimSet) Then
Return False
End If
If myClaimSet.Count <> 1 Then
Return False
End If
Dim myClaim = myClaimSet(0)
If myClaim.ClaimType = "http://www.tmpuri.org:userAuthenticated" Then
Dim resource = TryCast(myClaim.Resource, String)
If resource Is Nothing Then
Return False
End If
If resource <> "true" Then
Return False
End If
Return True
Else
Return False
End If
End Function
' This helper method checks whether SAML Token was issued by STS-A.
' It compares the Thumbprint Claim of the Issuer against the
' Certificate of STS-A.
Private Function IssuedBySTS_A(ByVal myClaimSet As ClaimSet) As Boolean
Dim issuerClaimSet = myClaimSet.Issuer
If issuerClaimSet Is Nothing Then
Return False
End If
If issuerClaimSet.Count <> 1 Then
Return False
End If
Dim issuerClaim = issuerClaimSet(0)
If issuerClaim.ClaimType <> ClaimTypes.Thumbprint Then
Return False
End If
If issuerClaim.Resource Is Nothing Then
Return False
End If
Dim claimThumbprint() = CType(issuerClaim.Resource, Byte())
' It is assumed that stsA_Certificate is a variable of type X509Certificate2
' that is initialized with the Certificate of STS-A.
Dim stsA_Certificate = GetStsACertificate()
Dim certThumbprint() = stsA_Certificate.GetCertHash()
If claimThumbprint.Length <> certThumbprint.Length Then
Return False
End If
For i = 0 To claimThumbprint.Length - 1
If claimThumbprint(i) <> certThumbprint(i) Then
Return False
End If
Next i
Return True
End Function
アクセス チェックで問題がなければ、STS B は、accessAuthorized
クレームを含む SAML トークンを発行します。
' Create the list of SAML Attributes.
Dim samlAttributes As New List(Of SamlAttribute)()
' Add the accessAuthorized claim.
Dim strList As New List(Of String)()
strList.Add("true")
samlAttributes.Add(New SamlAttribute("http://www.tmpuri.org", "accessAuthorized", strList))
' Create the SAML token with the accessAuthorized claim. It is assumed that
' the method CreateSamlToken() is implemented as part of STS-B.
Dim samlToken = CreateSamlToken(proofToken, _
issuerToken, _
samlConditions, _
samlSubjectNameFormat, _
samlSubjectEmailAddress, _
samlAttributes)
STS A
STS A を次の図に示します。
STS B と同様に、STS A もセキュリティ トークンを発行する Web サービスであり、そのための単一のエンドポイントを公開します。ただし、STS A は別のバインディング (wsHttpBinding) を使用し、emailAddress クレームを含む有効な CardSpace を提示することをユーザーに要求します。応答で、STS A は userAuthenticated クレームを含む SAML トークンを発行します。これは、サービス構成で宣言によって指定されます。
<system.serviceModel>
<services>
<service type="FederationSample.STS_A" behaviorConfiguration="STS-A_Behavior">
<endpoint address=""
binding="wsHttpBinding"
bindingConfiguration="STS-A_Binding"
contract="FederationSample.ISts">
<identity>
<certificateReference findValue="CN=FederationSample.com"
x509FindType="FindBySubjectDistinguishedName"
storeLocation="LocalMachine"
storeName="My" />
</identity>
<endpoint>
</service>
</services>
<bindings>
<wsHttpBinding>
<!-- This is the binding used by STS-A. It requires users to present
a CardSpace. -->
<binding name='STS-A_Binding'>
<security mode='Message'>
<message clientCredentialType="CardSpace" />
</security>
</binding>
</wsHttpBinding>
</bindings>
<behaviors>
<behavior name='STS-A_Behavior'>
<serviceAuthorization operationRequirementType=
"FederationSample.STS_A_OperationRequirement, STS_A" />
<serviceCredentials>
<serviceCertificate findValue="CN=FederationSample.com"
x509FindType='FindBySubjectDistinguishedName'
storeLocation='LocalMachine'
storeName='My' />
</serviceCredentials>
</behavior>
</behaviors>
</system.serviceModel>
STS A の一部として実装されているこのポリシーは、STS_A_OperationRequirement
クラスによって実行時に適用されます。
Public Class STS_A_AuthorizationManager
Inherits ServiceAuthorizationManager
' Override AccessCheck to enforce access control requirements.
Public Overloads Overrides Function CheckAccess(ByVal operationContext As OperationContext) As Boolean
Dim authContext = operationContext.ServiceSecurityContext.AuthorizationContext
If authContext.ClaimSets Is Nothing Then
Return False
End If
If authContext.ClaimSets.Count <> 1 Then
Return False
End If
Dim myClaimSet = authContext.ClaimSets(0)
If myClaimSet.Count <> 1 Then
Return False
End If
Dim myClaim = myClaimSet(0)
If myClaim.ClaimType = "https://schemas.microsoft.com/ws/2005/05/identity/claims:EmailAddress" AndAlso myClaim.Right = Rights.PossessProperty Then
Dim emailAddress = TryCast(myClaim.Resource, String)
If emailAddress Is Nothing Then
Return False
End If
If Not IsValidEmailAddress(emailAddress) Then
Return False
End If
Return True
Else
Return False
End If
End Function
' This helper method performs a rudimentary check for whether
'a given e-mail is valid.
Private Shared Function IsValidEmailAddress(ByVal emailAddress As String) As Boolean
Dim splitEmail() = emailAddress.Split("@"c)
If splitEmail.Length <> 2 Then
Return False
End If
If Not splitEmail(1).Contains(".") Then
Return False
End If
Return True
End Function
End Class
アクセスが true であれば、STS A は、userAuthenticated
クレームを含む SAML トークンを発行します。
' Create the list of SAML Attributes.
Dim samlAttributes As New List(Of SamlAttribute)()
' Add the userAuthenticated claim.
Dim strList As New List(Of String)()
strList.Add("true")
Dim mySamlAttribute As New SamlAttribute("http://www.tmpuri.org", _
"userAuthenticated", _
strList)
samlAttributes.Add(mySamlAttribute)
' Create the SAML token with the userAuthenticated claim. It is assumed that
' the method CreateSamlToken() is implemented as part of STS-A.
Dim samlToken = CreateSamlToken(proofToken, issuerToken, samlConditions, _
samlSubjectNameFormat, _
samlSubjectEmailAddress, _
samlAttributes)
組織 A のクライアント
MyService
サービスの呼び出しに必要な手順と共に、組織 A のクライアントを次の図に示します。全体の処理を示すために、他の機能コンポーネントも示します。
概要
フェデレーション セキュリティを使用すると、役割を明確に分離できるため、安全で拡張性のあるサービス アーキテクチャを構築できます。分散アプリケーションの構築と展開を行うためのプラットフォームとして、WCF ではフェデレーション セキュリティの実装をネイティブにサポートをしています。