Aggiungere l'accesso a un'applicazione Desktop di WindowsAdd sign-in to a Windows Desktop app

Con l'endpoint v2.0 è possibile aggiungere rapidamente l'autenticazione alle app desktop con supporto per account Microsoft personali, aziendali o dell'istituto di istruzione.With the the v2.0 endpoint, you can quickly add authentication to your desktop apps with support for both personal Microsoft accounts and work or school accounts. Consente inoltre all'app di comunicare in modo sicuro con un'API Web back-end, con Microsoft Graph e con alcune API unificate di Office 365.It also enables your app to securely communicate with a backend web api, as well as the Microsoft Graph and a few of the Office 365 Unified APIs.

Nota

Non tutti gli scenari e le funzionalità di Azure Active Directory (AD) sono supportati dall'endpoint 2.0.Not all Azure Active Directory (AD) scenarios & features are supported by the v2.0 endpoint. Per determinare se è necessario usare l'endpoint v2.0, leggere le informazioni sulle limitazioni v2.0.To determine if you should use the v2.0 endpoint, read about v2.0 limitations.

Per le app .NET native in esecuzione in un dispositivo, Azure AD fornisce la Microsoft Identity Authentication Library (MSAL).For .NET native apps that run on a device, Azure AD provides the Microsoft Identity Authentication Library, or MSAL. L'unico scopo di MSAL è consentire all'app di ottenere facilmente i token per le chiamate ai servizi Web.MSAL's sole purpose in life is to make it easy for your app to get tokens for calling web services. Per dimostrare la semplicità di questa operazione, in questo esempio viene creata un'app .NET WPF To Do List che:To demonstrate just how easy it is, here we'll build a .NET WPF To-Do List app that:

  • Consente agli utenti di accedere e ottiene i token di accesso usando il protocollo di autenticazione OAuth 2.0.Signs the user in & gets access tokens using the OAuth 2.0 authentication protocol.
  • Chiama in modo sicuro un servizio Web To Do List di back-end, anch'esso protetto da OAuth 2.0.Securely calls a backend To-Do List web service, which is also secured by OAuth 2.0.
  • Disconnette l'utente.Signs the user out.

Scaricare il codice di esempioDownload sample code

Il codice per questa esercitazione è salvato su GitHub.The code for this tutorial is maintained on GitHub. Per seguire la procedura è possibile scaricare la struttura dell'app come file con estensione zip o clonare la struttura:To follow along, you can download the app's skeleton as a .zip or clone the skeleton:

git clone --branch skeleton https://github.com/AzureADQuickStarts/AppModelv2-NativeClient-DotNet.git

Al termine dell'esercitazione, verrà fornita anche l'app completata.The completed app is provided at the end of this tutorial as well.

Registrare un'appRegister an app

Creare una nuova app in apps.dev.microsoft.com o seguire questa procedura dettagliata.Create a new app at apps.dev.microsoft.com, or follow these detailed steps. Verificare di:Make sure to:

  • Copiare l' ID applicazione assegnato all'app, perché verrà richiesto a breve.Copy down the Application Id assigned to your app, you'll need it soon.
  • Aggiungere la piattaforma Mobile per l'app.Add the Mobile platform for your app.

Installare e configurare MSALInstall & Configure MSAL

A questo punto si ha un'app registrata in Microsoft ed è possibile installare MSAL e trascrivere il codice correlato all'identità.Now that you have an app registered with Microsoft, you can install MSAL and write your identity-related code. Affinché MSAL riesca a comunicare con l'endpoint v2.0, è necessario fornirlo insieme ad alcune informazioni relative alla registrazione dell'app.In order for MSAL to be able to communicate the v2.0 endpoint, you need to provide it with some information about your app registration.

  • Aggiungere prima di tutto MSAL al progetto TodoListClient usando la console di Gestione pacchetti.Begin by adding MSAL to the TodoListClient project using the Package Manager Console.
PM> Install-Package Microsoft.Identity.Client -ProjectName TodoListClient -IncludePrerelease
  • Nel progetto TodoListClient aprire app.config.In the TodoListClient project, open app.config. Sostituire i valori degli elementi nella sezione <appSettings> in modo che corrispondano ai valori inseriti nel portale di registrazione dell'app.Replace the values of the elements in the <appSettings> section to reflect the values you input into the app registration portal. Il codice farà riferimento a questi valori ogni volta che userà MSAL.Your code will reference these values whenever it uses MSAL.

    • ida:ClientId rappresenta l' ID applicazione dell'app copiato dal portale.The ida:ClientId is the Application Id of your app you copied from the portal.
  • Nel progetto TodoList-Service aprire web.config nella radice del progetto.In the TodoList-Service project, open web.config in the root of the project.

    • Sostituire il valore ida:Audience con lo stesso ID applicazione del portale.Replace the ida:Audience value with the same Application Id from the portal.

