Aracılığıyla paylaş


SAML Belirteç Sağlayıcısı

Bu örnek, özel istemci SAML belirteci sağlayıcısının nasıl uygulanduğunu gösterir. Güvenlik altyapısına kimlik bilgileri sağlamak için Windows Communication Foundation'da (WCF) bir belirteç sağlayıcısı kullanılır. Belirteç sağlayıcısı genel olarak hedefi inceler ve güvenlik altyapısının iletinin güvenliğini sağlayabilmesi için uygun kimlik bilgilerini verir. WCF, varsayılan Kimlik Bilgisi Yöneticisi Belirteç Sağlayıcısı ile birlikte gelir. WCF ayrıca bir CardSpace belirteç sağlayıcısıyla birlikte gelir. Özel jeton sağlayıcılar aşağıdaki durumlarda faydalıdır:

  • Bu belirteç sağlayıcılarının çalışamayacağı bir kimlik bilgisi deponuz varsa.

  • Kullanıcının ayrıntıları sağladığı noktadan WCF istemci çerçevesinin kimlik bilgilerini kullandığı noktaya kadar kimlik bilgilerini dönüştürmek için kendi özel mekanizmanızı sağlamak istiyorsanız.

  • Özel bir belirteç oluşturuyorsanız.

Bu örnek, WCF istemci çerçevesinin dışından alınan bir SAML belirtecinin kullanılmasına izin veren özel bir belirteç sağlayıcısının nasıl oluşturulacağı gösterilmektedir.

Özetlemek gerekirse, bu örnek aşağıdakileri gösterir:

  • Bir istemci özel bir belirteç sağlayıcı ile nasıl yapılandırılabilir?

  • SAML belirtecinin özel istemci kimlik bilgilerine nasıl aktarılabileceği.

  • SAML belirtecinin WCF istemci çerçevesine nasıl sağlandığı.

  • Sunucunun X.509 sertifikası kullanılarak istemci tarafından kimlik doğrulaması nasıl yapılır.

Hizmet, App.configyapılandırma dosyası kullanılarak tanımlanan hizmetle iletişim kurmak için iki uç noktayı kullanıma sunar. Her uç nokta bir adres, bağlama ve bir sözleşmeden oluşur. Bağlama, İleti güvenliğini kullanan standart wsFederationHttpBinding ile yapılandırılır. Bir uç nokta istemcinin simetrik yazım denetleme anahtarı kullanan bir SAML belirteci ile kimlik doğrulaması yapmasını beklerken, diğeri istemcinin asimetrik bir yazım denetleme anahtarı kullanan bir SAML belirteci ile kimlik doğrulaması yapmasını bekler. Hizmet, hizmet sertifikasını serviceCredentials tarzını kullanarak yapılandırıyor. Bu serviceCredentials davranış, bir hizmet sertifikası yapılandırmanıza olanak tanır. Hizmet sertifikası, istemci tarafından hizmetin kimliğini doğrulamak ve ileti koruması sağlamak için kullanılır. Aşağıdaki yapılandırma, bu konunun sonundaki kurulum yönergelerinde açıklandığı gibi örnek kurulum sırasında yüklenen "localhost" sertifikasına başvurur. Bu serviceCredentials davranış, SAML belirteçlerini imzalamak için güvenilen sertifikaları yapılandırmanıza da olanak tanır. Aşağıdaki yapılandırma, örnek sırasında yüklenen 'Alice' sertifikasına başvurur.

