フェデレーション
ここでは、フェデレーション セキュリティの概念について簡単に説明します。 また、フェデレーション セキュリティ アーキテクチャを展開する際の 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> により、フェデレーション セキュリティ アーキテクチャの展開が設定不要でサポートされます。
<wsFederationHttpBinding> 要素では、安全で信頼性が高く相互運用可能なバインディングが提供されます。このバインディングでは、要求/応答形式の通信を実現するための基盤となるトランスポート機構として HTTP を使用する必要があり、エンコードのワイヤー形式としてテキストと XML が使用されます。
フェデレーション セキュリティ シナリオで <wsFederationHttpBinding> を使用する場合、次のセクションで説明するように、論理的に独立した 2 つのフェーズに分けることができます。
第 1 フェーズ : 設計
設計フェーズ中、クライアントでは ServiceModel メタデータ ユーティリティ ツール (Svcutil.exe) を使用してサービス エンドポイントが公開するポリシーが読み取られ、サービスの認証と承認の要件が収集されます。 次のフェデレーション セキュリティの通信パターンをクライアントで作成するために、適切なプロキシが構築されます。
クライアント信頼レルムにある STS からセキュリティ トークンを取得する。
サービス信頼レルムにある STS にトークンを提示する。
サービス信頼レルムにある STS からセキュリティ トークンを取得する。
サービスにトークンを提示してサービスにアクセスする。
第 2 フェーズ : 実行時
実行時フェーズ中、クライアントでは WCF クライアント クラスのオブジェクトがインスタンス化され、この WCF クライアントを使用して呼び出しが行われます。 WCF の基盤となるフレームワークにより、フェデレーション セキュリティの通信パターンにおける前述の手順が処理され、クライアントにおいてシームレスにサービスを利用できるようになります。
WCF を使用した実装のサンプル
WCF のネイティブ サポートを使用したフェデレーション セキュリティ アーキテクチャの実装サンプルを次の図に示します。
MyService の例
MyService
サービスは、MyServiceEndpoint
を介して単一のエンドポイントを公開します。 このエンドポイントに関連付けられたアドレス、バインディング、およびコントラクトを次の図に示します。
サービス エンドポイント MyServiceEndpoint
では、<wsFederationHttpBinding> が使用され、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="http://localhost/FederationSample/STS-B/STS.svc" />
<issuerMetadata
address=
"http://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
クラスによって実行時に適用されます。
using System.Collections.Generic;
using System.IdentityModel.Claims;
using System.IdentityModel.Policy;
using System.IdentityModel.Tokens;
using System.Security.Cryptography.X509Certificates;
using System.ServiceModel;
Imports System.Collections.Generic
Imports System.IdentityModel.Claims
Imports System.IdentityModel.Policy
Imports System.IdentityModel.Tokens
Imports System.Security.Cryptography.X509Certificates
Imports System.ServiceModel
Imports System.ServiceModel.Channels
Imports System.ServiceModel.Security.Tokens
Imports System.Text
public class myServiceAuthorizationManager : ServiceAuthorizationManager
{
// Override the CheckAccess method to enforce access control requirements.
public override bool CheckAccess(OperationContext operationContext)
{
AuthorizationContext authContext =
operationContext.ServiceSecurityContext.AuthorizationContext;
if (authContext.ClaimSets == null) return false;
if (authContext.ClaimSets.Count != 1) return false;
ClaimSet myClaimSet = authContext.ClaimSets[0];
if (!IssuedBySTS_B(myClaimSet)) return false;
if (myClaimSet.Count != 1) return false;
Claim myClaim = myClaimSet[0];
if (myClaim.ClaimType ==
"http://www.tmpuri.org:accessAuthorized")
{
string resource = myClaim.Resource as string;
if (resource == null) return false;
if (resource != "true") return false;
return true;
}
else
{
return false;
}
}
// 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 bool IssuedBySTS_B(ClaimSet myClaimSet)
{
ClaimSet issuerClaimSet = myClaimSet.Issuer;
if (issuerClaimSet == null) return false;
if (issuerClaimSet.Count != 1) return false;
Claim issuerClaim = issuerClaimSet[0];
if (issuerClaim.ClaimType != ClaimTypes.Thumbprint)
return false;
if (issuerClaim.Resource == null) return false;
byte[] claimThumbprint = (byte[])issuerClaim.Resource;
// It is assumed that stsB_Certificate is a variable of type
// X509Certificate2 that is initialized with the Certificate of
// STS-B.
X509Certificate2 stsB_Certificate = GetStsBCertificate();
byte[] certThumbprint = stsB_Certificate.GetCertHash();
if (claimThumbprint.Length != certThumbprint.Length)
return false;
for (int i = 0; i < claimThumbprint.Length; i++)
{
if (claimThumbprint[i] != certThumbprint[i]) return false;
}
return true;
}
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='http://localhost/FederationSample/STS-A/STS.svc' />
<issuerMetadata address='http://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 : ServiceAuthorizationManager
{
// Override AccessCheck to enforce access control requirements.
public override bool CheckAccess(OperationContext operationContext)
{
AuthorizationContext authContext =
operationContext.ServiceSecurityContext.AuthorizationContext;
if (authContext.ClaimSets == null) return false;
if (authContext.ClaimSets.Count != 1) return false;
ClaimSet myClaimSet = authContext.ClaimSets[0];
if (!IssuedBySTS_A(myClaimSet)) return false;
if (myClaimSet.Count != 1) return false;
Claim myClaim = myClaimSet[0];
if (myClaim.ClaimType == "http://www.tmpuri.org:userAuthenticated")
{
string resource = myClaim.Resource as string;
if (resource == null) return false;
if (resource != "true") return false;
return true;
}
else
{
return false;
}
}
// 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 bool IssuedBySTS_A(ClaimSet myClaimSet)
{
ClaimSet issuerClaimSet = myClaimSet.Issuer;
if (issuerClaimSet == null) return false;
if (issuerClaimSet.Count != 1) return false;
Claim issuerClaim = issuerClaimSet[0];
if (issuerClaim.ClaimType != ClaimTypes.Thumbprint) return false;
if (issuerClaim.Resource == null) return false;
byte[] claimThumbprint = (byte[])issuerClaim.Resource;
// It is assumed that stsA_Certificate is a variable of type X509Certificate2
// that is initialized with the Certificate of STS-A.
X509Certificate2 stsA_Certificate = GetStsACertificate();
byte[] certThumbprint = stsA_Certificate.GetCertHash();
if (claimThumbprint.Length != certThumbprint.Length) return false;
for (int i = 0; i < claimThumbprint.Length; i++)
{
if (claimThumbprint[i] != certThumbprint[i]) return false;
}
return true;
}
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.
List<SamlAttribute> samlAttributes = new List<SamlAttribute>();
// Add the accessAuthorized claim.
List<string> strList = new List<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.
SamlSecurityToken samlToken = CreateSamlToken(
proofToken,
issuerToken,
samlConditions,
samlSubjectNameFormat,
samlSubjectEmailAddress,
samlAttributes);
' 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 サービスであり、そのための単一のエンドポイントを公開します。 ただし、ここでは別のバインディング (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 : ServiceAuthorizationManager
{
// Override AccessCheck to enforce access control requirements.
public override bool CheckAccess(OperationContext operationContext)
{
AuthorizationContext authContext =
operationContext.ServiceSecurityContext.AuthorizationContext;
if (authContext.ClaimSets == null) return false;
if (authContext.ClaimSets.Count != 1) return false;
ClaimSet myClaimSet = authContext.ClaimSets[0];
if (myClaimSet.Count != 1) return false;
Claim myClaim = myClaimSet[0];
if ((myClaim.ClaimType ==
@"http://schemas.microsoft.com/ws/2005/05/identity/claims:EmailAddress") &&
(myClaim.Right == Rights.PossessProperty))
{
string emailAddress = myClaim.Resource as string;
if (emailAddress == null) return false;
if (!IsValidEmailAddress(emailAddress)) return false;
return true;
}
else
{
return false;
}
}
// This helper method performs a rudimentary check for whether
//a given email is valid.
private static bool IsValidEmailAddress(string emailAddress)
{
string[] splitEmail = emailAddress.Split('@');
if (splitEmail.Length != 2) return false;
if (!splitEmail[1].Contains(".")) return false;
return true;
}
}
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 = "http://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 email 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.
List<SamlAttribute> samlAttributes = new List<SamlAttribute>();
// Add the userAuthenticated claim.
List<string> strList = new List<string>();
strList.Add("true");
SamlAttribute mySamlAttribute = 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.
SamlSecurityToken samlToken = CreateSamlToken(
proofToken,
issuerToken,
samlConditions,
samlSubjectNameFormat,
samlSubjectEmailAddress,
samlAttributes);
' 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 ではフェデレーション セキュリティの実装をネイティブにサポートしています。