Windows uygulamaları arasında sertifika paylaşma

Kullanıcı kimliği ve parola bileşimi dışında güvenli kimlik doğrulaması gerektiren Windows uygulamaları, kimlik doğrulaması için sertifikaları kullanabilir. Sertifika kimlik doğrulaması, kullanıcının kimliğini doğrularken yüksek düzeyde güven sağlar. Bazı durumlarda, bir hizmet grubu birden çok uygulama için kullanıcının kimliğini doğrulamak ister. Bu makalede, aynı sertifikayı kullanarak birden çok Windows uygulamasının kimliğini nasıl doğrulayabileceğiniz ve kullanıcıların güvenli web hizmetlerine access için sağlanan bir sertifikayı içeri aktarmaları için nasıl bir yöntem sağlayabileceğiniz gösterilmektedir.

Uygulamalar bir sertifika kullanarak bir web hizmetinde kimlik doğrulaması yapabilir ve birden çok uygulama aynı kullanıcının kimliğini doğrulamak için sertifika deposundan tek bir sertifika kullanabilir. Depoda bir sertifika yoksa, PFX dosyasından bir sertifika yüklemek için uygulamanıza kod ekleyebilirsiniz. Bu hızlı başlangıçtaki istemci uygulaması bir WinUI 3 uygulamasıdır ve web hizmeti ASP.NET Core bir web API'dir.

Tavsiye

Microsoft Copilot, Windows uygulamaları veya ASP.NET Core web API'leri yazmaya başlangıç yapma hakkında sorularınız varsa harika bir kaynaktır. Copilot kod yazmanıza, örnekler bulmanıza ve güvenli uygulamalar oluşturmaya yönelik en iyi yöntemler hakkında daha fazla bilgi edinmenize yardımcı olabilir.

Önkoşullar

