Federacja
Ten temat zawiera krótkie omówienie koncepcji zabezpieczeń federacyjnych. Opisano również obsługę programu Windows Communication Foundation (WCF) na potrzeby wdrażania architektur zabezpieczeń federacyjnych. Aby zapoznać się z przykładową aplikacją, która demonstruje federację, zobacz Przykład federacji.
Definicja zabezpieczeń federacyjnych
Zabezpieczenia federacyjne umożliwiają czystą separację między usługą, do której uzyskuje dostęp klient, a skojarzonymi procedurami uwierzytelniania i autoryzacji. Zabezpieczenia federacyjne umożliwiają również współpracę w wielu systemach, sieciach i organizacjach w różnych obszarach zaufania.
Program WCF zapewnia obsługę kompilowania i wdrażania systemów rozproszonych, które korzystają z zabezpieczeń federacyjnych.
Elementy architektury zabezpieczeń federacyjnych
Architektura zabezpieczeń federacyjnych zawiera trzy kluczowe elementy, zgodnie z opisem w poniższej tabeli.
Element | opis |
---|---|
Domena/obszar | Pojedyncza jednostka administracji zabezpieczeń lub zaufania. Typowa domena może obejmować jedną organizację. |
Federacja | Kolekcja domen, które mają ustanowioną relację zaufania. Poziom zaufania może się różnić — zwykle obejmuje uwierzytelnianie i niemal zawsze autoryzację. Typowa federacja może obejmować kilka organizacji, które mają ustanowioną relację zaufania na potrzeby dostępu współdzielonego do zestawu zasobów. |
Usługa tokenu zabezpieczającego (STS) | Usługa sieci Web, która wystawia tokeny zabezpieczające; oznacza to, że twierdzi, że opiera się na dowodach, że ufa, niezależnie od tego, kto mu ufa. Stanowi to podstawę brokera zaufania między domenami. |
Przykładowy scenariusz
Poniższa ilustracja przedstawia przykład zabezpieczeń federacyjnych:
Ten scenariusz obejmuje dwie organizacje: A i B. Organizacja B ma zasób internetowy (usługę sieci Web), który niektórzy użytkownicy w organizacji A znajdują cenne.
Uwaga
W tej sekcji są używane terminy zasoby, usługa i usługa sieci Web zamiennie.
Zazwyczaj organizacja B wymaga, aby użytkownik z organizacji A zapewniał prawidłową formę uwierzytelniania przed uzyskaniem dostępu do usługi. Ponadto organizacja może również wymagać, aby użytkownik był autoryzowany do uzyskiwania dostępu do określonego zasobu. Jednym ze sposobów rozwiązania tego problemu i umożliwienia użytkownikom w organizacji A uzyskiwania dostępu do zasobu w organizacji B jest następujący:
Użytkownicy z organizacji A rejestrują swoje poświadczenia (nazwę użytkownika i hasło) w organizacji B.
Podczas uzyskiwania dostępu do zasobów użytkownicy z organizacji A przedstawiają swoje poświadczenia organizacji B i są uwierzytelniani przed uzyskaniem dostępu do zasobu.
Takie podejście ma trzy znaczące wady:
Organizacja B musi zarządzać poświadczeniami użytkowników z organizacji A oprócz zarządzania poświadczeniami użytkowników lokalnych.
Użytkownicy w organizacji Musi zachować dodatkowy zestaw poświadczeń (czyli zapamiętać dodatkową nazwę użytkownika i hasło) poza poświadczeniami, których zwykle używają do uzyskiwania dostępu do zasobów w organizacji A. Zwykle zachęca to do korzystania z tej samej nazwy użytkownika i hasła w wielu lokacjach usług, co jest słabą miarą zabezpieczeń.
Architektura nie jest skalowana, ponieważ więcej organizacji postrzega zasób w organizacji B jako wartość.
Alternatywną metodą, która dotyczy wcześniej wymienionych wad, jest zastosowanie zabezpieczeń federacyjnych. W tym podejściu organizacje A i B ustanawiają relację zaufania i wykorzystują usługę tokenu zabezpieczającego (STS), aby umożliwić brokerowi ustanowionego zaufania.
W architekturze zabezpieczeń federacyjnych użytkownicy z organizacji A wiedzą, że jeśli chcą uzyskać dostęp do usługi internetowej w organizacji B, że muszą przedstawić prawidłowy token zabezpieczający z usługi STS w organizacji B, która uwierzytelnia i autoryzuje dostęp do określonej usługi.
Po skontaktowaniu się z usługą STS B użytkownicy otrzymują kolejny poziom pośredni od zasad skojarzonych z usługą STS. Muszą przedstawić prawidłowy token zabezpieczający z usługi STS A (czyli obszar zaufania klienta), zanim usługa STS B będzie mogła wydać im token zabezpieczający. Jest to wspólna relacja zaufania ustanowiona między dwiema organizacjami i oznacza, że organizacja B nie musi zarządzać tożsamościami użytkowników z organizacji A. W praktyce usługa STS B zwykle ma wartość null issuerAddress
i issuerMetadataAddress
. Aby uzyskać więcej informacji, zobacz How to: Configure a Local Issuer (Jak skonfigurować wystawcę lokalnego). W takim przypadku klient skonsultuje się z zasadami lokalnymi, aby zlokalizować usługę STS A. Ta konfiguracja jest nazywana federacją obszaru macierzystego i jest skalowana lepiej, ponieważ usługa STS B nie musi przechowywać informacji o STS A.
Następnie użytkownicy kontaktują się z usługą STS w organizacji A i uzyskują token zabezpieczający, przedstawiając poświadczenia uwierzytelniania, których zwykle używają do uzyskania dostępu do dowolnego innego zasobu w organizacji A. Zapobiega to również problemowi użytkowników, którzy muszą obsługiwać wiele zestawów poświadczeń lub używać tego samego zestawu poświadczeń w wielu lokacjach usług.
Gdy użytkownicy uzyskają token zabezpieczający z usługi STS A, przedstawią token do usługi STS B. Organizacja B kontynuuje autoryzację żądań użytkowników i wystawia token zabezpieczający użytkownikom z własnego zestawu tokenów zabezpieczających. Użytkownicy mogą następnie przedstawić swój token do zasobu w organizacji B i uzyskać dostęp do usługi.
Obsługa zabezpieczeń federacyjnych w programie WCF
Program WCF zapewnia kompleksową obsługę wdrażania architektur zabezpieczeń federacyjnych za pośrednictwem programu wsFederationHttpBinding>.<
Element <wsFederationHttpBinding> zapewnia bezpieczne, niezawodne powiązanie międzyoperacyjne, które wiąże się z użyciem protokołu HTTP jako podstawowego mechanizmu transportu dla stylu komunikacji żądań i odpowiedzi, stosowania tekstu i kodu XML jako formatu przewodowego do kodowania.
Użycie usługi <wsFederationHttpBinding> w scenariuszu zabezpieczeń federacyjnych może zostać oddzielone od dwóch logicznie niezależnych faz, zgodnie z opisem w poniższych sekcjach.
Faza 1. Faza projektowania
W fazie projektowania klient używa narzędzia ServiceModel Metadata Tool (Svcutil.exe), aby odczytać zasady uwidoczniane przez punkt końcowy usługi i zebrać wymagania dotyczące uwierzytelniania i autoryzacji usługi. Odpowiednie serwery proxy są tworzone w celu utworzenia następującego wzorca komunikacji federacyjnej zabezpieczeń na kliencie:
Uzyskaj token zabezpieczający z usługi STS w obszarze zaufania klienta.
Prezentowanie tokenu do usługi STS w obszarze zaufania usługi.
Uzyskaj token zabezpieczający z usługi STS w obszarze zaufania usługi.
Przedstawia token usłudze w celu uzyskania dostępu do usługi.
Faza 2. Faza czasu wykonywania
W fazie wykonywania klient tworzy wystąpienie obiektu klasy klienta WCF i wykonuje wywołanie przy użyciu klienta WCF. Podstawowa struktura usługi WCF obsługuje wymienione wcześniej kroki we wzorcu komunikacji zabezpieczeń federacyjnych i umożliwia klientowi bezproblemowe korzystanie z usługi.
Przykładowa implementacja przy użyciu programu WCF
Poniższa ilustracja przedstawia przykładową implementację architektury zabezpieczeń federacyjnych przy użyciu natywnej obsługi programu WCF.
Przykładowa usługa MyService
Usługa MyService
uwidacznia pojedynczy punkt końcowy za pośrednictwem elementu MyServiceEndpoint
. Poniższa ilustracja przedstawia adres, powiązanie i kontrakt skojarzony z punktem końcowym.
Punkt końcowy MyServiceEndpoint
usługi używa tokenu <wsFederationHttpBinding> i wymaga prawidłowego tokenu języka SAML (Security Assertions Markup Language) z oświadczeniem wystawionym przez usługę accessAuthorized
STS B. Jest to deklaratywnie określone w konfiguracji usługi.
<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>
Uwaga
Należy zauważyć subtelny punkt dotyczący oświadczeń wymaganych przez MyService
element . Druga ilustracja wskazuje, że MyService
wymaga tokenu SAML z oświadczeniem accessAuthorized
. Aby dokładniej określić typ oświadczenia, który MyService
jest wymagany. W pełni kwalifikowana nazwa tego typu oświadczenia to http://tempuri.org:accessAuthorized
(wraz ze skojarzona przestrzenią nazw), która jest używana w pliku konfiguracji usługi. Wartość tego oświadczenia wskazuje obecność tego oświadczenia i przyjmuje się, że ma zostać ustawiona na true
wartość STS B.
W czasie wykonywania te zasady są wymuszane przez klasę MyServiceOperationRequirement
zaimplementowaną w ramach klasy 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
Na poniższej ilustracji przedstawiono sts B. Jak wspomniano wcześniej, usługa tokenu zabezpieczającego (STS) jest również usługą sieci Web i może mieć skojarzone z nią punkty końcowe, zasady itd.
Usługa STS B uwidacznia pojedynczy punkt końcowy o nazwie STSEndpoint
, który może służyć do żądania tokenów zabezpieczających. W szczególności usługa STS B wystawia tokeny SAML z accessAuthorized
oświadczeniem, które można przedstawić w MyService
lokacji usługi w celu uzyskania dostępu do usługi. Jednak usługa STS B wymaga od użytkowników przedstawienia prawidłowego tokenu SAML wystawionego przez usługę STS A, który zawiera userAuthenticated
oświadczenie. Jest to deklaratywnie określone w konfiguracji usługi 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>
Uwaga
Ponownie oświadczenie userAuthenticated
jest typem oświadczenia wymaganym przez usługę STS B. W pełni kwalifikowana nazwa tego typu oświadczenia to http://tempuri.org:userAuthenticated
(wraz ze skojarzona przestrzenią nazw), która jest używana w pliku konfiguracji usługi STS. Wartość tego oświadczenia wskazuje obecność tego oświadczenia i zakłada się, że ma zostać ustawiona na true
wartość STS A.
W czasie STS_B_OperationRequirement
wykonywania klasa wymusza te zasady, które są implementowane w ramach usługi 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
Jeśli sprawdzanie dostępu jest jasne, usługa STS B wystawia token SAML z oświadczeniem accessAuthorized
.
// 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
Na poniższej ilustracji przedstawiono sts A.
Podobnie jak usługa STS B, STS A jest również usługą sieci Web, która wystawia tokeny zabezpieczające i uwidacznia jeden punkt końcowy w tym celu. Jednak używa innego powiązania (wsHttpBinding
) i wymaga od użytkowników przedstawienia prawidłowego elementu CardSpace z oświadczeniem emailAddress
. W odpowiedzi wystawia tokeny SAML z oświadczeniem userAuthenticated
. Jest to deklaratywnie określone w konfiguracji usługi.
<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>
W czasie STS_A_OperationRequirement
wykonywania klasa wymusza te zasady, które są implementowane w ramach usługi 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
Jeśli dostęp to true
, usługa STS A wystawia token SAML z oświadczeniem userAuthenticated
.
// 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)
Klient w organizacji A
Poniższa ilustracja przedstawia klienta w organizacji A wraz z krokami podejmowania MyService
wywołania usługi. Pozostałe składniki funkcjonalne są również uwzględniane w celu ukończenia pracy.
Podsumowanie
Zabezpieczenia federacyjne zapewniają czysty podział odpowiedzialności i pomagają tworzyć bezpieczne, skalowalne architektury usług. Jako platforma do tworzenia i wdrażania aplikacji rozproszonych usługa WCF zapewnia natywną obsługę implementowania zabezpieczeń federacyjnych.