Usare MSAL per ottenere tokenUse MSAL to get tokens

Il principio alla base di MSAL è che l'app, ogni volta che ha bisogno di un token di accesso, deve semplicemente chiamare app.AcquireToken(...)e MSAL esegue le altre operazioni necessarie.The basic principle behind MSAL is that whenever your app needs an access token, you simply call app.AcquireToken(...), and MSAL does the rest.

  • Nel progetto TodoListClient aprire MainWindow.xaml.cs e individuare il metodo OnInitialized(...).In the TodoListClient project, open MainWindow.xaml.cs and locate the OnInitialized(...) method. Il primo passaggio consiste nell'inizializzare la classe primaria PublicClientApplication di MSAL dell'app, che rappresenta applicazioni native,The first step is to initialize your app's PublicClientApplication - MSAL's primary class representing native applications. dove si passano a MSAL le coordinate di cui ha bisogno per comunicare con Azure AD e gli si indica come memorizzare i token nella cache.This is where you pass MSAL the coordinates it needs to communicate with Azure AD and tell it how to cache tokens.
protected override async void OnInitialized(EventArgs e)
{
        base.OnInitialized(e);

        app = new PublicClientApplication(new FileCache());
        AuthenticationResult result = null;
        ...
}
  • All'avvio dell'app si intende quindi verificare e controllare se l'utente è già connesso all'app.When the app starts up, we want to check and see if the user is already signed into the app. Tuttavia, non si desidera ancora richiamare un'interfaccia utente di accesso. A questo scopo l'utente deve fare clic su "Accedi".However, we don't want to invoke a sign-in UI just yet - we'll make the user click "Sign In" to do so. Nel metodo OnInitialized(...):Also in the OnInitialized(...) method:
// As the app starts, we want to check to see if the user is already signed in.
// You can do so by trying to get a token from MSAL, using the method
// AcquireTokenSilent.  This forces MSAL to throw an exception if it cannot
// get a token for the user without showing a UI.
try
{
    result = await app.AcquireTokenSilentAsync(new string[] { clientId });
    // If we got here, a valid token is in the cache - or MSAL was able to get a new oen via refresh token.
    // Proceed to fetch the user's tasks from the TodoListService via the GetTodoList() method.

    SignInButton.Content = "Clear Cache";
    GetTodoList();
}
catch (MsalException ex)
{
    if (ex.ErrorCode == "user_interaction_required")
    {
        // If user interaction is required, the app should take no action,
        // and simply show the user the sign in button.
    }
    else
    {
        // Here, we catch all other MsalExceptions
        string message = ex.Message;
        if (ex.InnerException != null)
        {
            message += "Inner Exception : " + ex.InnerException.Message;
        }
        MessageBox.Show(message);
    }
}
  • Se l'utente non è connesso e fa clic sul pulsante "Accedi", si intende richiamare un'interfaccia utente di accesso e richiedere all'utente di immettere le credenziali.If the user is not signed in and they click the "Sign In" button, we want to invoke a login UI and have the user enter their credentials. Implementare il gestore del pulsante di accesso:Implement the Sign-In button handler:
private async void SignIn(object sender = null, RoutedEventArgs args = null)
{
        // TODO: Sign the user out if they clicked the "Clear Cache" button

// If the user clicked the 'Sign-In' button, force
// MSAL to prompt the user for credentials by using
// AcquireTokenAsync, a method that is guaranteed to show a prompt to the user.
// MSAL will get a token for the TodoListService and cache it for you.

AuthenticationResult result = null;
try
{
    result = await app.AcquireTokenAsync(new string[] { clientId });
    SignInButton.Content = "Clear Cache";
    GetTodoList();
}
catch (MsalException ex)
{
    // If MSAL cannot get a token, it will throw an exception.
    // If the user canceled the login, it will result in the
    // error code 'authentication_canceled'.

    if (ex.ErrorCode == "authentication_canceled")
    {
        MessageBox.Show("Sign in was canceled by the user");
    }
    else
    {
        // An unexpected error occurred.
        string message = ex.Message;
        if (ex.InnerException != null)
        {
            message += "Inner Exception : " + ex.InnerException.Message;
        }

        MessageBox.Show(message);
    }

    return;
}


}
  • Se l'utente accede correttamente, MSAL riceve e memorizza nella cache un token per l'utente ed è possibile procedere in tutta sicurezza alla chiamata al metodo GetTodoList() .If the user successfully signs-in, MSAL will receive and cache a token for you, and you can proceed to call the GetTodoList() method with confidence. Per ottenere le attività dell'utente è sufficiente implementare il metodo GetTodoList() .All that's left to get a user's tasks is to implement the GetTodoList() method.