Güvenli web hizmeti oluşturma ve yayımlama

  1. Microsoft Visual Studio açın ve başlangıç ekranından Yeni bir project oluştur'u seçin.

  2. Yeni bir proje oluştur iletişim kutusunda, proje türü seçim listesinde API seçeneğini belirleyerek kullanılabilir proje şablonlarını filtreleyin.

  3. ASP.NET Core Web API şablonunu seçin ve İleri'i seçin.

  4. Uygulamayı "FirstContosoBank" olarak adlandırın ve İleri'yi seçin.

  5. .NET 8.0 veya daha yenisini çerçeve olarak seçin, Kimlik doğrulama türünüYok olarak ayarlayın, HTTPS için yapılandır seçeneğinin işaretli olduğundan emin olun, OpenAPI desteğini etkinleştirmeyin, Üst düzey ifadeleri kullanmayın ve Denetleyicileri kullan, ardından Oluştur öğesini seçin.

    ASP.NET Core web API projesi için yeni proje ayrıntıları oluşturma Visual Studio ekran görüntüsü

  6. Denetleyicilerklasöründeki WeatherForecastController.cs dosyasına sağ tıklayın ve Yeniden Adlandır'ı seçin. Adı BankController.cs olarak değiştirin ve Visual Studio sınıfı ve sınıfın tüm başvurularını yeniden adlandırmasına izin verin.

  7. launchSettings.json dosyasında, değeri kullanan üç yapılandırma için de "launchUrl" değerini "weatherforecast" yerine "bank" olarak değiştirin.

  8. BankController.cs dosyasına aşağıdaki "Login" yöntemini ekleyin.

    [HttpGet]
    [Route("login")]
    public string Login()
    {
        // Return any value you like here.
        // The client is just looking for a 200 OK response.
        return "true";
    }
    
  9. NuGet Package Manager açın ve Microsoft.AspNetCore.Authentication.Certificate paketinin en son kararlı sürümünü arayın ve yükleyin. Bu paket, ASP.NET Core sertifika kimlik doğrulaması için ara yazılım sağlar.

  10. Yeni bir sınıf ekleyin ve adına SecureCertificateValidationService deyin; projeye dahil edin. Sertifika kimlik doğrulaması ara yazılımını yapılandırmak için sınıfına aşağıdaki kodu ekleyin.

    using System.Security.Cryptography.X509Certificates;
    
    public class SecureCertificateValidationService
    {
        public bool ValidateCertificate(X509Certificate2 clientCertificate)
        {
            // Values are hard-coded for this example.
            // You should load your valid thumbprints from a secure location.
            string[] allowedThumbprints = { "YOUR_CERTIFICATE_THUMBPRINT_1", "YOUR_CERTIFICATE_THUMBPRINT_2" };
            if (allowedThumbprints.Contains(clientCertificate.Thumbprint))
            {
                return true;
            }
        }
    }
    
  11. Program.cs açın ve Main yöntemindeki kodu aşağıdaki kodla değiştirin:

    public static void Main(string[] args)
    {
        var builder = WebApplication.CreateBuilder(args);
    
        // Add our certificate validation service to the DI container.
        builder.Services.AddTransient<SecureCertificateValidationService>();
    
        builder.Services.Configure<KestrelServerOptions>(options =>
        {
            // Configure Kestrel to require a client certificate.
            options.ConfigureHttpsDefaults(options =>
            {
                options.ClientCertificateMode = ClientCertificateMode.RequireCertificate;
                options.AllowAnyClientCertificate();
            });
        });
    
        builder.Services.AddControllers();
    
        // Add certificate authentication middleware.
        builder.Services.AddAuthentication(
        CertificateAuthenticationDefaults.AuthenticationScheme)
           .AddCertificate(options =>
        {
            options.AllowedCertificateTypes = CertificateTypes.SelfSigned;
            options.Events = new CertificateAuthenticationEvents
            {
                // Validate the certificate with the validation service.
                OnCertificateValidated = context =>
                {
                    var validationService = context.HttpContext.RequestServices.GetService<SecureCertificateValidationService>();
    
                    if (validationService.ValidateCertificate(context.ClientCertificate))
                    {
                        context.Success();
                    }
                    else
                    {
                        context.Fail("Invalid certificate");
                    }
    
                    return Task.CompletedTask;
                },
                OnAuthenticationFailed = context =>
                {
                    context.Fail("Invalid certificate");
                    return Task.CompletedTask;
                }
            };
         });
    
         var app = builder.Build();
    
         // Add authentication/authorization middleware.
         app.UseHttpsRedirection();
         app.UseAuthentication();
         app.UseAuthorization();
    
         app.MapControllers();
         app.Run();
     }
    

    Yukarıdaki kod, Kestrel sunucusunu bir istemci sertifikası gerektirecek şekilde yapılandırıyor ve uygulamaya sertifika kimlik doğrulaması ara yazılımını ekliyor. Ara yazılım, SecureCertificateValidationService sınıfını kullanarak istemci sertifikasını doğrular. Olay OnCertificateValidated , bir sertifika doğrulandığında çağrılır. Sertifika geçerliyse, olay yöntemini çağırır Success . Sertifika geçersizse, olay bir hata iletisiyle Fail yöntemini çağırır ve bu mesaj istemciye geri gönderilir.

  12. Web hizmetini başlatmak için projede hata ayıklamaya başlayın. SSL sertifikasına güvenme ve yükleme hakkında iletiler alabilirsiniz. Sertifikaya güvenmek ve project hata ayıklamaya devam etmek için bu iletilerin her biri için Yes öğesine tıklayın.

    Kullanıcıya sertifikaya güvenmek isteyip istemediğini soran bir iletişim kutusunun ekran görüntüsü

    Kullanıcıya sertifika yüklemek isteyip istemediğini soran bir Windows iletişim kutusunun ekran görüntüsü

  13. Web hizmeti adresinde https://localhost:7072/bankkullanılabilir olacaktır. Web tarayıcısını açıp web adresini girerek web hizmetini test edebilirsiniz. Oluşturulan hava durumu tahmin verileriniN JSON olarak biçimlendirildiğini görürsünüz. İstemci uygulamasını oluştururken web hizmetini çalışır durumda tutun.

denetleyici tabanlı ASP.NET Core web API'leriyle çalışma hakkında daha fazla bilgi için bkz. ASP.NET Core.

Sertifika kimlik doğrulaması kullanan bir WinUI uygulaması oluşturma

Artık bir veya daha fazla güvenli web hizmetiniz olduğuna göre, uygulamalarınız bu web hizmetlerinde kimlik doğrulaması yapmak için sertifikaları kullanabilir. WinRT API'lerinden HttpClient nesnesini kullanarak kimliği doğrulanmış bir web hizmetine istekte bulunursanız, ilk istek bir istemci sertifikası içermez. Kimliği doğrulanmış web hizmeti, istemci kimlik doğrulaması isteğiyle yanıt verir. Bu durumda, Windows istemcisi kullanılabilir istemci sertifikaları için sertifika deposunu otomatik olarak sorgular. Kullanıcınız web hizmetinde kimlik doğrulaması yapmak için bu sertifikalardan birini seçebilir. Bazı sertifikalar parola korumalıdır, bu nedenle kullanıcıya bir sertifikanın parolasını girme yolu sağlamanız gerekir.

Uyarı

