Condividere i certificati tra le app

Le app UWP (Universal Windows Platform) che richiedono un'autenticazione sicura oltre a una combinazione di ID utente e password possono usare certificate per l'autenticazione. L'autenticazione del certificato offre un livello elevato di attendibilità durante l'autenticazione di un utente. In alcuni casi, un gruppo di servizi vorrà autenticare un utente per più app. Questo articolo mostra come sia possibile autenticare più app usando lo stesso certificato e come sia possibile fornire un codice comodo che consenta all'utente di importare un certificato fornito per accedere a servizi Web protetti.

Le app possono eseguire l'autenticazione a un servizio Web usando un certificato e più app possono usare un singolo certificato dall'archivio certificati per autenticare lo stesso utente. Se un certificato non esiste nell'archivio, è possibile aggiungere codice all'app per importare un certificato da un file PFX.

Abilitare Microsoft Internet Information Services (IIS) e il mapping dei certificati client

Questo articolo usa Microsoft Internet Information Services (IIS) a scopo di esempio. Per impostazione predefinita, la funzionalità IIS non è abilitata. È possibile abilitare IIS usando il Pannello di controllo.

  1. Aprire il Pannello di controllo e selezionare Programmi.
  2. Selezionare Attivazione o disattivazione delle funzionalità di Windows.
  3. Espandere Internet Information Services e quindi espandere World Wide Web Services. Espandere Funzionalità di sviluppo di applicazione e selezionare ASP.NET 3.5 e ASP.NET 4.5. Se si effettuano queste selezioni, Internet Information Services verrà abilitato automaticamente.
  4. Per rendere effettive le modifiche, fare clic su OK.

Creare e pubblicare un servizio Web sicuro

  1. Eseguire Microsoft Visual Studio come amministratore e selezionare Nuovo progetto nella pagina iniziale. L'accesso come amministratore è necessario per pubblicare un servizio Web in un server IIS. Nella finestra di dialogo Nuovo progetto modificare il framework in .NET Framework 3.5. Selezionare Visual C# ->Web ->Visual Studio ->ASP.NET Web Service Application. Assegnare all'applicazione il nome "FirstContosoBank". Fare clic su OK per creare il progetto.

  2. Nel file Service1.asmx.cs sostituire il metodo Web HelloWorld predefinito con il metodo "Login" seguente.

            [WebMethod]
            public string Login()
            {
                // Verify certificate with CA
                var cert = new System.Security.Cryptography.X509Certificates.X509Certificate2(
                    this.Context.Request.ClientCertificate.Certificate);
                bool test = cert.Verify();
                return test.ToString();
            }
    
  3. Salvare il file Service1.asmx.cs.

  4. In Solution Explorer, fare clic con il tasto destro del mouse sull'app "FirstContosoBank" e selezionare Publish.

  5. Nella finestra di dialogo Pubblica web creare un nuovo profilo e denominarlo "ContosoProfile". Fare clic su Avanti.

  6. Nella pagina successiva immettere il nome del server IIS e specificare il nome del sito "Sito Web predefinito/FirstContosoBank". Fare clic su Publish per pubblicare il servizio Web.

Configurare il servizio Web per l'uso dell'autenticazione del certificato client

  1. Eseguire Gestione Internet Information Services (IIS).
  2. Espandere i siti per il server IIS. Nel sito Web predefinito selezionare il nuovo servizio Web "FirstContosoBank". Nella sezione Azioni selezionare Impostazioni avanzate....
  3. Impostare il pool di applicazioni su .NET v2.0 e fare clic su OK.
  4. In Gestione Internet Information Services (IIS) selezionare il server IIS e quindi fare doppio clic su Certificati server. Nella sezione Azioni selezionare Crea certificato autofirmato.... Immettere "ContosoBank" come nome descrittivo per il certificato e fare clic su OK. Verrà creato un nuovo certificato da usare dal server IIS sotto forma di "<nome-server>.<nome-dominio>".
  5. In Internet Information Services (IIS) Manager, selezionare il Sito Web predefinito. Nella sezione Azioni selezionare Binding e quindi fare clic su Aggiungi.... Selezionare "https" come tipo, impostare la porta su "443" e immettere il nome host completo per il server IIS ("<nome-server>.<nome-dominio>"). Impostare il certificato SSL su "ContosoBank". Fare clic su OK. Fare clic su Chiudi nella finestra Site Bindings.
  6. In Gestione Internet Information Services (IIS) selezionare il servizio Web "FirstContosoBank". Fare doppio clic su Impostazioni SSL. Selezionare Richiedere SSL. In Certificati client selezionare Richiedi. Nella sezione Azioni fare clic su Applica.
  7. È possibile verificare che il servizio Web sia configurato correttamente aprendo il Web browser e immettendo l'indirizzo Web seguente: "https://<server-name>.<domain-name>/FirstContosoBank/Service1.asmx". Ad esempio, "https://myserver.example.com/FirstContosoBank/Service1.asmx". Se il servizio Web è configurato correttamente, verrà richiesto di selezionare un certificato client per accedere al servizio Web.