<system.serviceModel>
 <services>
  <service
          name="Microsoft.ServiceModel.Samples.CalculatorService"
          behaviorConfiguration="CalculatorServiceBehavior">
   <host>
    <baseAddresses>
     <!-- configure base address provided by host -->
     <add
  baseAddress="http://localhost:8000/servicemodelsamples/service/" />
    </baseAddresses>
   </host>
   <!-- use base address provided by host -->
   <!-- Endpoint that expect SAML tokens with Symmetric proof keys -->
   <endpoint address="calc/symm"
             binding="wsFederationHttpBinding"
             bindingConfiguration="Binding1"
             contract="Microsoft.ServiceModel.Samples.ICalculator" />
   <!-- Endpoint that expect SAML tokens with Asymmetric proof keys -->
   <endpoint address="calc/asymm"
             binding="wsFederationHttpBinding"
             bindingConfiguration="Binding2"
             contract="Microsoft.ServiceModel.Samples.ICalculator" />
  </service>
 </services>

 <bindings>
  <wsFederationHttpBinding>
   <!-- Binding that expect SAML tokens with Symmetric proof keys -->
   <binding name="Binding1">
    <security mode="Message">
     <message negotiateServiceCredential ="false"
              issuedKeyType="SymmetricKey"
              issuedTokenType="http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV1.1"  />
    </security>
   </binding>
   <!-- Binding that expect SAML tokens with Asymmetric proof keys -->
   <binding name="Binding2">
    <security mode="Message">
     <message negotiateServiceCredential ="false"
              issuedKeyType="AsymmetricKey"
              issuedTokenType="http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV1.1"  />
    </security>
   </binding>
  </wsFederationHttpBinding>
 </bindings>

 <behaviors>
  <serviceBehaviors>
   <behavior name="CalculatorServiceBehavior">
    <!--
    The serviceCredentials behavior allows one to define a service certificate.
    A service certificate is used by a client to authenticate the service and provide message protection.
    This configuration references the "localhost" certificate installed during the setup instructions.
    -->
    <serviceCredentials>
     <!-- Set allowUntrustedRsaIssuers to true to allow self-signed, asymmetric key based SAML tokens -->
     <issuedTokenAuthentication allowUntrustedRsaIssuers ="true" >
      <!-- Add Alice to the list of certs trusted to issue SAML tokens -->
      <knownCertificates>
       <add storeLocation="LocalMachine"
            storeName="TrustedPeople"
            x509FindType="FindBySubjectName"
            findValue="Alice"/>
      </knownCertificates>
     </issuedTokenAuthentication>
     <serviceCertificate storeLocation="LocalMachine"
                         storeName="My"
                         x509FindType="FindBySubjectName"
                         findValue="localhost"  />
    </serviceCredentials>
   </behavior>
  </serviceBehaviors>
 </behaviors>

</system.serviceModel>