Sertifikaları yönetmek için henüz Windows App SDK API'leri yok. Uygulamanızdaki sertifikaları yönetmek için WinRT API'lerini kullanmanız gerekir. Bir PFX dosyasından sertifika içeri aktarmak için WinRT storage API'lerini de kullanacağız. Birçok WinRT API'si, WinUI uygulamaları dahil olmak üzere paket kimliğine sahip herhangi bir Windows app tarafından kullanılabilir.

Uygulayacağımız HTTP istemci kodu, .NET HttpClient kullanır. WinRT API'lerine dahil edilen HttpClient , istemci sertifikalarını desteklemez.

Kullanılabilir istemci sertifikası yoksa, kullanıcının sertifika deposuna bir sertifika eklemesi gerekir. Uygulamanıza kullanıcının istemci sertifikası içeren bir PFX dosyası seçmesini ve ardından bu sertifikayı istemci sertifika deposuna aktarmasını sağlayan kodu ekleyebilirsiniz.

Tavsiye

Otomatik olarak imzalanan bir sertifika oluşturmak ve bu hızlı başlangıçta kullanmak üzere bir PFX dosyasına aktarmak için New-SelfSignedCertificate ve Export-PfxCertificate PowerShell cmdlet'lerini kullanabilirsiniz. Bilgi için bkz. New-SelfSignedCertificate ve Export-PfxCertificate.

