Aracılığıyla paylaş


Nasıl yapılır: Özel Bir Sertifika Doğrulayıcı Kullanan Bir Hizmet Oluşturma

Bu konu başlığında, özel sertifika doğrulayıcının nasıl uygulanacakları ve istemci veya hizmet kimlik bilgilerinin varsayılan sertifika doğrulama mantığını özel sertifika doğrulayıcıyla değiştirecek şekilde nasıl yapılandıracakları gösterilmektedir.

X.509 sertifikası bir istemcinin veya hizmetin kimliğini doğrulamak için kullanılıyorsa, Windows Communication Foundation (WCF), sertifikayı doğrulamak ve güvenilir olduğundan emin olmak için varsayılan olarak Windows sertifika deposunu ve Şifreleme API'sini kullanır. Bazen yerleşik sertifika doğrulama işlevi yeterli olmaz ve değiştirilmesi gerekir. WCF, kullanıcıların özel bir sertifika doğrulayıcı eklemesine izin vererek doğrulama mantığını değiştirmenin kolay bir yolunu sağlar. Özel bir sertifika doğrulayıcı belirtilirse, WCF yerleşik sertifika doğrulama mantığını kullanmaz, ancak bunun yerine özel doğrulayıcıyı kullanır.

Yordamlar

Özel sertifika doğrulayıcı oluşturmak için

  1. öğesinden X509CertificateValidatortüretilmiş yeni bir sınıf tanımlayın.

  2. Soyut Validate yöntemini uygulayın. Doğrulanması gereken sertifika yöntemine bağımsız değişken olarak geçirilir. Geçirilen sertifika doğrulama mantığına göre geçerli değilse, bu yöntem bir SecurityTokenValidationExceptionoluşturur. Sertifika geçerliyse, yöntemi çağırana geri döner.

    Not

    kimlik doğrulama hatalarını istemciye geri döndürmek için yöntemine Validate bir FaultException oluşturun.

public class MyX509CertificateValidator : X509CertificateValidator
{
    string allowedIssuerName;

    public MyX509CertificateValidator(string allowedIssuerName)
    {
        if (allowedIssuerName == null)
        {
            throw new ArgumentNullException("allowedIssuerName");
        }

        this.allowedIssuerName = allowedIssuerName;
    }

    public override void Validate(X509Certificate2 certificate)
    {
        // Check that there is a certificate.
        if (certificate == null)
        {
            throw new ArgumentNullException("certificate");
        }

        // Check that the certificate issuer matches the configured issuer.
        if (allowedIssuerName != certificate.IssuerName.Name)
        {
            throw new SecurityTokenValidationException
              ("Certificate was not issued by a trusted issuer");
        }
    }
}
Public Class MyX509CertificateValidator
    Inherits X509CertificateValidator
    Private allowedIssuerName As String

    Public Sub New(ByVal allowedIssuerName As String)
        If allowedIssuerName Is Nothing Then
            Throw New ArgumentNullException("allowedIssuerName")
        End If

        Me.allowedIssuerName = allowedIssuerName

    End Sub

    Public Overrides Sub Validate(ByVal certificate As X509Certificate2)
        ' Check that there is a certificate.
        If certificate Is Nothing Then
            Throw New ArgumentNullException("certificate")
        End If

        ' Check that the certificate issuer matches the configured issuer.
        If allowedIssuerName <> certificate.IssuerName.Name Then
            Throw New SecurityTokenValidationException _
              ("Certificate was not issued by a trusted issuer")
        End If

    End Sub
End Class

