다음을 통해 공유


연맹

이 항목에서는 페더레이션 보안 개념에 대한 간략한 개요를 제공합니다. 또한 페더레이션 보안 아키텍처를 배포하기 위한 WCF(Windows Communication Foundation) 지원에 대해서도 설명합니다. 페더레이션을 보여 주는 샘플 애플리케이션은 페더레이션 샘플을 참조하세요.

페더레이션 보안 정의

페더레이션 보안을 사용하면 클라이언트가 액세스하는 서비스와 연결된 인증 및 권한 부여 절차를 완전히 분리할 수 있습니다. 페더레이션 보안은 여러 신뢰 영역의 여러 시스템, 네트워크 및 조직 간에 협업을 가능하게 합니다.

WCF는 페더레이션 보안을 사용하는 분산 시스템 빌드 및 배포를 지원합니다.

페더레이션 보안 아키텍처의 요소

페더레이션 보안 아키텍처에는 다음 표에 설명된 대로 세 가지 주요 요소가 있습니다.

요소 설명
도메인/영역 보안 관리 또는 신뢰의 단일 단위입니다. 일반적인 도메인에는 단일 조직이 포함될 수 있습니다.
연맹 신뢰가 형성된 도메인의 모음입니다. 신뢰 수준은 다를 수 있지만 일반적으로 인증을 포함하며 거의 항상 권한 부여를 포함합니다. 일반적인 페더레이션에는 리소스 집합에 대한 공유 액세스에 대한 신뢰를 설정한 여러 조직이 포함될 수 있습니다.
STS(보안 토큰 서비스) 보안 토큰을 발급하는 웹 서비스; 즉, 신뢰할 수 있는 증거를 바탕으로, 그것을 신뢰하는 이들에게만 신뢰할 수 있는 어설션을 제공합니다. 이는 도메인 간의 신뢰 조정의 기초를 형성합니다.

예제 시나리오

다음 그림에서는 페더레이션 보안의 예를 보여 줍니다.

일반적인 페더레이션 보안 시나리오를 보여 주는 다이어그램

이 시나리오에는 A와 B라는 두 개의 조직이 포함됩니다. 조직 B에는 조직 A의 일부 사용자가 유용하게 사용할 수 있는 웹 리소스(웹 서비스)가 있습니다.

비고

이 섹션에서는 리소스, 서비스웹 서비스 용어를 서로 교환하여 사용합니다.

일반적으로 조직 B는 서비스에 액세스하기 전에 조직 A의 사용자가 유효한 형태의 인증을 제공해야 합니다. 또한 조직은 사용자에게 해당 리소스에 액세스할 수 있는 권한을 부여하도록 요구할 수도 있습니다. 이 문제를 해결하고 조직 A의 사용자가 조직 B의 리소스에 액세스할 수 있도록 하는 한 가지 방법은 다음과 같습니다.

  • 조직 A의 사용자는 조직 B에 자격 증명(사용자 이름 및 암호)을 등록합니다.

  • 리소스 액세스 중에 조직 A의 사용자는 조직 B에 자격 증명을 표시하고 리소스에 액세스하기 전에 인증됩니다.

이 방법에는 다음과 같은 세 가지 중요한 단점이 있습니다.

  • 조직 B는 로컬 사용자의 자격 증명을 관리하는 것 외에도 조직 A의 사용자에 대한 자격 증명을 관리해야 합니다.

  • 조직의 사용자 A는 조직 A 내에서 리소스에 액세스하기 위해 일반적으로 사용하는 자격 증명과 별도로 추가 자격 증명 집합(즉, 추가 사용자 이름 및 암호를 기억)을 유지 관리해야 합니다. 이는 일반적으로 취약한 보안 조치인 여러 서비스 사이트에서 동일한 사용자 이름 및 암호를 사용하는 방법을 권장합니다.

  • 더 많은 조직이 조직 B의 리소스를 일부 가치로 인식하기 때문에 아키텍처는 확장되지 않습니다.

앞에서 언급한 단점을 해결하는 다른 방법은 페더레이션 보안을 사용하는 것입니다. 이 방법에서 조직 A와 B는 트러스트 관계를 설정하고 STS(보안 토큰 서비스)를 사용하여 설정된 트러스트를 중개할 수 있도록 합니다.

