Федерация
В этом разделе приведен краткий обзор концепции федеративной безопасности. Кроме того, описывается предусмотренная в Windows Communication Foundation (WCF) поддержка развертывания архитектур федеративной безопасности. Пример приложения, демонстрирующий федерацию, см. в разделе Образец федерации.
Определение федеративной безопасности
Федеративная безопасность обеспечивает четкое разделение между службой, к которой обращается клиент, и связанными процедурами проверки подлинности и авторизации. Федеративная безопасность также делает возможной совместную работу групп из нескольких систем, сетей и организаций, принадлежащих к различным областям доверия.
WCF обеспечивает поддержку построения и развертывания распределенных систем, в которых используется федеративная безопасность.
Элементы архитектуры федеративной безопасности
Архитектура федеративной безопасности включает три основных элемента, рассмотренных в следующей таблице.
Элемент | Описание |
---|---|
Домен/область |
Единица администрирования безопасности или доверия. Типичный домен может включать одну организацию. |
Федерация |
Совокупность доменов, между которыми установлено отношение доверия. Уровень доверия может быть разным, но обычно предусматривает проверку подлинности и почти всегда предусматривает авторизацию. Типичная федерация может включать ряд организаций, между которыми установлено отношение доверия для общего доступа к некоторому набору ресурсов. |
Служба маркеров безопасности (STS) |
Веб-служба, выдающая маркеры безопасности, т. е. делающая утверждения на основании свидетельств, которым она доверяет, перед теми, кто доверяет ей. Эти утверждения образуют основу посредничества с доверием между доменами. |
Пример сценария
На следующем рисунке показан пример федеративной безопасности.
В сценарии участвует две организации: A и B. Организация B имеет веб-ресурс (веб-службу), которую некоторые пользователи в организации A находят полезной.
Примечание |
---|
В этом разделе термины ресурс, служба и веб-служба используются взаимозаменяемо. |
Как правило, организация B требует, чтобы пользователь из организации A предоставил какое-либо допустимое доказательство своей подлинности, прежде чем обращаться к службе. Кроме того, организация может также потребовать, чтобы пользователь был авторизован для доступа к данному ресурсу. Один из способов решить эту проблему и дать пользователям в организации A возможность доступа к ресурсу в организации B заключается в следующем.
Пользователи из организации A регистрируют свои учетные данные (имя пользователя и пароль) в организации B.
При обращении к ресурсу пользователи из организации A предъявляют свои учетные данные организации B, т. е. подлинность пользователей проверяется, прежде чем они получают доступ к ресурсу.
Это подход имеет три существенных недостатка.
Организации B приходится управлять учетными данными пользователей из организации A, помимо управления учетными данными своих локальных пользователей.
Пользователям в организации A приходится иметь дополнительный набор учетных данных (т. е. помнить дополнительные имя пользователя и пароль) помимо учетных данных, которыми они пользуются для получения доступа к ресурсам в пределах организации A. В таких случаях пользователи часто используют одни и те же имя пользователя и пароль для доступа к нескольким сайтам служб, что ослабляет защиту.
Архитектура не масштабируется, если другие организации посчитают ресурс в организации B полезным для своих пользователей.
Альтернативный подход, лишенный упомянутых выше недостатков — это использование федеративной безопасности. В соответствии с этим подходом организации A и B устанавливают отношения доверия и используют службу маркеров безопасности (Security Token Service, STS) как посредника для установленного доверия.
В архитектуре федеративной безопасности пользователи из организации A знают, что если им требуется обратиться к веб-службе в организации B, они должны предъявить в организации B допустимый маркер безопасности от службы STS, который используется для проверки их подлинности и авторизации их доступа к определенной службе.
При обращении к службе STS B пользователи приобретают еще один уровень косвенного обращения от политики, связанной со службой STS. Прежде чем служба STS B сможет выдать им маркер безопасности, они должны предъявить допустимый маркер безопасности от службы STS A (т. е. из области доверия клиента). Это логическое следствие из отношения доверия, установленного между двумя организациями, подразумевающее, что организации B не требуется управлять удостоверениями пользователей из организации A. На практике служба STS B обычно имеет пустые адреса issuerAddress и issuerMetadataAddress. Дополнительные сведения см. в разделе Как настраивать локальный издатель. В этом случае, чтобы найти службу STS A, клиент обращается к локальной политике. Такая конфигурация называется федерация с домашней областью и является более масштабируемой, поскольку службе STS B не требуется обладать информацией о службе STS A.
Затем пользователи связываются со службой STS в организации A и получают маркер безопасности, предъявляя для проверки подлинности учетные данные, которыми они обычно пользуются для доступа к любому другому ресурсу в пределах организации A. Это также решает проблему пользователей, которым приходится либо помнить несколько наборов учетных данных, либо использовать один и тот же набор учетных данных на нескольких сайтах служб.
Получив маркер безопасности от службы STS A, пользователи предъявляют маркер службе STS B. Далее организация B авторизует запросы пользователей и выдает пользователям маркер безопасности из собственного набора маркеров безопасности. Пользователи затем могут предъявить свой маркер ресурсу в организации B и получить доступ к службе.
Поддержка федеративной безопасности в WCF
В WCF предусмотрена готовая поддержка развертывания архитектур федеративной безопасности посредством wsFederationHttpBinding element.
Элемент wsFederationHttpBinding element обеспечивает безопасную, надежную, поддерживающую взаимодействие привязку, предполагающую использование протокола HTTP в качестве базового транспортного механизма для связи в стиле "запрос-ответ" и текста и XML в качестве формата кодирования при передаче по линиям связи.
Использование wsFederationHttpBinding element в сценарии федеративной безопасности можно разделить на две логически независимых фазы, как описано ниже.
Фаза 1: фаза проектирования
На фазе проектирования клиент использует Служебное средство ServiceModel Metadata Utility Tool (Svcutil.exe) для чтения политики, предоставляемой конечной точкой службы, и для сбора требований службы в отношении проверки подлинности и авторизации. Строятся соответствующие прокси-объекты для создания следующей схемы обмена данными федеративной безопасности на стороне клиента:
получение маркера безопасности от службы STS в области доверия клиента;
предъявление маркера службе STS в области доверия службы;
получение маркера безопасности от службы STS в области доверия службы;
предъявление маркера службе для доступа к службе.
Фаза 2: фаза времени выполнения
На фазе времени выполнения клиент создает экземпляр класса клиента WCF и делает вызов с использованием клиента WCF. Базовая архитектура WCF обрабатывает упомянутые выше шаги схемы обмена данными федеративной безопасности и позволяет клиенту легко воспользоваться службой.
Пример реализации с использованием WCF
На следующем рисунке показан пример реализации архитектуры федеративной безопасности с использованием встроенной поддержки WCF.
Служба MyService
Служба MyService
предоставляет одну конечную точку — MyServiceEndpoint
. На следующем рисунке показаны адрес, привязка и контракт, связанные с конечной точкой.
Конечная точка MyServiceEndpoint
использует wsFederationHttpBinding element и требует допустимый маркер на языке SAML (Security Assertions Markup Language) с утверждением accessAuthorized, выданным службой STS B. Это декларативно указано в конфигурации службы.
<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 , необходимо отметить один небольшой момент. Из второго рисунка видно, что служба MyService требует маркер SAML с утверждением accessAuthorized. Точнее, эта строка задает тип утверждения, которого требует служба MyService . Полное имя этого типа утверждения — http://tempuri.org:accessAuthorized (вместе со связанным пространством имен); это имя используется в файле конфигурации службы. Значение этого утверждения указывает на присутствие этого утверждения, и предполагается, что служба STS B установила его равным true.
|
Во время выполнения эта политика применяется классом MyServiceOperationRequirement
, реализованным в составе службы MyService
.
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) также представляет собой веб-службу и может иметь свои конечные точки, политику и т. д.
Служба STS B предоставляет одну конечную точку, STSEndpoint
, которую можно использовать для запроса маркеров безопасности. В частности, служба STS B выдает маркеры SAML с утверждением accessAuthorized, которые могут быть предъявлены на сайте службы MyService
для доступа к службе. В то же время служба STS B требует от пользователей предъявления допустимого маркера SAML, выданного службой STS A и содержащего утверждение userAuthenticated. Это декларативно указано в конфигурации службы 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:accessAuthorized (вместе со связанным пространством имен); это имя используется в файле конфигурации службы STS. Значение этого утверждения указывает на присутствие этого утверждения, и предполагается, что служба STS A установила его равным true.
|
Во время выполнения эта политика применяется классом STS_B_OperationRequirement
, реализованным в составе службы STS B.
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 выдает маркер SAML с утверждением accessAuthorized
.
' 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 также представляет собой веб-службу, выдающую маркеры безопасности и предоставляющую с этой целью одну конечную точку. Однако она использует другую привязку (wsHttpBinding) и требует от пользователей предъявления допустимого маркера CardSpace с утверждением emailAddress. В ответ она выдает маркеры SAML с утверждением userAuthenticated. Это декларативно указано в конфигурации службы.
<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
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 выдает маркер SAML с утверждением userAuthenticated
.
' 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 предусматривает встроенную поддержку для реализации федеративной безопасности.