Hizmet yapılandırmasında özel bir sertifika doğrulayıcı belirtmek için

  1. system.serviceModel öğesine bir <behaviors> öğesi ve serviceBehaviors<<> ekleyin.>

  2. Bir <davranış> ekleyin ve özniteliğini name uygun bir değere ayarlayın.

  3. öğesine serviceCredentials <><behavior> ekleyin.

  4. öğesine bir <clientCertificate> öğe <serviceCredentials> ekleyin.

  5. öğesine bir <kimlik doğrulaması <clientCertificate>> ekleyin.

  6. özniteliğini customCertificateValidatorType doğrulayıcı türüne ayarlayın. Aşağıdaki örnek özniteliğini türün ad alanına ve adına ayarlar.

  7. özniteliğini certificateValidationMode olarak Customayarlayın.

    <configuration>  
     <system.serviceModel>  
      <behaviors>  
       <serviceBehaviors>  
        <behavior name="ServiceBehavior">  
         <serviceCredentials>  
          <clientCertificate>  
          <authentication certificateValidationMode="Custom" customCertificateValidatorType="Samples.MyValidator, service" />  
          </clientCertificate>  
         </serviceCredentials>  
        </behavior>  
       </serviceBehaviors>  
      </behaviors>  
    </system.serviceModel>  
    </configuration>  
    

İstemcide yapılandırma kullanarak özel bir sertifika doğrulayıcı belirtmek için

  1. system.serviceModel öğesine bir <behaviors> öğesi ve serviceBehaviors<<> ekleyin.>

  2. endpointBehaviors <> öğesi ekleyin.

  3. Bir <behavior> öğe ekleyin ve özniteliğini name uygun bir değere ayarlayın.

  4. clientCredentials <> öğesi ekleyin.

  5. ServiceCertificate <>ekleyin.

  6. Aşağıdaki örnekte gösterildiği gibi bir <kimlik doğrulaması> ekleyin.

  7. özniteliğini customCertificateValidatorType doğrulayıcı türüne ayarlayın.

  8. özniteliğini certificateValidationMode olarak Customayarlayın. Aşağıdaki örnek özniteliğini türün ad alanına ve adına ayarlar.

    <configuration>  
     <system.serviceModel>  
      <behaviors>  
       <endpointBehaviors>  
        <behavior name="clientBehavior">  
         <clientCredentials>  
          <serviceCertificate>  
           <authentication certificateValidationMode="Custom"
                  customCertificateValidatorType=  
             "Samples.CustomX509CertificateValidator, client"/>  
          </serviceCertificate>  
         </clientCredentials>  
        </behavior>  
       </endpointBehaviors>  
      </behaviors>  
     </system.serviceModel>  
    </configuration>  
    

Hizmette kod kullanarak özel bir sertifika doğrulayıcı belirtmek için

  1. özelliğinde özel sertifika doğrulayıcısını ClientCertificate belirtin. özelliğini kullanarak hizmet kimlik bilgilerine Credentials erişebilirsiniz.

  2. CertificateValidationMode özelliğini Custom olarak ayarlayın.

serviceHost.Credentials.ClientCertificate.Authentication.CertificateValidationMode =
    X509CertificateValidationMode.Custom;
serviceHost.Credentials.ClientCertificate.Authentication.CustomCertificateValidator =
    new MyX509CertificateValidator("CN=Contoso.com");
serviceHost.Credentials.ClientCertificate.Authentication. _
    CertificateValidationMode = X509CertificateValidationMode.Custom
serviceHost.Credentials.ClientCertificate.Authentication. _
   CustomCertificateValidator = New MyX509CertificateValidator("CN=Contoso.com")

İstemcide kod kullanarak özel bir sertifika doğrulayıcı belirtmek için

  1. özelliğini kullanarak özel sertifika doğrulayıcısını CustomCertificateValidator belirtin. özelliğini kullanarak istemci kimlik bilgilerine Credentials erişebilirsiniz. (tarafından oluşturulan istemci sınıfıServiceModel Meta Veri Yardımcı Programı Aracı (Svcutil.exe) her zaman sınıfından ClientBase<TChannel> türetilir.)

  2. CertificateValidationMode özelliğini Custom olarak ayarlayın.

Örnek

Açıklama

Aşağıdaki örnekte özel bir sertifika doğrulayıcının uygulaması ve hizmet üzerindeki kullanımı gösterilmektedir.

Kod

using System;
using System.IdentityModel.Selectors;
using System.IdentityModel.Tokens;
using System.Security.Cryptography.X509Certificates;
using System.ServiceModel;
using System.ServiceModel.Security;