È possibile ripetere i passaggi precedenti per creare più servizi Web a cui è possibile accedere usando lo stesso certificato client.

Creare un'app UWP che usa l'autenticazione del certificato

Ora che si dispone di uno o più servizi Web protetti, le app possono usare i certificati per l'autenticazione a tali servizi Web. Quando si effettua una richiesta a un servizio Web autenticato usando l'oggetto HttpClient, la richiesta iniziale non conterrà un certificato client. Il servizio Web autenticato risponderà con una richiesta di autenticazione client. In questo caso, il client Windows eseguirà automaticamente una query sull'archivio certificati per i certificati client disponibili. L'utente può selezionare da questi certificati per l'autenticazione al servizio Web. Alcuni certificati sono protetti da password, quindi sarà necessario fornire all'utente un modo per immettere la password per un certificato.

Se non sono disponibili certificati client, l'utente dovrà aggiungere un certificato all'archivio certificati. È possibile includere codice nell'app che consente a un utente di selezionare un file PFX che contiene un certificato client e quindi importarlo nell'archivio certificati client.

Suggerimento È possibile usare makecert.exe per creare un file PFX da usare con questa guida introduttiva. Per informazioni sull'uso di makecert.exe, vedere MakeCert.

 

  1. Aprire Visual Studio e creare un nuovo progetto dalla pagina di avvio. Denominare il nuovo progetto "FirstContosoBankApp". Fare clic su OK per creare il nuovo progetto.

  2. Nel file MainPage.xaml aggiungere il codice XAML seguente all'elemento Grid predefinito. Questo codice XAML include un pulsante per cercare un file PFX da importare, una casella di testo per immettere una password per un file PFX protetto da password, un pulsante per importare un file PFX selezionato, un pulsante per accedere al servizio Web protetto e un blocco di testo per visualizzare lo stato dell'azione corrente.

    <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. Salvare il file MainPage.xaml.

  4. Nel file di progetto MainPage.xaml.cs aggiungere le istruzioni using seguenti.

    using Windows.Web.Http;
    using System.Text;
    using Windows.Security.Cryptography.Certificates;
    using Windows.Storage.Pickers;
    using Windows.Storage;
    using Windows.Storage.Streams;
    
  5. Nel file MainPage.xaml.cs, aggiungere la variabile seguente alla classe MainPage. Specificano l'indirizzo per il metodo "Login" protetto del servizio Web "FirstContosoBank" e una variabile globale che contiene un certificato PFX da importare nell'archivio certificati. Aggiornare il <server-name> al nome completo del server per il server Microsoft Internet Information Server (IIS).

    private Uri requestUri = new Uri("https://<server-name>/FirstContosoBank/Service1.asmx?op=Login");
    private string pfxCert = null;
    
  6. Nel file MainPage.xaml.cs aggiungere il gestore di clic seguente per il pulsante di accesso e il metodo per accedere al servizio Web protetto.

    private void Login_Click(object sender, RoutedEventArgs e)
    {
        MakeHttpsCall();
    }
    
    private async void MakeHttpsCall()
    {
    
        StringBuilder result = new StringBuilder("Login ");
        HttpResponseMessage response;
        try
        {
            Windows.Web.Http.HttpClient httpClient = new Windows.Web.Http.HttpClient();
            response = await httpClient.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. Nel file MainPage.xaml.cs aggiungere i gestori di clic seguenti per il pulsante per cercare un file PFX e il pulsante per importare un file PFX selezionato nell'archivio certificati.

    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 succeded";
        }
        catch (Exception ex)
        {
            Result.Text = "Certificate import failed with " + ex.Message;
        }
    }
    
    private async void Browse_Click(object sender, RoutedEventArgs e)
    {
    
        StringBuilder result = new StringBuilder("Pfx file selection ");
        FileOpenPicker pfxFilePicker = new FileOpenPicker();
        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. Eseguire l'app e accedere al servizio Web protetto, nonché importare un file PFX nell'archivio certificati locale.

È possibile usare questi passaggi per creare più app che usano lo stesso certificato utente per accedere agli stessi servizi Web protetti o diversi.