Azure AD B2C: Chiamare un'API Web .NET da un'app Web .NETAzure AD B2C: Call a .NET web API from a .NET web app

Tramite Azure AD B2C, è possibile aggiungere potenti funzionalità di gestione di identità per l'app Web e le API.By using Azure AD B2C, you can add powerful identity management features to your web apps and web APIs. In questo articolo viene illustrato come richiedere i token di accesso ed effettuare chiamate da un'app Web "elenco attività" .NET per API Web .NET.This article discusses how to request access tokens and make calls from a .NET "to-do list" web app to a .NET web api.

Questo articolo non descrive come implementare le esperienze di accesso, iscrizione e gestione del profilo con Azure AD B2C,This article does not cover how to implement sign-in, sign-up and profile management with Azure AD B2C. ma illustra la chiamata delle API Web dopo che l'utente ha già effettuato l'autenticazione.It focuses on calling web APIs after the user is already authenticated. Se lo si è già fatto, è necessario fare:If you haven't already, you should:

PrerequisitoPrerequisite

Per compilare un'app Web che chiama un'API Web è necessario:To build a web application that calls a web api, you need to:

  1. Creare un tenant di Azure AD B2C.Create an Azure AD B2C tenant.
  2. Registrare un'API Web.Register a web api.
  3. Registrare un'app Web.Register a web app.
  4. Configurare i criteri.Set up policies.
  5. Concedere le autorizzazioni all'app Web per usare le API Web.Grant the web app permissions to use the web api.

Importante

L'applicazione client e l'API Web devono usare la stessa directory di Azure AD B2C.The client application and web API must use the same Azure AD B2C directory.

Scaricare il codiceDownload the code

Il codice per questa esercitazione è salvato su GitHub.The code for this tutorial is maintained on GitHub. È possibile clonare l'esempio eseguendo:You can clone the sample by running:

git clone https://github.com/Azure-Samples/active-directory-b2c-dotnet-webapp-and-webapi.git

Dopo aver scaricato il codice di esempio, aprire il file SLN di Visual Studio per iniziare.After you download the sample code, open the Visual Studio .sln file to get started. Il file della soluzione contiene due progetti: TaskWebApp e TaskService.The solution file contains two projects: TaskWebApp and TaskService. TaskWebApp è un'applicazione Web MVC con cui l'utente interagisce.TaskWebApp is a MVC web application that the user interacts with. TaskService è l'API Web back-end dell'app in cui viene archiviato l'elenco attività di ogni utente.TaskService is the app's back-end web API that stores each user's to-do list. Questo articolo non descrive la compilazione dell'app Web TaskWebApp o delle API Web TaskService.This article does not cover building the TaskWebApp web app or the TaskService web api. Per informazioni su come compilare un'app Web .NET usando Azure AD B2C, vedere l'esercitazione sulle app Web .NET.To learn how to build the .NET web app using Azure AD B2C, see our .NET web app tutorial. Per informazioni su come compilare l'API Web .NET usando Azure AD B2C, vedere l'esercitazione sulle API Web .NET.To learn how to build the .NET web API secured using Azure AD B2C, see our .NET web API tutorial.

Aggiornare la configurazione di Azure AD B2CUpdate the Azure AD B2C configuration

L'esempio è configurato per l'uso dei criteri e dell'ID client del tenant demo.Our sample is configured to use the policies and client ID of our demo tenant. Se si desidera usare il proprio tenant:If you would like to use your own tenant:

  1. Aprire web.config nel progetto TaskService e sostituire i valori diOpen web.config in the TaskService project and replace the values for

    • ida:Tenant con il nome del tenantida:Tenant with your tenant name
    • ida:ClientId con l'ID dell'applicazione API Webida:ClientId with your web api application ID
    • ida:SignUpSignInPolicyId con il nome del criterio "Iscrizione o accesso"ida:SignUpSignInPolicyId with your "Sign-up or Sign-in" policy name
  2. Aprire web.config nel progetto TaskWebApp e sostituire i valori diOpen web.config in the TaskWebApp project and replace the values for

    • ida:Tenant con il nome del tenantida:Tenant with your tenant name
    • ida:ClientId con l'ID dell'applicazione di tipo app Webida:ClientId with your web app application ID
    • ida:ClientSecret con la chiave privata dell'app Webida:ClientSecret with your web app secret key
    • ida:SignUpSignInPolicyId con il nome del criterio "Iscrizione o accesso"ida:SignUpSignInPolicyId with your "Sign-up or Sign-in" policy name
    • ida:EditProfilePolicyId con il nome del criterio "Modifica profilo"ida:EditProfilePolicyId with your "Edit Profile" policy name
    • ida:ResetPasswordPolicyId con il nome del criterio "Reimposta password"ida:ResetPasswordPolicyId with your "Reset Password" policy name