namespace Microsoft.ServiceModel.Samples
{
    [ServiceContract(Namespace="http://Microsoft.ServiceModel.Samples")]
    public interface ICalculator
    {
        [OperationContract]
        double Add(double n1, double n2);
    }

    public class CalculatorService : ICalculator
    {
        public double Add(double n1, double n2)
        {
            double result = n1 + n2;
            return result;
        }
    }

    class Program
    {
        static void Main()
        {
            using (ServiceHost serviceHost = new ServiceHost(typeof(CalculatorService)))
            {
                serviceHost.Credentials.ClientCertificate.Authentication.CertificateValidationMode =
                    X509CertificateValidationMode.Custom;
                serviceHost.Credentials.ClientCertificate.Authentication.CustomCertificateValidator =
                    new MyX509CertificateValidator("CN=Contoso.com");

                serviceHost.Open();
                Console.WriteLine("Service started, press ENTER to stop ...");
                Console.ReadLine();

                serviceHost.Close();
            }
        }
    }

    public class MyX509CertificateValidator : X509CertificateValidator
    {
        string allowedIssuerName;

        public MyX509CertificateValidator(string allowedIssuerName)
        {
            if (allowedIssuerName == null)
            {
                throw new ArgumentNullException("allowedIssuerName");
            }

            this.allowedIssuerName = allowedIssuerName;
        }

        public override void Validate(X509Certificate2 certificate)
        {
            // Check that there is a certificate.
            if (certificate == null)
            {
                throw new ArgumentNullException("certificate");
            }

            // Check that the certificate issuer matches the configured issuer.
            if (allowedIssuerName != certificate.IssuerName.Name)
            {
                throw new SecurityTokenValidationException
                  ("Certificate was not issued by a trusted issuer");
            }
        }
    }
}
Imports System.IdentityModel.Selectors
Imports System.Security.Cryptography.X509Certificates
Imports System.ServiceModel
Imports System.ServiceModel.Security
Imports System.IdentityModel.Tokens
Imports System.Security.Permissions

<ServiceContract([Namespace]:="http://Microsoft.ServiceModel.Samples")> _
Public Interface ICalculator
    <OperationContract()> _
    Function Add(ByVal n1 As Double, ByVal n2 As Double) As Double
End Interface


Public Class CalculatorService
    Implements ICalculator

    Public Function Add(ByVal n1 As Double, ByVal n2 As Double) As Double _
       Implements ICalculator.Add
        Dim result As Double = n1 + n2
        Return result
    End Function
End Class


Class Program

    Shared Sub Main()
        Dim serviceHost As New ServiceHost(GetType(CalculatorService))
        Try
            serviceHost.Credentials.ClientCertificate.Authentication. _
                CertificateValidationMode = X509CertificateValidationMode.Custom
            serviceHost.Credentials.ClientCertificate.Authentication. _
               CustomCertificateValidator = New MyX509CertificateValidator("CN=Contoso.com")
            serviceHost.Open()
            Console.WriteLine("Service started, press ENTER to stop ...")
            Console.ReadLine()

            serviceHost.Close()
        Finally
            serviceHost.Close()
        End Try

    End Sub
End Class

Public Class MyX509CertificateValidator
    Inherits X509CertificateValidator
    Private allowedIssuerName As String

    Public Sub New(ByVal allowedIssuerName As String)
        If allowedIssuerName Is Nothing Then
            Throw New ArgumentNullException("allowedIssuerName")
        End If

        Me.allowedIssuerName = allowedIssuerName

    End Sub

    Public Overrides Sub Validate(ByVal certificate As X509Certificate2)
        ' Check that there is a certificate.
        If certificate Is Nothing Then
            Throw New ArgumentNullException("certificate")
        End If

        ' Check that the certificate issuer matches the configured issuer.
        If allowedIssuerName <> certificate.IssuerName.Name Then
            Throw New SecurityTokenValidationException _
              ("Certificate was not issued by a trusted issuer")
        End If

    End Sub
End Class

Ayrıca bkz.