private async void GetTodoList()
{

AuthenticationResult result = null;
try
{
    // Here, we try to get an access token to call the TodoListService
    // without invoking any UI prompt.  AcquireTokenSilentAsync forces
    // MSAL to throw an exception if it cannot get a token silently.


    result = await app.AcquireTokenSilentAsync(new string[] { clientId });
}
catch (MsalException ex)
{
    // MSAL couldn't get a token silently, so show the user a message
    // and let them click the Sign-In button.

    if (ex.ErrorCode == "user_interaction_required")
    {
        MessageBox.Show("Please sign in first");
        SignInButton.Content = "Sign In";
    }
    else
    {
        // In any other case, an unexpected error occurred.

        string message = ex.Message;
        if (ex.InnerException != null)
        {
            message += "Inner Exception : " + ex.InnerException.Message;
        }
        MessageBox.Show(message);
    }

    return;
}

// Once the token has been returned by MSAL,
// add it to the http authorization header,
// before making the call to access the To Do list service.

httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", result.Token);


        ...
...


- When the user is done managing their To-Do List, they may finally sign out of the app by clicking the "Clear Cache" button.

```C#
private async void SignIn(object sender = null, RoutedEventArgs args = null)
{
        // If the user clicked the 'clear cache' button,
        // clear the MSAL token cache and show the user as signed out.
        // It's also necessary to clear the cookies from the browser
        // control so the next user has a chance to sign in.

        if (SignInButton.Content.ToString() == "Clear Cache")
        {
                TodoList.ItemsSource = string.Empty;
                app.UserTokenCache.Clear(app.ClientId);
                ClearCookies();
                SignInButton.Content = "Sign In";
                return;
        }

        ...

EseguiRun

Congratulazioni.Congratulations! A questo punto si dispone di un'app WPF .NET funzionante, la quale consente di autenticare gli utenti e di effettuare chiamate sicure delle API Web utilizzando Oauth 2.0.You now have a working .NET WPF app that has the ability to authenticate users & securely call Web APIs using OAuth 2.0. Eseguire entrambi i progetti e accedere con un account Microsoft personale oppure con un account aziendale o dell'istituto di istruzione.Run your both projects, and sign in with either a personal Microsoft account or a work or school account. Aggiungere le attività all'elenco To-Do dell'utente.Add tasks to that user's To-Do list. Disconnettersi e ripetere l'accesso come utente differente per visualizzare l'elenco To-Do.Sign out, and sign back in as another user to view their To-Do list. Chiudere l'app e rieseguirla.Close the app, and re-run it. La sessione dell'utente non subisce modifiche, poiché l'app memorizza i token in un file locale.Notice how the user's session remains intact - that is because the app caches tokens in a local file.

MSAL facilita l'incorporazione delle funzionalità di identità comuni all'interno dell'app usando sia account personali che aziendali.MSAL makes it easy to incorporate common identity features into your app, using both personal and work accounts. Esegue automaticamente le attività più complesse: gestione della cache, supporto del protocollo OAuth, presentazione all'utente di un'interfaccia utente di accesso, aggiornamento dei token scaduti e altro.It takes care of all the dirty work for you - cache management, OAuth protocol support, presenting the user with a login UI, refreshing expired tokens, and more. Tutto ciò che occorre conoscere è una sola chiamata all'API, app.AcquireTokenAsync(...).All you really need to know is a single API call, app.AcquireTokenAsync(...).

Come riferimento, l'esempio completato (senza i valori di configurazione) è disponibile in un file con estensione .zip qui. In alternativa, è possibile clonarlo da GitHub:For reference, the completed sample (without your configuration values) is provided as a .zip here, or you can clone it from GitHub:

git clone --branch complete https://github.com/AzureADQuickStarts/AppModelv2-NativeClient-DotNet.git

Passaggi successiviNext steps

Ora è possibile passare ad argomenti più avanzati.You can now move onto more advanced topics. È possibile:You may want to try:

Per altre risorse, vedere:For additional resources, check out:

Ottenere aggiornamenti della sicurezza per i prodottiGet security updates for our products

È consigliabile ricevere notifiche in caso di problemi di sicurezza. A tale scopo, visitare questa pagina e sottoscrivere gli avvisi di sicurezza.We encourage you to get notifications of when security incidents occur by visiting this page and subscribing to Security Advisory Alerts.