Sertifikayı oluştururken, doğrulama için web hizmetinde kullanılacak sertifikanın parmak izini kaydetmeniz gerektiğini unutmayın.

  1. Visual Studio açın ve başlangıç sayfasından yeni bir WinUI project oluşturun. Yeni projeyi "FirstContosoBankApp" olarak adını koyun. Yeni project oluşturmak için Create öğesine tıklayın.

  2. MainWindow.xaml dosyasında, mevcut StackPanel öğesini ve içeriğini değiştirerek aşağıdaki XAML'yi bir Grid öğesine ekleyin. Bu XAML, içeri aktaracak PFX dosyasına göz atmak için bir düğme, parola korumalı PFX dosyası için parola girmek için bir metin kutusu, seçili PFX dosyasını içeri aktarma düğmesi, güvenli web hizmetinde oturum açmak için bir düğme ve geçerli eylemin durumunu görüntülemek için bir metin bloğu içerir.

    <Button x:Name="Import" Content="Import Certificate (PFX file)" HorizontalAlignment="Left" Margin="352,305,0,0" VerticalAlignment="Top" Height="77" Width="260" Click="Import_Click" FontSize="16"/>
    <Button x:Name="Login" Content="Login" HorizontalAlignment="Left" Margin="611,305,0,0" VerticalAlignment="Top" Height="75" Width="240" Click="Login_Click" FontSize="16"/>
    <TextBlock x:Name="Result" HorizontalAlignment="Left" Margin="355,398,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Height="153" Width="560"/>
    <PasswordBox x:Name="PfxPassword" HorizontalAlignment="Left" Margin="483,271,0,0" VerticalAlignment="Top" Width="229"/>
    <TextBlock HorizontalAlignment="Left" Margin="355,271,0,0" TextWrapping="Wrap" Text="PFX password" VerticalAlignment="Top" FontSize="18" Height="32" Width="123"/>
    <Button x:Name="Browse" Content="Browse for PFX file" HorizontalAlignment="Left" Margin="352,189,0,0" VerticalAlignment="Top" Click="Browse_Click" Width="499" Height="68" FontSize="16"/>
    <TextBlock HorizontalAlignment="Left" Margin="717,271,0,0" TextWrapping="Wrap" Text="(Optional)" VerticalAlignment="Top" Height="32" Width="83" FontSize="16"/>
    
  3. MainWindow değişikliklerini kaydedin.

  4. MainWindow.xaml.cs dosyasını açın ve aşağıdaki using deyimleri ekleyin.

    using System;
    using System.Security.Cryptography.X509Certificates;
    using System.Diagnostics;
    using System.Net.Http;
    using System.Net;
    using System.Text;
    using Microsoft.UI.Xaml;
    using Windows.Security.Cryptography.Certificates;
    using Windows.Storage.Pickers;
    using Windows.Storage;
    using Windows.Storage.Streams;
    
  5. MainWindow.xaml.cs dosyasında MainWindow sınıfına aşağıdaki değişkenleri ekleyin. "FirstContosoBank" web hizmetinizin güvenli oturum açma hizmeti uç noktasının adresini ve sertifika deposuna içeri aktarılacak PFX sertifikasını barındıran bir genel değişkeni belirtir. <server-name>'yi localhost:7072'ye veya API projenizin launchSettings.json dosyasındaki "https" yapılandırmasında belirtilen bağlantı noktasına güncelleyin.

    private Uri requestUri = new Uri("https://<server-name>/bank/login");
    private string pfxCert = null;
    
  6. MainWindow.xaml.cs dosyasında, oturum açma düğmesi için aşağıdaki tıklama işleyicisini ve güvenli web hizmetine erişmek için yöntemi ekleyin.

    private void Login_Click(object sender, RoutedEventArgs e)
    {
        MakeHttpsCall();
    }
    
    private async void MakeHttpsCall()
    {
        var result = new StringBuilder("Login ");
    
        // Load the certificate
        var certificate = new X509Certificate2(Convert.FromBase64String(pfxCert),
                                               PfxPassword.Password);
    
        // Create HttpClientHandler and add the certificate
        var handler = new HttpClientHandler();
        handler.ClientCertificates.Add(certificate);
        handler.ClientCertificateOptions = ClientCertificateOption.Automatic;
    
        // Create HttpClient with the handler
        var client = new HttpClient(handler);
    
        try
        {
            // Make a request
            var response = await client.GetAsync(requestUri);
    
            if (response.StatusCode == HttpStatusCode.OK)
            {
                result.Append("successful");
            }
            else
            {
                result = result.Append("failed with ");
                result = result.Append(response.StatusCode);
            }
        }
        catch (Exception ex)
        {
            result = result.Append("failed with ");
            result = result.Append(ex.Message);
        }
    
        Result.Text = result.ToString();
    }
    
  7. Ardından, bir PFX dosyasına göz atmak için düğme için aşağıdaki tıklama işleyicilerini ve seçili pfx dosyasını sertifika deposuna içeri aktarma düğmesini ekleyin.

    private async void Import_Click(object sender, RoutedEventArgs e)
    {
        try
        {
            Result.Text = "Importing selected certificate into user certificate store....";
            await CertificateEnrollmentManager.UserCertificateEnrollmentManager.ImportPfxDataAsync(
                  pfxCert,
                  PfxPassword.Password,
                  ExportOption.Exportable,
                  KeyProtectionLevel.NoConsent,
                  InstallOptions.DeleteExpired,
                  "Import Pfx");
    
            Result.Text = "Certificate import succeeded";
        }
        catch (Exception ex)
        {
            Result.Text = "Certificate import failed with " + ex.Message;
        }
    }
    
    private async void Browse_Click(object sender, RoutedEventArgs e)
    {
        var result = new StringBuilder("Pfx file selection ");
        var pfxFilePicker = new FileOpenPicker();
        IntPtr hwnd = WinRT.Interop.WindowNative.GetWindowHandle(this);
        WinRT.Interop.InitializeWithWindow.Initialize(pfxFilePicker, hwnd);
        pfxFilePicker.FileTypeFilter.Add(".pfx");
        pfxFilePicker.CommitButtonText = "Open";
        try
        {
            StorageFile pfxFile = await pfxFilePicker.PickSingleFileAsync();
            if (pfxFile != null)
            {
                IBuffer buffer = await FileIO.ReadBufferAsync(pfxFile);
                using (DataReader dataReader = DataReader.FromBuffer(buffer))
                {
                    byte[] bytes = new byte[buffer.Length];
                    dataReader.ReadBytes(bytes);
                    pfxCert = System.Convert.ToBase64String(bytes);
                    PfxPassword.Password = string.Empty;
                    result.Append("succeeded");
                }
            }
            else
            {
                result.Append("failed");
            }
        }
        catch (Exception ex)
        {
            result.Append("failed with ");
            result.Append(ex.Message); ;
        }
    
        Result.Text = result.ToString();
    }
    
  8. Package.appxmanifest dosyasını açın ve Özellikler sekmesine aşağıdaki özellikleri ekleyin.

    • EnterpriseAuthentication (Kurumsal Kimlik Doğrulama)
    • SharedUserCertificates
  9. Uygulamanızı çalıştırın, güvenli web hizmetinizde oturum açın ve yerel sertifika deposuna bir PFX dosyası içeri aktarın.

    PFX dosyasına göz atmak, sertifikayı içeri aktarmak ve güvenli bir web hizmetinde oturum açmak için düğmeler içeren WinUI uygulamasının ekran görüntüsü

Aynı veya farklı güvenli web hizmetlerini access için aynı kullanıcı sertifikasını kullanan birden çok uygulama oluşturmak için bu adımları kullanabilirsiniz.

Windows Hello

Güvenlik ve kimlik

ASP.NET Core