本主题简要概述了联合安全性的概念。 它还介绍了部署联合安全体系结构的 Windows Communication Foundation (WCF) 支持。 有关演示联合的示例应用程序,请参阅 联合示例。
联合安全性的定义
联合安全性允许客户端访问的服务与关联的身份验证和授权过程之间实现干净分离。 联合安全性还支持在不同信任领域跨多个系统、网络和组织进行协作。
WCF 支持生成和部署采用联合安全性的分布式系统。
联合安全体系结构的元素
联合安全体系结构具有三个关键元素,如下表所述。
元素 | DESCRIPTION |
---|---|
域/领域 | 安全管理或信任的单个单位。 典型的域可能包括单个组织。 |
联邦 | 已建立信任的域的集合。 信任级别可能会有所不同,但通常包括身份验证,并且几乎始终包括授权。 典型的联合可能包括一些组织,这些组织已建立对一组资源的共享访问权限的信任。 |
安全令牌服务 (STS) | 颁发安全令牌的 Web 服务;也就是说,它基于可信证据做出断言,并提供给信任它的任何人。 这构成了域之间信任调解的基础。 |
示例方案
下图显示了联合安全性的示例:
此方案包括两个组织:A 和 B.组织 B 具有 Web 资源(Web 服务),组织 A 中的一些用户发现有价值的内容。
注释
本部分可互换使用术语 资源、 服务和Web 服务 。
通常,组织 B 要求组织 A 的用户在访问服务之前提供某种有效的身份验证形式。 此外,组织可能还要求用户有权访问相关的特定资源。 解决此问题并使组织 A 中的用户能够访问组织 B 中的资源的一种方法如下:
组织 A 中的用户向组织 B 注册其凭据(用户名和密码)。
在资源访问期间,组织 A 中的用户向组织 B 提供其凭据,并在访问资源之前进行身份验证。
此方法有三大缺点:
除了管理其本地用户的凭据之外,组织 B 必须管理来自组织 A 的用户的凭据。
组织中的用户需要维护一组额外的凭据(即记住其他用户名和密码),除了他们通常用来访问组织 A 中的资源的凭据之外。这通常鼓励在多个服务站点使用相同的用户名和密码的做法,这是一种薄弱的安全措施。
体系结构不会随着更多组织认为组织 B 的资源具有某种价值而缩放。
一种解决前面提到的缺点的替代方法是使用联合安全性。 在这种方法中,组织 A 和 B 建立信任关系,并使用安全令牌服务(STS)来促进已建立信任的代理过程。
在联合安全体系结构中,组织 A 中的用户知道,如果他们想要访问组织 B 中的 Web 服务,则必须从组织 B 上的 STS 提供有效的安全令牌,该令牌对特定服务的访问权限进行身份验证和授权。
在与 STS B 联系时,用户可通过与 STS 关联的策略获得另一级间接寻址。 它们必须提供 STS A(即客户端信任领域)的有效安全令牌,然后 STS B 才能向他们颁发安全令牌。 这是两个组织之间建立的信任关系的结果,这意味着组织 B 不必从组织 A 管理用户的标识。在实践中,STS B 通常具有 null issuerAddress
和 issuerMetadataAddress
。 请参阅如何:配置本地颁发者以获取更多信息。 在这种情况下,客户端会查阅本地策略来查找 STS A。此配置称为 主领域联合 ,并且其缩放效果更好,因为 STS B 不必维护有关 STS A 的信息。
然后,用户联系组织 A 上的 STS,并通过提供他们通常用来访问组织 A 中任何其他资源的身份验证凭据来获取安全令牌。这还缓解了用户在多个服务站点上必须维护多个凭据集或使用同一组凭据的问题。
用户从 STS A 获取安全令牌后,会将令牌提供给 STS B。组织 B 继续执行用户请求的授权,并从其自己的安全令牌集中向用户颁发安全令牌。 然后,用户可以将其令牌呈现到组织 B 的资源,并访问该服务。
支持 WCF 中的联合安全性
WCF 为通过 <wsFederationHttpBinding> 部署联合安全体系结构提供全面支持。
<wsFederationHttpBinding> 元素提供了一个安全、可靠、可互作的绑定,该绑定需要使用 HTTP 作为请求-回复通信样式的基础传输机制,使用文本和 XML 作为编码的线路格式。
联合安全方案中 wsFederationHttpBinding<> 的使用可以分为两个逻辑独立的阶段,如以下各节中所述。
阶段 1:设计阶段
在设计阶段,客户端使用 ServiceModel 元数据实用工具工具(Svcutil.exe) 读取服务终结点公开的策略,并收集服务的身份验证和授权要求。 将构造相应的代理,以在客户端上创建以下联合安全通信模式:
从客户端信任领域中的 STS 获取安全令牌。
将令牌提供给服务信任领域中的 STS。
从服务信任领域中的 STS 获取安全令牌。
向服务提供令牌以访问该服务。
阶段 2:运行时阶段
在运行时阶段,客户端实例化 WCF 客户端类的对象,并使用 WCF 客户端进行调用。 WCF 的基础框架处理联合安全通信模式中前面提到的步骤,并使客户端能够无缝使用服务。
使用 WCF 的示例实现
下图表现了一个使用 WCF 原生支持的联合安全架构的示例实现。
MyService 示例
服务 MyService
通过 MyServiceEndpoint
公开单个终结点。 下图显示了与终结点关联的地址、绑定和协定。
服务终结点 MyServiceEndpoint
使用 <wsFederationHttpBinding>,并要求具有由 STS B 颁发的 accessAuthorized
声明的有效安全断言标记语言(SAML)令牌。这一点在服务配置中已通过声明方式指定。
<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
要求的声明,有一细微点应加以注意。 第二个图指示 MyService
需要具有 accessAuthorized
声明的 SAML 令牌。 更确切地说,这指定了 MyService
需要的声明类型。 此声明类型的完全限定名称是 http://tempuri.org:accessAuthorized
(包括关联命名空间),用于服务配置文件中。 此声明的值表明该声明的存在,并假定由STS B设置为true
。
在运行时,此策略由 MyServiceOperationRequirement
作为其中一部分实现的 MyService
类强制执行。
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 要求用户提供由包含 userAuthenticated
声明的 STS A 颁发的有效 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_OperationRequirement
该类强制实施此策略,该策略作为 STS B 的一部分实现。
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 服务,用于颁发安全令牌并公开单个终结点以实现此目的。 不过,STS A 使用另一个绑定 (wsHttpBinding
) 并要求用户提供具有 emailAddress
声明的有效 CardSpace。 作为响应,它会颁发具有 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_OperationRequirement
该类强制实施此策略,该策略作为 STS A 的一部分实现。
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 的客户
下图显示了组织 A 上的客户端,以及进行 MyService
服务调用所涉及的步骤。 还包含其它功能组件,以确保完整性。
概要
联合安全性提供干净的责任划分,有助于构建安全、可缩放的服务体系结构。 作为构建和部署分布式应用程序的平台,WCF 提供对实现联合安全性的原生支持。