Aşağıdaki adımlarda özel bir SAML belirteci sağlayıcısı geliştirme ve WCF ile tümleştirme adımları gösterilmektedir: güvenlik çerçevesi:

  1. Özel bir SAML belirteç sağlayıcısı yazın.

    Örnek, oluşturulma anında sağlanan bir SAML beyanını temel alarak bir güvenlik belirteci döndüren özel bir SAML belirteç sağlayıcısını uygular.

    Bu görevi gerçekleştirmek için, özel belirteç sağlayıcı SecurityTokenProvider sınıfından türetilir ve GetTokenCore yöntemini geçersiz kılar. Bu yöntem yeni bir SecurityToken oluşturur ve döndürür.

    protected override SecurityToken GetTokenCore(TimeSpan timeout)
    {
     // Create a SamlSecurityToken from the provided assertion
     SamlSecurityToken samlToken = new SamlSecurityToken(assertion);
    
     // Create a SecurityTokenSerializer that will be used to
     // serialize the SamlSecurityToken
     WSSecurityTokenSerializer ser = new WSSecurityTokenSerializer();
     // Create a memory stream to write the serialized token into
     // Use an initial size of 64Kb
     MemoryStream s = new MemoryStream(UInt16.MaxValue);
    
     // Create an XmlWriter over the stream
     XmlWriter xw = XmlWriter.Create(s);
    
     // Write the SamlSecurityToken into the stream
     ser.WriteToken(xw, samlToken);
    
     // Seek back to the beginning of the stream
     s.Seek(0, SeekOrigin.Begin);
    
     // Load the serialized token into a DOM
     XmlDocument dom = new XmlDocument();
     dom.Load(s);
    
     // Create a KeyIdentifierClause for the SamlSecurityToken
     SamlAssertionKeyIdentifierClause samlKeyIdentifierClause = samlToken.CreateKeyIdentifierClause<SamlAssertionKeyIdentifierClause>();
    
    // Return a GenericXmlToken from the XML for the
    // SamlSecurityToken, the proof token, the valid from and valid
    // until times from the assertion and the key identifier clause
    // created above
    return new GenericXmlSecurityToken(dom.DocumentElement, proofToken, assertion.Conditions.NotBefore, assertion.Conditions.NotOnOrAfter, samlKeyIdentifierClause, samlKeyIdentifierClause, null);
    }
    
  2. Özel bir güvenlik belirteci yöneticisi yazın.

    SecurityTokenManager sınıfı, SecurityTokenProvider yöntemine geçirilen belirli bir SecurityTokenRequirement için CreateSecurityTokenProvider oluşturmak amacıyla kullanılır. Güvenlik belirteci yöneticisi, belirteç kimlik doğrulayıcıları ve belirteç serileştiricisi oluşturmak için de kullanılır, ancak bunlar bu örnek kapsamında değildir. Bu örnekte, özel güvenlik belirteci yöneticisi ClientCredentialsSecurityTokenManager sınıfından devralır ve CreateSecurityTokenProvider yöntemini geçersiz kılarak, geçirilen belirteç gereksinimlerinin SAML belirtecinin istendiğini gösterdiği durumlarda özel SAML belirteç sağlayıcısını döndürür. İstemci kimlik bilgileri sınıfı (bkz. 3. adım) onay belirtmediyse, güvenlik belirteci yöneticisi uygun bir örnek oluşturur.

    public class SamlSecurityTokenManager : ClientCredentialsSecurityTokenManager
    {
     SamlClientCredentials samlClientCredentials;
    
     public SamlSecurityTokenManager ( SamlClientCredentials samlClientCredentials)
      : base(samlClientCredentials)
     {
      // Store the creating client credentials
      this.samlClientCredentials = samlClientCredentials;
     }
    
     public override SecurityTokenProvider CreateSecurityTokenProvider ( SecurityTokenRequirement tokenRequirement )
     {
      // If token requirement matches SAML token return the
      // custom SAML token provider
      if (tokenRequirement.TokenType == SecurityTokenTypes.Saml ||
          tokenRequirement.TokenType == "http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV1.1")
      {
       // Retrieve the SAML assertion and proof token from the
       // client credentials
       SamlAssertion assertion = this.samlClientCredentials.Assertion;
       SecurityToken prooftoken = this.samlClientCredentials.ProofToken;
    
       // If either the assertion of proof token is null...
       if (assertion == null || prooftoken == null)
       {
        // ...get the SecurityBindingElement and then the
        // specified algorithm suite
        SecurityBindingElement sbe = null;
        SecurityAlgorithmSuite sas = null;
    
        if ( tokenRequirement.TryGetProperty<SecurityBindingElement> ( "http://schemas.microsoft.com/ws/2006/05/servicemodel/securitytokenrequirement/SecurityBindingElement", out sbe))
        {
         sas = sbe.DefaultAlgorithmSuite;
        }
    
        // If the token requirement is for a SymmetricKey based token..
        if (tokenRequirement.KeyType == SecurityKeyType.SymmetricKey)
        {
         // Create a symmetric proof token
         prooftoken = SamlUtilities.CreateSymmetricProofToken ( tokenRequirement.KeySize );
         // and a corresponding assertion based on the claims specified in the client credentials
         assertion = SamlUtilities.CreateSymmetricKeyBasedAssertion ( this.samlClientCredentials.Claims, new X509SecurityToken ( samlClientCredentials.ClientCertificate.Certificate ), new X509SecurityToken ( samlClientCredentials.ServiceCertificate.DefaultCertificate ), (BinarySecretSecurityToken)prooftoken, sas);
        }
        // otherwise...
        else
        {
         // Create an asymmetric proof token
         prooftoken = SamlUtilities.CreateAsymmetricProofToken();
         // and a corresponding assertion based on the claims
         // specified in the client credentials
         assertion = SamlUtilities.CreateAsymmetricKeyBasedAssertion ( this.samlClientCredentials.Claims, prooftoken, sas );
        }
       }
    
       // Create a SamlSecurityTokenProvider based on the assertion and proof token
       return new SamlSecurityTokenProvider(assertion, prooftoken);
      }
      // otherwise use base implementation
      else
      {
       return base.CreateSecurityTokenProvider(tokenRequirement);
      }
    }
    
  3. Özel bir istemci kimlik bilgisi yazın.

    İstemci kimlik bilgileri sınıfı, istemci proxy'si için yapılandırılan kimlik bilgilerini temsil etmek için kullanılır ve belirteç doğrulayıcıları, belirteç sağlayıcılarını ve belirteç seri hale getiricisini almak için kullanılan bir güvenlik belirteci yöneticisi oluşturur.

    public class SamlClientCredentials : ClientCredentials
    {
     ClaimSet claims;
     SamlAssertion assertion;
     SecurityToken proofToken;
    
     public SamlClientCredentials() : base()
     {
      // Set SupportInteractive to false to suppress Cardspace UI
      base.SupportInteractive = false;
     }
    
     protected SamlClientCredentials(SamlClientCredentials other) : base ( other )
     {
      // Just do reference copy given sample nature
      this.assertion = other.assertion;
      this.claims = other.claims;
      this.proofToken = other.proofToken;
     }
    
     public SamlAssertion Assertion { get { return assertion; } set { assertion = value; } }
    
     public SecurityToken ProofToken { get { return proofToken; } set { proofToken = value; } }
     public ClaimSet Claims { get { return claims; } set { claims = value; } }
    
     protected override ClientCredentials CloneCore()
     {
      return new SamlClientCredentials(this);
     }
    
     public override SecurityTokenManager CreateSecurityTokenManager()
     {
      // return custom security token manager
      return new SamlSecurityTokenManager(this);
     }
    }
    
  4. İstemciyi özel istemci kimlik bilgilerini kullanacak şekilde yapılandırın.

    Örnek, varsayılan istemci kimlik bilgisi sınıfını siler ve istemcinin özel istemci kimlik bilgilerini kullanabilmesi için yeni istemci kimlik bilgisi sınıfını sağlar.

    // Create new credentials class
    SamlClientCredentials samlCC = new SamlClientCredentials();
    
    // Set the client certificate. This is the cert that will be used to sign the SAML token in the symmetric proof key case
    samlCC.ClientCertificate.SetCertificate(StoreLocation.CurrentUser, StoreName.My, X509FindType.FindBySubjectName, "Alice");
    
    // Set the service certificate. This is the cert that will be used to encrypt the proof key in the symmetric proof key case
    samlCC.ServiceCertificate.SetDefaultCertificate(StoreLocation.CurrentUser, StoreName.TrustedPeople, X509FindType.FindBySubjectName, "localhost");
    
    // Create some claims to put in the SAML assertion
    IList<Claim> claims = new List<Claim>();
    claims.Add(Claim.CreateNameClaim(samlCC.ClientCertificate.Certificate.Subject));
    ClaimSet claimset = new DefaultClaimSet(claims);
    samlCC.Claims = claimset;
    
    // set new credentials
    client.ChannelFactory.Endpoint.Behaviors.Remove(typeof(ClientCredentials));
    client.ChannelFactory.Endpoint.Behaviors.Add(samlCC);
    

Çağıran kişiyle ilişkili iddialar, hizmette görüntülenir. Örneği çalıştırdığınızda, işlem istekleri ve yanıtları istemci konsolu penceresinde görüntülenir. İstemciyi kapatmak için istemci penceresinde ENTER tuşuna basın.

Batch Dosyasını Ayarlama

Bu örneğe dahil olan Setup.bat toplu dosyası, sunucuyu ilgili sertifikayla yapılandırmanıza ve sunucu sertifikası tabanlı güvenlik gerektiren özyönetimli bir uygulamayı çalıştırmanıza olanak tanır. Bu toplu iş dosyası, bilgisayarlar arasında çalışacak veya barındırılmayan bir durumda çalışacak şekilde değiştirilmelidir.

Aşağıda, toplu iş dosyalarının farklı bölümlerine ilişkin kısa bir genel bakış sağlanır, böylece bunlar uygun yapılandırmada çalıştırılacak şekilde değiştirilebilir.

  • Sunucu sertifikası oluşturuluyor:

    Setup.bat toplu iş dosyasındaki aşağıdaki satırlar kullanılacak sunucu sertifikasını oluşturur. %SERVER_NAME% değişkeni sunucu adını belirtir. Kendi sunucu adınızı belirtmek için bu değişkeni değiştirin. Bu toplu iş dosyasındaki varsayılan değer localhost'tır.

    Sertifika, LocalMachine depolama konumu altında My (Personal) deposunda depolanır.

    echo ************
    echo Server cert setup starting
    echo %SERVER_NAME%
    echo ************
    echo making server cert
    echo ************
    makecert.exe -sr LocalMachine -ss My -a sha1 -n CN=%SERVER_NAME% -sky exchange -pe
    
  • Sunucu sertifikasını istemcinin güvenilen sertifika deposuna yükleme:

    Setup.bat toplu iş dosyasındaki aşağıdaki satırlar sunucu sertifikasını istemcinin güvenilen kişiler deposuna kopyalar. Makecert.exe tarafından oluşturulan sertifikalara istemci sistemi tarafından örtük olarak güvenilmediğinden bu adım gereklidir. İstemci güvenilen kök sertifikasında (örneğin, Microsoft tarafından verilen bir sertifika) köke sahip bir sertifikanız zaten varsa, istemci sertifika depoyu sunucu sertifikasıyla doldurma adımı gerekli değildir.

    certmgr.exe -add -r LocalMachine -s My -c -n %SERVER_NAME% -r LocalMachine -s TrustedPeople
    
  • Veren sertifika oluşturuluyor.

    Setup.bat yığın dosyasındaki aşağıdaki satırlar, kullanılacak verici sertifikasını oluşturur. %USER_NAME% değişkeni, verenin adını belirtir. Kendi veren adınızı belirtmek için bu değişkeni değiştirin. Bu toplu iş dosyasındaki varsayılan değer Alice'tir.

    Sertifika, Geçerli Kullanıcı mağaza konumu altında Benim Mağazam'da saklanır.

    echo ************
    echo Server cert setup starting
    echo %SERVER_NAME%
    echo ************
    echo making server cert
    echo ************
    makecert.exe -sr CurrentUser -ss My -a sha1 -n CN=%USER_NAME% -sky exchange -pe
    
  • Veren sertifikayı sunucunun güvenilen sertifika deposuna yükleme.

    Setup.bat toplu iş dosyasındaki aşağıdaki satırlar sunucu sertifikasını istemcinin güvenilen kişiler deposuna kopyalar. Makecert.exe tarafından oluşturulan sertifikalara istemci sistemi tarafından örtük olarak güvenilmediğinden bu adım gereklidir. Eğer zaten bir istemci tarafından güvenilen kök sertifikasına (örneğin, Microsoft tarafından verilen bir sertifika) dayanan bir sertifikanız varsa, sunucu sertifika deposunu veren sertifikayla doldurma adımını atlayabilirsiniz.

    certmgr.exe -add -r CurrentUser -s My -c -n %USER_NAME% -r LocalMachine -s TrustedPeople
    

Örneği ayarlamak ve derlemek için

  1. Windows Communication Foundation Örnekleri içinOne-Time Kurulum Yordamını yaptığınızdan emin olun.

  2. Çözümü oluşturmak için Windows Communication Foundation Örnekleri Oluşturma başlığındaki yönergeleri izleyin.

Uyarı

Bu örneğin yapılandırmasını yeniden oluşturmak için Svcutil.exe kullanıyorsanız, istemci yapılandırmasındaki uç nokta adını istemci koduyla eşleşecek şekilde değiştirdiğinizden emin olun.

Örneği aynı bilgisayarda çalıştırmak için

  1. Visual Studio komut istemi içindeki örnek yükleme klasöründen Setup.bat yönetici ayrıcalıklarıyla çalıştırın. Bu, örneği çalıştırmak için gereken tüm sertifikaları yükler.

    Uyarı

    Setup.bat toplu iş dosyası, Visual Studio Komut İsteminden çalıştırılacak şekilde tasarlanmıştır. Visual Studio Komut İstemi içinde ayarlanan PATH ortam değişkeni, Setup.bat betiği tarafından gereken yürütülebilir dosyaları içeren dizini işaret eder.

  2. service\bin konumundan Service.exe başlatın.

  3. \client\bin konumundan Client.exe başlatın. İstemci etkinliği, istemci konsol uygulamasında görüntülenir.

  4. İstemci ve hizmet iletişim kuramıyorsa bkz. WCF Örnekleri için Sorun Giderme İpuçları.

Örneği bilgisayarlar arasında çalıştırmak için

  1. Hizmet ikili dosyaları için hizmet bilgisayarında bir dizin oluşturun.

  2. Hizmet programı dosyalarını hizmet bilgisayarındaki hizmet dizinine kopyalayın. Ayrıca Setup.bat ve Cleanup.bat dosyalarını hizmet bilgisayarına kopyalayın.

  3. Bilgisayarın tam etki alanı adını içeren bir konu başlığına sahip bir sunucu sertifikanız olmalıdır. Service.exe.config dosyası bu yeni sertifika adını yansıtacak şekilde güncelleştirilmelidir. Setup.bat toplu iş dosyasını değiştirerek sunucu sertifikası oluşturabilirsiniz. setup.bat dosyasının yönetici ayrıcalıklarıyla açılan Visual Studio için Geliştirici Komut İstemi penceresinde çalıştırılması gerektiğini unutmayın. %SERVER_NAME% değişkenini, hizmeti barındırmak için kullanılan bilgisayarın tam ana bilgisayar adına ayarlamalısınız.

  4. Sunucu sertifikasını istemcinin CurrentUser-TrustedPeople deposuna kopyalayın. Sunucu sertifikası istemcinin güvenilen bir vereni tarafından verildiğinde bu adım gerekli değildir.

  5. Hizmet bilgisayarındaki Service.exe.config dosyasında, localhost yerine tam bilgisayar adı belirtmek için temel adresin değerini değiştirin.

  6. Hizmet bilgisayarında bir komut isteminden Service.exe çalıştırın.

  7. \client\bin\ klasöründeki, dile özgü klasörün altındaki istemci program dosyalarını istemci bilgisayara kopyalayın.

  8. İstemci bilgisayardaki Client.exe.config dosyasında, uç noktanın adres değerini hizmetinizin yeni adresiyle eşleşecek şekilde değiştirin.

  9. İstemci bilgisayarda, bir komut istemi penceresinden başlatın Client.exe .

  10. İstemci ve hizmet iletişim kuramıyorsa bkz. WCF Örnekleri için Sorun Giderme İpuçları.

Örnekten sonra temizlik yapmak için

  1. Örneği çalıştırmayı bitirdikten sonra örnekler klasöründe Cleanup.bat çalıştırın.