Verbund
Dieses Thema enthält eine kurze Übersicht über den Begriff Verbundsicherheit. Darüber hinaus wird die Windows Communication Foundation (WCF)-Unterstützung für die Einbindung von Verbundsicherheitsarchitekturen beschrieben. Eine Beispielanwendung, die Verbund veranschaulicht, finden Sie unter Verbundbeispiel.
Definition von Verbundsicherheit
Verbundsicherheit ermöglicht eine saubere Trennung zwischen dem Dienst, auf den ein Client zugreift, und den dazugehörigen Authentifizierungs- und Autorisierungsvorgängen. Darüber hinaus aktiviert Verbundsicherheit die Zusammenarbeit über mehrere Systeme, Netzwerke und Organisationen in anderen Vertrauensbereichen.
WCF unterstützt die Erstellung und Bereitstellung von verteilten Systemen, die Verbundsicherheit verwenden.
Elemente einer Verbundsicherheitsarchitektur
Die Verbundsicherheitsarchitektur verfügt über drei Hauptelemente (siehe Beschreibung in der folgenden Tabelle).
Element | Beschreibung |
---|---|
Domäne/Bereich |
Eine einzelne Einheit von Sicherheitsverwaltung oder -vertrauen. Eine typische Domäne könnte eine einzelne Organisation einschließen. |
Verbund |
Eine Auflistung von Domänen, die Vertrauenswürdigkeit bewiesen haben. Die Ebene der Vertrauenswürdigkeit ändert sich möglicherweise, schließt aber in der Regel die Authentifizierung und fast immer die Autorisierung ein. Zu einem typischen Verbund kann eine Anzahl an Organisationen gehören, die Vertrauen für einen gemeinsamen Zugriff auf Ressourcen aufgebaut haben. |
Sicherheitstokendienst (STS; Security Token Service) |
Hierbei handelt es sich um einen Webdienst, der Sicherheitstoken herausgibt, d. h. es werden basierend auf Beweisen, die als vertrauenswürdig eingestuft werden, Assertionen erstellt. Dies bildet die Grundlage für die Vertrauensvermittlung zwischen Domänen. |
Beispielszenario
Die folgende Abbildung zeigt ein Beispiel für Verbundsicherheit.
Dieses Szenario enthält zwei Organisationen: A und B. Organisation B hat eine Webressource (einen Webdienst), die einige Benutzer in der Organisation A als wertvoll betrachten.
Hinweis: |
---|
In diesem Abschnitt sind die verwendeten Begriffe Ressource, Dienst und Webdienst austauschbar. |
Üblicherweise fordert Organisation B, dass ein Benutzer der Organisation A eine gültige Form der Authentifizierung bereitstellt, bevor der Zugriff auf den Dienst gewährt wird. Darüber hinaus kann die Organisation verlangen, dass der Benutzer für den Zugriff auf die spezifische Ressource autorisiert wird. Eine Art der Problemlösung und Ermöglichung des Zugriffs auf die Ressource in der Organisation B durch die Benutzer in der Organisation A ist folgendermaßen:
Benutzer von Organisation A registrieren Ihre Anmeldeinformationen (Benutzername und Kennwort) bei der Organisation B.
Während des Zugriffs auf die Ressource geben Benutzer der Organisation A Ihre Anmeldeinformationen an die Organisation B weiter und werden vor Zugriff auf die Ressource authentifiziert.
Dieser Ansatz hat drei bedeutende Nachteile:
Zusätzlich zur Verwaltung der Anmeldeinformationen der lokalen Benutzer muss die Organisation B die Anmeldeinformationen für Benutzer der Organisation A verwalten.
Benutzer der Organisation A müssen, abgesehen von den Anmeldeinformationen, die sie sonst für den Zugriff auf die Ressourcen innerhalb der Organisation verwenden, zusätzliche Anmeldeinformationen pflegen (d. h. einen zusätzlichen Benutzernamen und ein zusätzliches Kennwort). Es wird daher empfohlen, denselben Benutzernamen und dasselbe Kennwort für unterschiedliche Dienstsites zu verwenden, wobei es sich um eine anfällige Sicherheitsmaßnahme handelt.
Die Architektur nimmt keine Skalierung vor, während weitere Organisationen die Ressource bei Organisation B als wertvoll betrachten.
Ein alternativer Ansatz, der die zuvor erwähnten Nachteile berücksichtigt, ist die Bereitstellung von Verbundsicherheit. In diesem Ansatz bauen die Organisationen A und B eine Vertrauensbeziehung auf und verwenden STS (Security Token Service), um die Vermittlung des aufgebauten Vertrauens zu ermöglichen.
In einer Verbundsicherheitsarchitektur wissen Benutzer der Organisation A, dass sie einen gültigen Sicherheitstoken aus STS bei der Organisation vorlegen müssen, der ihren Zugang zum entsprechenden Dienst authentifiziert und autorisiert, wenn sie auf den Webdienst in Organisation B zugreifen möchten.
Durch die Kontaktaufnahme mit dem STS B erhalten die Benutzer eine andere Dereferenzierungsebene aus der zum STS gehörenden Richtlinie. Sie müssen einen gültigen Sicherheitstoken aus STS A (d. h. den Clientvertrauensbereich) vorweisen, bevor der STS B einen Sicherheitstoken an sie ausgeben kann. Hierbei handelt es sich um eine Folgeerscheinung aus der zwischen den beiden Organisationen aufgebauten Vertrauensbeziehung, wobei impliziert wird, dass Organisation B die Identitäten für Benutzer aus der Organisation A nicht verwalten muss. In der Praxis verfügt der STS B üblicherweise über eine Null-issuerAddress und eine issuerMetadataAddress. Weitere Informationen finden Sie unter Vorgehensweise: Konfigurieren eines lokalen Ausstellers. In diesem Fall konsultiert der Client eine lokale Richtlinie für die Lokalisierung des STS A. Diese Konfiguration wird Heimbereichsverbund genannt, und die Skalierung ist hier besser, da STS B keine Informationen über STS A pflegen muss.
Die Benutzer kontaktieren nun den STS bei Organisation A und erhalten einen Sicherheitstoken, indem sie Authentifizierungsanmeldeinformationen vorlegen, die sie normalerweise für den Zugang zu anderen Ressourcen innerhalb der Organisation A verwenden. Hierdurch wird auch das Problem gemindert, dass Benutzer mehrere Sätze an Anmeldeinformationen pflegen müssen oder den gleichen Satz an Anmeldeinformationen für mehrere Dienstsites verwenden.
Nachdem die Benutzer einen Sicherheitstoken vom STS A erhalten haben, legen Sie den Token dem STS B vor. Organisation B führt die Autorisierung der Benutzeranfragen durch und gibt an die Benutzer einen Sicherheitstoken aus ihrem eigenen Satz an Sicherheitstoken heraus. Die Benutzer können dann ihren Token bei der Ressource bei Organisation B vorlegen und auf den Dienst zugreifen.
Unterstützung für Verbundsicherheit in WCF
WCF bietet sofort verwendbare Unterstützung für die Bereitstellung von Verbundsicherheitsarchitekturen durch wsFederationHttpBinding element.
Das wsFederationHttpBinding element-Element bietet eine sichere, zuverlässige, interoperable Bindung, die die Verwendung von HTTP als den zugrunde liegenden Transportmechanismus für den Anforderung-Antwort-Kommunikationsstil umfasst, während Text und XML als Format für die Codierung fungieren.
Die Verwendung von wsFederationHttpBinding element in einem Verbundsicherheitsszenario kann in zwei logisch unabhängige Phasen entkoppelt werden (siehe Beschreibung in den folgenden Abschnitten).
Phase 1: Entwurfsphase
Während der Entwurfsphase verwendet der Client ServiceModel Metadata Utility-Tool (Svcutil.exe), um die Richtlinie zu lesen, die der Dienstendpunkt zur Verfügung stellt, und die Dienstauthentifizierungs- und -autorisierungsanforderungen zu sammeln. Die entsprechenden Proxys werden erzeugt, um das folgende Verbundsicherheitskommunikationsmuster beim Client zu erstellen:
Erhalt eines Sicherheitstoken vom STS im Clientvertrauensbereich.
Präsentation des Token vor dem STS im Dienstvertrauensbereich.
Erhalt eines Sicherheitstoken vom STS im Dienstvertrauensbereich.
Präsentation des Token vor dem Dienst für den Zugriff auf den Dienst.
Phase 2: Laufzeitphase
Während der Laufzeitphase instanziiert ein Objekt der WCF-Clientklasse und nimmt mithilfe des WCF-Clients einen Aufruf vor. Das zugrunde liegende Framework von WCF behandelt die zuvor genannten Schritte im Verbundsicherheitskommunikationsmuster und ermöglicht es dem Client, den Dienst nahtlos zu nutzen.
Beispielimplementierung mithilfe von WCF
Die folgende Abbildung zeigt eine Beispielimplementierung für eine Verbundsicherheitsarchitektur mit systemeigener Unterstützung von WCF.
Beispiel MyService
Der Dienst MyService
macht durch MyServiceEndpoint
einen einzelnen Endpunkt verfügbar. Die folgende Abbildung zeigt Adresse, Bindung und Vertrag an, die zum Endpunkt gehören.
Der Dienstendpunkt MyServiceEndpoint
nutzt das wsFederationHttpBinding element und erfordert ein gültiges SAML (Security Assertions Markup Language)-Token mit einem accessAuthorized-Anspruch, der von STS B herausgegeben wurde. Dies wird deklarativ in der Dienstkonfiguration angegeben.
<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>
Hinweis: |
---|
Ein Punkt über die für MyService erforderlichen Ansprüche sollte beachtet werden. Die zweite Abbildung zeigt, dass MyService ein SAML-Token mit einem accessAuthorized-Anspruch erfordert. Genauer gesagt gibt dies den Anspruchstyp an, den MyService erfordert. Der vollqualifizierte Name dieses Anspruchstyps ist http://tempuri.org:accessAuthorized (mit dem zugehörigen Namespace). Dieser wird in der Dienstkonfigurationsdatei verwendet. Der Wert dieses Anspruchs zeigt das Vorhandensein dieses Anspruchs an und wird als von STS B auf true festgelegt angenommen.
|
Zur Laufzeit wird diese Richtlinie von der MyServiceOperationRequirement
-Klasse erzwungen, die als Teil von MyService
implementiert ist.
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
Die folgende Abbildung zeigt den STS B. Wie zuvor erwähnt, ist ein STS (Security Token Service) auch ein Webdienst und kann über zugehörige Endpunkte, Richtlinien usw. verfügen.
STS B macht einen einzelnen Endpunkt namens STSEndpoint
verfügbar, der verwendet werden kann, um das Sicherheitstoken anzufordern. STS B gibt insbesondere SAML-Token mit accessAuthorized-Anspruch heraus, die der MyService
-Dienstsite vorgelegt werden können, um Zugriff auf den Dienst zu erhalten. Allerdings erfordert STS B, dass Benutzer ein gültiges SAML-Token vorlegen, das von STS A herausgegeben wurde und den userAuthenticated-Anspruch enthält. Dies wird deklarativ in der STS-Konfiguration angegeben.
<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>
Hinweis: |
---|
Wiederum ist der userAuthenticated -Anspruch der Anspruchstyp, der von STS B gefordert wird. Der vollqualifizierte Name dieses Anspruchstyps ist http://tempuri.org:userAuthenticated (mit dem zugehörigen Namespace). Dieser wird von der STS-Konfigurationsdatei verwendet. Der Wert dieses Anspruchs zeigt das Vorhandensein dieses Anspruchs an und wird als von STS A auf true festgelegt angenommen.
|
Zur Laufzeit erzwingt die STS_B_OperationRequirement
-Klasse diese Richtlinie, die als Teil von STS B implementiert ist.
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
Wenn die Zugriffsprüfung klar ist, gibt STS B ein SAML-Token mit dem accessAuthorized
-Anspruch aus.
' 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
Die folgende Abbildung zeigt den STS A.
Ähnlich wie beim STS B ist auch der STS A ein Webdienst, der Sicherheitstoken herausgibt und einen einzelnen Endpunkt für diesen Zweck zur Verfügung stellt. Allerdings verwendet er eine andere Bindung (wsHttpBinding) und erfordert, dass Benutzer eine gültige CardSpace mit emailAddress-Anspruch vorlegen. Als Antwort gibt er SAML-Token mit dem userAuthenticated-Anspruch heraus. Dies wird deklarativ in der Dienstkonfiguration angegeben.
<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>
Zur Laufzeit erzwingt die STS_A_OperationRequirement
-Klasse diese Richtlinie, die als Teil von STS A implementiert ist.
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
Ist der Zugang true, gibt STS A ein SAML-Token mit userAuthenticated
-Anspruch heraus.
' 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)
Client bei Organisation A
Die folgende Abbildung zeigt den Client bei Organisation A sowie die Schritte zur Durchführung eines MyService
-Dienstaufrufs. Der Vollständigkeit halber sind auch die anderen funktionalen Komponenten aufgeführt.
Zusammenfassung
Verbundsicherheit liefert eine klare Trennung der Verantwortungsbereiche und unterstützt den Aufbau einer sicheren und skalierbaren Dienstarchitektur. Als Plattform für den Aufbau und die Bereitstellung von verteilten Anwendungen bietet WCF systemeigene Unterstützung für die Implementierung von Verbundsicherheit.