Richiesta e salvataggio di un token di accessoRequesting and saving an access token

Specificare le autorizzazioniSpecify the permissions

Per poter effettuare la chiamata all'API Web, è necessario autenticare l'utente (tramite i criteri di registrazione o accesso) e ricevere un token di accesso da Azure Active Directory B2C.In order to make the call to the web API, you need to authenticate the user (using your sign-up/sign-in policy) and receive an access token from Azure AD B2C. Per ricevere un token di accesso, è necessario specificare le autorizzazioni che si desidera concedere al token di accesso.In order to receive an access token, you first must specify the permissions you would like the access token to grant. Le autorizzazioni vengono specificate nel parametro scope quando si effettua la richiesta per l'endpoint /authorize.The permissions are specified in the scope parameter when you make the request to the /authorize endpoint. Ad esempio, per acquisire un token di accesso con l'autorizzazione "lettura" per l'applicazione della risorsa con l'URI ID App di https://contoso.onmicrosoft.com/tasks, l'ambito sarà https://contoso.onmicrosoft.com/tasks/read.For example, to acquire an access token with the “read” permission to the resource application that has the App ID URI of https://contoso.onmicrosoft.com/tasks, the scope would be https://contoso.onmicrosoft.com/tasks/read.

Per specificare l'ambito nell'esempio, aprire il file App_Start\Startup.Auth.cs e definire la variabile Scope in OpenIdConnectAuthenticationOptions.To specify the scope in our sample, open the file App_Start\Startup.Auth.cs and define the Scope variable in OpenIdConnectAuthenticationOptions.

// App_Start\Startup.Auth.cs

    app.UseOpenIdConnectAuthentication(
        new OpenIdConnectAuthenticationOptions
        {
            ...

            // Specify the scope by appending all of the scopes requested into one string (seperated by a blank space)
            Scope = $"{OpenIdConnectScopes.OpenId} {ReadTasksScope} {WriteTasksScope}"
        }
    );
}

Scambiare il codice di autorizzazione con un token di accessoExchange the authorization code for an access token

Al termine dell'esperienza di iscrizione o accesso dell'utente, l'applicazione riceverà un codice di autorizzazione da Azure AD B2C.After an user completes the sign-up or sign-in experience, your app will receive an authorization code from Azure AD B2C. Il middleware OWIN OpenID Connect archivierà il codice, ma non lo scambierà per un token di accesso.The OWIN OpenID Connect middleware will store the code, but will not exchange it for an access token. È possibile usare la libreria MSAL per fare lo scambio.You can use the MSAL library to make the exchange. Nell'esempio, è stato configurato un callback di notifica nel middleware OpenID Connect ogni volta che viene ricevuto un codice di autorizzazione.In our sample, we configured a notification callback into the OpenID Connect middleware whenever an authorization code is received. Nel callback viene usato MSAL per scambiare il codice con un token e salvare il token nella cache.In the callback, we use MSAL to exchange the code for a token and save the token into the cache.

/*
* Callback function when an authorization code is received
*/
private async Task OnAuthorizationCodeReceived(AuthorizationCodeReceivedNotification notification)
{
    // Extract the code from the response notification
    var code = notification.Code;

    var userObjectId = notification.AuthenticationTicket.Identity.FindFirst(ObjectIdElement).Value;
    var authority = String.Format(AadInstance, Tenant, DefaultPolicy);
    var httpContext = notification.OwinContext.Environment["System.Web.HttpContextBase"] as HttpContextBase;

    // Exchange the code for a token. Make sure to specify the necessary scopes
    ClientCredential cred = new ClientCredential(ClientSecret);
    ConfidentialClientApplication app = new ConfidentialClientApplication(authority, Startup.ClientId,
                                            RedirectUri, cred, new NaiveSessionCache(userObjectId, httpContext));
    var authResult = await app.AcquireTokenByAuthorizationCodeAsync(new string[] { ReadTasksScope, WriteTasksScope }, code, DefaultPolicy);
}