페더레이션 보안 아키텍처에서 조직 A의 사용자는 조직 B의 웹 서비스에 액세스하려는 경우 특정 서비스에 대한 액세스를 인증하고 권한을 부여하는 조직 B의 STS에서 유효한 보안 토큰을 제공해야 한다는 것을 알고 있습니다.

STS B에 연결할 때 사용자는 STS와 연결된 정책에서 다른 수준의 간접 참조를 받습니다. STS B가 보안 토큰을 발급하려면 먼저 STS A(즉, 클라이언트 신뢰 영역)에서 유효한 보안 토큰을 제공해야 합니다. 이는 두 조직 간에 설정된 신뢰 관계의 결과이며 조직 B가 조직 A의 사용자에 대한 ID를 관리할 필요가 없음을 의미합니다. 실제로 STS B에는 일반적으로 null issuerAddressissuerMetadataAddress. 자세한 내용은 방법: 로컬 발급자 구성을 참조하세요. 이 경우 클라이언트는 로컬 정책을 참조하여 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단계: Run-Time 단계

런타임 단계에서 클라이언트는 WCF 클라이언트 클래스의 개체를 인스턴스화하고 WCF 클라이언트를 사용하여 호출합니다. WCF의 기본 프레임워크는 페더레이션된 보안 통신 패턴에서 이전에 언급한 단계를 처리하고 클라이언트가 서비스를 원활하게 사용할 수 있도록 합니다.

WCF를 사용한 샘플 구현

다음 그림에서는 WCF의 네이티브 지원을 사용하는 페더레이션 보안 아키텍처에 대한 샘플 구현을 보여 줍니다.

샘플 페더레이션 보안 구현을 보여 주는 다이어그램

MyService 예제

서비스는 MyService .를 통해 MyServiceEndpoint단일 엔드포인트를 노출합니다. 다음 그림에서는 엔드포인트와 연결된 주소, 바인딩 및 계약을 보여 줍니다.

MyServiceEndpoint 세부 정보를 보여 주는 다이어그램

서비스 엔드포인트 MyServiceEndpointwsFederationHttpBinding을< 사용>하며 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에 의해 요구되는 클레임에 대한 미묘한 점에 유의해야 합니다. 두 번째 그림은 MyService 클레임이 있는 SAML 토큰이 필요하다는 것을 accessAuthorized 나타냅니다. 보다 정확하게 말하자면, 필요한 클레임 유형을 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(보안 토큰 서비스)도 웹 서비스이며 연결된 엔드포인트, 정책 등을 포함할 수 있습니다.

보안 토큰 서비스 B를 보여 주는 다이어그램

STS B는 보안 토큰을 요청하는 데 사용할 수 있는 단일 STSEndpoint 엔드포인트를 노출합니다. 특히 STS B는 accessAuthorized 클레임을 포함하는 SAML 토큰을 발급하며, 이 토큰은 서비스에 액세스하기 위해 MyService 서비스 사이트에서 제출될 수 있습니다. 그러나 STS B를 사용하려면 사용자가 클레임을 포함하는 STS A에서 발급한 유효한 SAML 토큰을 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='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는 클레임과 함께 SAML 토큰을 발급합니다 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

다음 그림에서는 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 : 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

액세스 권한이 있는 경우 STS A는 true클레임을 사용하여 SAML 토큰 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)

조직 A의 클라이언트

다음 그림은 조직 A의 클라이언트가 MyService 서비스 호출을 수행하는 단계를 보여 줍니다. 완전성을 위해 다른 기능 구성 요소도 포함됩니다.

MyService 서비스 호출의 단계를 보여 주는 다이어그램

요약

페더레이션 보안은 책임의 깨끗한 분할을 제공하고 안전하고 확장 가능한 서비스 아키텍처를 구축하는 데 도움이 됩니다. 분산 애플리케이션을 빌드하고 배포하기 위한 플랫폼인 WCF는 페더레이션 보안 구현을 위한 기본 지원을 제공합니다.

참고하십시오