Chiamata dell'API WebCalling the web API

Questa sezione illustra come usare il token ricevuto durante la registrazione o l'accesso con Azure AD B2C per accedere a un'API Web.This section discusses how to use the token received during sign-up/sign-in with Azure AD B2C in order to access the web API.

Recuperare il token salvato nei controllerRetrieve the saved token in the controllers

TasksController è responsabile della comunicazione con l'API Web e dell'invio di richieste HTTP all'API per la lettura, la creazione e l'eliminazione di attività.The TasksController is responsible for communicating with the web API and for sending HTTP requests to the API to read, create, and delete tasks. Poiché che l'API è protetta da Azure AD B2C, per prima cosa è necessario recuperare il token salvato nel passaggio precedente.Because the API is secured by Azure AD B2C, you need to first retrieve the token you saved in the above step.

// Controllers\TasksController.cs

/*
* Uses MSAL to retrieve the token from the cache
*/
private async void acquireToken(String[] scope)
{
    string userObjectID = ClaimsPrincipal.Current.FindFirst(Startup.ObjectIdElement).Value;
    string authority = String.Format(Startup.AadInstance, Startup.Tenant, Startup.DefaultPolicy);

    ClientCredential credential = new ClientCredential(Startup.ClientSecret);

    // Retrieve the token using the provided scopes
    ConfidentialClientApplication app = new ConfidentialClientApplication(authority, Startup.ClientId,
                                        Startup.RedirectUri, credential,
                                        new NaiveSessionCache(userObjectID, this.HttpContext));
    AuthenticationResult result = await app.AcquireTokenSilentAsync(scope);

    accessToken = result.Token;
}

Leggere le attività dall'API WebRead tasks from the web API

Dopo aver ottenuto un token, collegarlo alla richiesta HTTP GET nell'intestazione Authorization per chiamare TaskService in modo sicuro:When you have a token, you can attach it to the HTTP GET request in the Authorization header to securely call TaskService:

// Controllers\TasksController.cs

public async Task<ActionResult> Index()
{
    try {

        // Retrieve the token with the specified scopes
        acquireToken(new string[] { Startup.ReadTasksScope });

        HttpClient client = new HttpClient();
        HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, apiEndpoint);

        // Add token to the Authorization header and make the request
        request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);
        HttpResponseMessage response = await client.SendAsync(request);

        // Handle response ...
}

Creare ed eliminare attività nell'API WebCreate and delete tasks on the web API

Seguire lo stesso modello quando si inviano le richieste POST e DELETE all'API Web, usando MSAL per recuperare il token di accesso dalla cache.Follow the same pattern when you send POST and DELETE requests to the web API, using MSAL to retrieve the access token from the cache.

Eseguire l'app di esempioRun the sample app

Infine, compilare ed eseguire entrambe le app.Finally, build and run both the apps. Eseguire l'iscrizione e l'accesso e creare attività per l'utente connesso.Sign up and sign in, and create tasks for the signed-in user. Disconnettersi ed eseguire l'accesso usando un account utente diverso.Sign out and sign in as a different user. Creare le attività per l'utente.Create tasks for that user. Si noti che le attività sono archiviate per ogni utente nell'API, perché l'API estrae l'identità dell'utente dai token che riceve.Notice how the tasks are stored per-user on the API, because the API extracts the user's identity from the token it receives. Provare inoltre a usare gli ambiti.Also try playing with the scopes. Rimuovere l'autorizzazione "scrivere" e quindi provare ad aggiungere un'attività.Remove the permission to "write" and then try adding a task. Basta assicurarsi di disconnettersi ogni volta che si modifica l'ambito.Just make sure to sign out each time you change the scope.