Aggiungere l'accesso con Microsoft a un'app Web ASP.NET

Questa guida illustra come implementare l'accesso con Microsoft usando una soluzione ASP.NET MVC con un'applicazione tradizionale basata su Web browser tramite OpenID Connect.

Al termine di questa guida, l'applicazione sarà in grado di accettare accessi sia di account personali (ad esempio, outlook.com, live.com e altri) sia di account aziendali o di istituti di istruzione di proprietà di aziende od organizzazioni con Azure Active Directory integrato.

Questa guida richiede Visual Studio 2015 Update 3 o Visual Studio 2017. Se non lo si ha, è possibile scaricare Visual Studio 2017 gratuitamente

Come interpretare questa guida

Come interpretare questa guida

Questa guida si basa su uno scenario in cui un browser accede a un sito Web ASP.NET e chiede agli utenti di eseguire l'autenticazione tramite un pulsante di accesso. In questo scenario, la maggior parte delle operazioni necessarie per il rendering della pagina Web viene eseguita sul lato server.

Librerie

Questa guida usa le librerie seguenti:

Libreria Descrizione
Microsoft.Owin.Security.OpenIdConnect Middleware che consente a un'applicazione di usare OpenID Connect per l'autenticazione
Microsoft.Owin.Security.Cookies Middleware che consente a un'applicazione di mantenere la sessione utente usando i cookie
Microsoft.Owin.Host.SystemWeb Consente l'esecuzione in IIS di applicazioni basate su OWIN tramite la pipeline di richieste ASP.NET

Configurare il progetto

Questa sezione illustra la procedura per l'installazione e la configurazione della pipeline di autenticazione tramite middleware OWIN in un progetto ASP.NET mediante OpenID Connect.

Se invece si preferisce scaricare questo progetto Visual Studio di esempio, Scaricare un progetto e passare direttamente al passaggio di configurazione per configurare il codice di esempio prima di eseguirlo.

Creare un progetto ASP.NET

  1. In Visual Studio: File > New > Project
  2. In Visual C#\Web selezionare ASP.NET Web Application (.NET Framework)
  3. Assegnare un nome all'applicazione e fare clic su OK
  4. Selezionare Empty e quindi selezionare la casella di controllo per aggiungere i riferimenti MVC

Aggiungere i componenti per l'autenticazione

  1. In Visual Studio: Tools > Nuget Package Manager > Package Manager Console
  2. Aggiungere pacchetti NuGet del middleware OWIN digitando quanto segue nella finestra della Console di Gestione pacchetti:
Install-Package Microsoft.Owin.Security.OpenIdConnect
Install-Package Microsoft.Owin.Security.Cookies
Install-Package Microsoft.Owin.Host.SystemWeb

Informazioni sulle librerie

Le librerie precedenti abilitano l'accesso Single Sign-On (SSO) usando OpenID Connect tramite l'autenticazione basata su cookie. Al termine dell'autenticazione e dopo l'invio del token che rappresenta l'utente all'applicazione, il middleware OWIN crea un cookie di sessione. Il browser usa quindi questo cookie nelle richieste successive, in modo che l'utente non debba digitare di nuovo la password, e non sono necessarie operazioni di verifica aggiuntive.

Configurare la pipeline di autenticazione

La procedura seguente consente di creare una classe di avvio del middleware OWIN per configurare l'autenticazione OpenID Connect. Questa classe verrà eseguita automaticamente all'avvio del processo di IIS.

Se il progetto non include alcun file Startup.cs nella cartella radice:

  1. Fare clic con il pulsante destro del mouse sulla cartella radice del progetto: > Add > New Item... > OWIN Startup class
  2. Assegnare il nome Startup.cs

Assicurarsi che la classe selezionata sia una classe di avvio di OWIN e non una classe C# standard. Per confermarlo, verificare se [assembly: OwinStartup(typeof({NameSpace}.Startup))] viene visualizzato sopra lo spazio dei nomi.

  1. Aggiungere i riferimenti OWIN e Microsoft.IdentityModel a Startup.cs:
using Microsoft.Owin;
using Owin;
using Microsoft.IdentityModel.Protocols;
using Microsoft.Owin.Security;
using Microsoft.Owin.Security.Cookies;
using Microsoft.Owin.Security.OpenIdConnect;
using Microsoft.Owin.Security.Notifications;
  1. Sostituire la classe di avvio con il codice seguente:
public class Startup
{        
    // The Client ID is used by the application to uniquely identify itself to Azure AD.
    string clientId = System.Configuration.ConfigurationManager.AppSettings["ClientId"];

    // RedirectUri is the URL where the user will be redirected to after they sign in.
    string redirectUri = System.Configuration.ConfigurationManager.AppSettings["RedirectUri"];

    // Tenant is the tenant ID (e.g. contoso.onmicrosoft.com, or 'common' for multi-tenant)
    static string tenant = System.Configuration.ConfigurationManager.AppSettings["Tenant"];

    // Authority is the URL for authority, composed by Azure Active Directory v2 endpoint and the tenant name (e.g. https://login.microsoftonline.com/contoso.onmicrosoft.com/v2.0)
    string authority = String.Format(System.Globalization.CultureInfo.InvariantCulture, System.Configuration.ConfigurationManager.AppSettings["Authority"], tenant);

    /// <summary>
    /// Configure OWIN to use OpenIdConnect 
    /// </summary>
    /// <param name="app"></param>
    public void Configuration(IAppBuilder app)
    {
        app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);

        app.UseCookieAuthentication(new CookieAuthenticationOptions());
            app.UseOpenIdConnectAuthentication(
            new OpenIdConnectAuthenticationOptions
            {
                // Sets the ClientId, authority, RedirectUri as obtained from web.config
                ClientId = clientId,
                Authority = authority,
                RedirectUri = redirectUri,
                // PostLogoutRedirectUri is the page that users will be redirected to after sign-out. In this case, it is using the home page
                PostLogoutRedirectUri = redirectUri,
                Scope = OpenIdConnectScopes.OpenIdProfile,
                // ResponseType is set to request the id_token - which contains basic information about the signed-in user
                ResponseType = OpenIdConnectResponseTypes.IdToken,
                // ValidateIssuer set to false to allow personal and work accounts from any organization to sign in to your application
                // To only allow users from a single organizations, set ValidateIssuer to true and 'tenant' setting in web.config to the tenant name
                // To allow users from only a list of specific organizations, set ValidateIssuer to true and use ValidIssuers parameter 
                TokenValidationParameters = new System.IdentityModel.Tokens.TokenValidationParameters() { ValidateIssuer = false },
                // OpenIdConnectAuthenticationNotifications configures OWIN to send notification of failed authentications to OnAuthenticationFailed method
                Notifications = new OpenIdConnectAuthenticationNotifications
                {
                    AuthenticationFailed = OnAuthenticationFailed
                }
            }
        );
    }

    /// <summary>
    /// Handle failed authentication requests by redirecting the user to the home page with an error in the query string
    /// </summary>
    /// <param name="context"></param>
    /// <returns></returns>
    private Task OnAuthenticationFailed(AuthenticationFailedNotification<OpenIdConnectMessage, OpenIdConnectAuthenticationOptions> context)
    {
        context.HandleResponse();
        context.Response.Redirect("/?errormessage=" + context.Exception.Message);
        return Task.FromResult(0);
    }
}

Altre informazioni

I parametri forniti in OpenIDConnectAuthenticationOptions fungeranno da coordinate per consentire all'applicazione di comunicare con Azure AD. Poiché il middleware OpenID Connect usa i cookie in background, è anche necessario configurare l'autenticazione dei cookie, come illustrato nel codice precedente. Il valore ValidateIssuer segnala a OpenIdConnect di non limitare l'accesso a un'organizzazione specifica.

Aggiungere un controller per gestire le richieste di accesso e disconnessione

Questo passaggio illustra come creare un nuovo controller per esporre i metodi di accesso e disconnessione.

  1. Fare clic con il pulsante destro del mouse sulla cartella Controllers e scegliere Add > Controller.
  2. Selezionare MVC (.NET version) Controller – Empty.
  3. Fare clic su Aggiungi.
  4. Assegnare il nome HomeController e fare clic su Aggiungi.
  5. Aggiungere i riferimenti OWIN alla classe:
using Microsoft.Owin.Security;
using Microsoft.Owin.Security.Cookies;
using Microsoft.Owin.Security.OpenIdConnect;
  1. Aggiungere al controller i due metodi seguenti per gestire l'accesso e la disconnessione avviando una richiesta di autenticazione tramite codice:
/// <summary>
/// Send an OpenID Connect sign-in request.
/// Alternatively, you can just decorate the SignIn method with the [Authorize] attribute
/// </summary>
public void SignIn()
{
    if (!Request.IsAuthenticated)
    {
        HttpContext.GetOwinContext().Authentication.Challenge(
            new AuthenticationProperties{ RedirectUri = "/" },
            OpenIdConnectAuthenticationDefaults.AuthenticationType);
    }
}

/// <summary>
/// Send an OpenID Connect sign-out request.
/// </summary>
public void SignOut()
{
    HttpContext.GetOwinContext().Authentication.SignOut(
            OpenIdConnectAuthenticationDefaults.AuthenticationType,
            CookieAuthenticationDefaults.AuthenticationType);
}

Creare la home page dell'app per l'accesso degli utenti tramite un pulsante di accesso

In Visual Studio creare una nuova visualizzazione per aggiungere il pulsante di accesso e mostrare le informazioni relative all'utente dopo l'autenticazione:

  1. Fare clic con il pulsante destro del mouse sulla cartella Views\Home e scegliere Add View.
  2. Denominarlo Index.
  3. Aggiungere al file il codice HTML seguente, che include il pulsante di accesso:
<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title>Sign-In with Microsoft Guide</title>
</head>
<body>
@if (!Request.IsAuthenticated)
{
    <!-- If the user is not authenticated, display the sign-in button -->
    <a href="@Url.Action("SignIn", "Home")" style="text-decoration: none;">
        <svg xmlns="http://www.w3.org/2000/svg" xml:space="preserve" width="300px" height="50px" viewBox="0 0 3278 522" class="SignInButton">
        <style type="text/css">.fil0:hover {fill: #4B4B4B;} .fnt0 {font-size: 260px;font-family: 'Segoe UI Semibold', 'Segoe UI'; text-decoration: none;}</style>
        <rect class="fil0" x="2" y="2" width="3174" height="517" fill="black" />
        <rect x="150" y="129" width="122" height="122" fill="#F35325" />
        <rect x="284" y="129" width="122" height="122" fill="#81BC06" />
        <rect x="150" y="263" width="122" height="122" fill="#05A6F0" />
        <rect x="284" y="263" width="122" height="122" fill="#FFBA08" />
        <text x="470" y="357" fill="white" class="fnt0">Sign in with Microsoft</text>
        </svg>
    </a>
}
else
{
    <span><br/>Hello @System.Security.Claims.ClaimsPrincipal.Current.FindFirst("name").Value;</span>
    <br /><br />
    @Html.ActionLink("See Your Claims", "Index", "Claims")
    <br /><br />
    @Html.ActionLink("Sign out", "SignOut", "Home")
}
@if (!string.IsNullOrWhiteSpace(Request.QueryString["errormessage"]))
{
    <div style="background-color:red;color:white;font-weight: bold;">Error: @Request.QueryString["errormessage"]</div>
}
</body>
</html>

Altre informazioni

Questa pagina aggiunge un pulsante di accesso in formato SVG con sfondo nero:
Pulsante "Accedi con Microsoft"
Per altri pulsanti di accesso, vedere questa pagina.

Aggiungere un controller per visualizzare le attestazioni dell'utente

Questo controller illustra gli usi dell'attributo [Authorize] per la protezione di un controller. Questo attributo limita l'accesso al controller ai soli utenti autenticati. Il codice seguente usa l'attributo per visualizzare le attestazioni utente recuperate durante l'accesso.

  1. Fare clic con il pulsante destro del mouse sulla cartella Controllers e scegliere Add > Controller.
  2. Selezionare MVC {version} Controller – Empty.
  3. Fare clic su Aggiungi.
  4. Assegnare il nome ClaimsController.
  5. Sostituire il codice della classe controller con il codice seguente, che aggiunge l'attributo [Authorize] alla classe:
[Authorize]
public class ClaimsController : Controller
{
    /// <summary>
    /// Add user's claims to viewbag
    /// </summary>
    /// <returns></returns>
    public ActionResult Index()
    {
        var claimsPrincipalCurrent = System.Security.Claims.ClaimsPrincipal.Current;
        //You get the user’s first and last name below:
        ViewBag.Name = claimsPrincipalCurrent.FindFirst("name").Value;

        // The 'preferred_username' claim can be used for showing the username
        ViewBag.Username = claimsPrincipalCurrent.FindFirst("preferred_username").Value;

        // The subject claim can be used to uniquely identify the user across the web
        ViewBag.Subject = claimsPrincipalCurrent.FindFirst(System.Security.Claims.ClaimTypes.NameIdentifier).Value;

        // TenantId is the unique Tenant Id - which represents an organization in Azure AD
        ViewBag.TenantId = claimsPrincipalCurrent.FindFirst("http://schemas.microsoft.com/identity/claims/tenantid").Value;

        return View();
    }
}

Altre informazioni

A causa dell'uso dell'attributo [Authorize], tutti i metodi di questo controller possono essere eseguiti solo se l'utente è autenticato. Se un utente non autenticato prova ad accedere al controller, OWIN avvierà una richiesta di autenticazione e imporrà all'utente di autenticarsi. Il codice riportato sopra cerca nella raccolta di attestazioni dell'istanza ClaimsPrincipal.Current attributi utente specifici inclusi nel token dell'utente. Tali attributi includono nome e cognome, nome utente e soggetto ID utente globale dell'utente. Contengono anche l'ID tenant, che rappresenta l'ID dell'organizzazione dell'utente.

Creare una visualizzazione per mostrare le attestazioni dell'utente

In Visual Studio creare una nuova visualizzazione per mostrare le attestazioni dell'utente in una pagina Web:

  1. Fare clic con il pulsante destro del mouse sulla cartella Views\Claims e scegliere Add View.
  2. Denominarlo Index.
  3. Aggiungere il codice HTML seguente al file:
<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title>Sign-In with Microsoft Sample</title>
    <link href="@Url.Content("~/Content/bootstrap.min.css")" rel="stylesheet" type="text/css" />
</head>
<body style="padding:50px">
    <h3>Main Claims:</h3>
    <table class="table table-striped table-bordered table-hover">
        <tr><td>Name</td><td>@ViewBag.Name</td></tr>
        <tr><td>Username</td><td>@ViewBag.Username</td></tr>
        <tr><td>Subject</td><td>@ViewBag.Subject</td></tr>
        <tr><td>TenantId</td><td>@ViewBag.TenantId</td></tr>
    </table>
    <br />
    <h3>All Claims:</h3>
    <table class="table table-striped table-bordered table-hover table-condensed">
    @foreach (var claim in System.Security.Claims.ClaimsPrincipal.Current.Claims)
    {
        <tr><td>@claim.Type</td><td>@claim.Value</td></tr>
    }
</table>
    <br />
    <br />
    @Html.ActionLink("Sign out", "SignOut", "Home", null, new { @class = "btn btn-primary" })
</body>
</html>

Creare un'applicazione (Rapida)

È ora necessario registrare l'applicazione nel portale di registrazione delle applicazioni Microsoft:

  1. Registrare l'applicazione tramite il portale di registrazione delle applicazioni Microsoft
  2. Immettere un nome per l'applicazione e l'indirizzo di posta elettronica
  3. Assicurarsi che l'opzione per l'installazione guidata sia selezionata
  4. Seguire le istruzioni per aggiungere un URL di reindirizzamento all'applicazione

Aggiungere le informazioni di registrazione dell'applicazione alla soluzione (Avanzata)

È ora necessario registrare l'applicazione nel portale di registrazione delle applicazioni Microsoft:

  1. Passare al portale di registrazione delle applicazioni Microsoft per registrare un'applicazione
  2. Immettere un nome per l'applicazione e l'indirizzo di posta elettronica
  3. Assicurarsi che l'opzione per l'installazione guidata sia deselezionata
  4. Fare clic su Add Platform, quindi selezionare Web
  5. Tornare a Visual Studio e in Esplora soluzioni selezionare il progetto, quindi esaminare la finestra Proprietà (se la finestra Proprietà non è visualizzata, premere F4)
  6. Impostare il valore di SSL abilitato su True
  7. Copiare l'URL SSL e aggiungere tale URL all'elenco di URL di reindirizzamento nell'elenco corrispondente del portale di registrazione:

    Proprietà del progetto
  8. Aggiungere il codice seguente in web.config, disponibile nella sezione configuration\appSettings della cartella radice:
<add key="ClientId" value="Enter_the_Application_Id_here" />
<add key="redirectUri" value="Enter_the_Redirect_URL_here" />
<add key="Tenant" value="common" />
<add key="Authority" value="https://login.microsoftonline.com/{0}/v2.0" /> 

  1. Sostituire ClientId con l'ID applicazione appena registrato
  2. Sostituire redirectUri con l'URL SSL del progetto

Testare il codice

Premere F5 per eseguire il progetto in Visual Studio. Verrà aperto il browser e l'utente verrà indirizzato a http://localhost:{porta}, in cui verrà visualizzato il pulsante Accedi con Microsoft. Fare clic per eseguire l'accesso.

Quando si è pronti per il test, usare un account aziendale o dell'istituto di istruzione (Azure Active Directory) oppure un account personale (live.com, outlook.com) per accedere.

Finestra del browser con accesso con Microsoft

Finestra del browser con accesso con Microsoft

Risultati previsti

Dopo l'accesso, l'utente viene reindirizzato alla home page del sito Web, ossia all'URL HTTPS specificato nelle informazioni di registrazione dell'applicazione nel portale di registrazione delle applicazioni Microsoft. Nella pagina vengono ora visualizzati Hello {utente}, un collegamento per la disconnessione e uno per visualizzare le attestazioni dell'utente, ossia un collegamento al controller Authorize creato in precedenza.

Visualizzare le attestazioni dell'utente

Selezionare il collegamento ipertestuale per visualizzare le attestazioni dell'utente. Si accederà così al controller e alla visualizzazione disponibile solo per gli utenti autenticati.

Risultati previsti

Verrà visualizzata una tabella contenente le proprietà di base dell'utente connesso:

Proprietà Valore Descrizione
Nome {Nome e cognome utente} Nome e cognome dell'utente
Nome utente user@domain.com Nome utente usato per identificare l'utente connesso
Subject {Soggetto} Stringa che identifica in modo univoco l'account di accesso dell'utente sul Web
ID tenant {GUID} GUID che rappresenta in modo univoco l'organizzazione di Azure Active Directory dell'utente.

Verrà visualizzata anche una tabella contenente tutte le attestazioni utente incluse nella richiesta di autenticazione. Per un elenco e una spiegazione di tutte le attestazioni in un token ID, vedere questo articolo.

Testare l'accesso a un metodo con attributo [Authorize] (facoltativo)

In questo passaggio si testerà l'accesso al controller Authenticated come utente anonimo:
Selezionare il collegamento per la disconnessione dell'utente e completare il processo di disconnessione.
Nel browser digitare http://localhost:{porta}/authenticated per accedere al controller protetto con l'attributo [Authorize].

Risultati previsti

Verrà visualizzata la richiesta di eseguire l'autenticazione per accedere alla visualizzazione.

Informazioni aggiuntive

Proteggere l'intero sito Web

Per proteggere l'intero sito Web, aggiungere AuthorizeAttribute a GlobalFilters nel metodo Application_Start di Global.asax:

GlobalFilters.Filters.Add(new AuthorizeAttribute());


Nota

Come limitare l'accesso all'applicazione agli utenti di una sola organizzazione

Per impostazione predefinita, all'applicazione possono accedere account personali (ad esempio outlook.com, live.com e altri) e account aziendali o di istituti di istruzione di qualsiasi organizzazione o azienda che abbia eseguito l'integrazione con Azure Active Directory.

Se si vuole che l'applicazione accetti accessi da una sola organizzazione di Azure Active Directory, sostituire il parametro Tenant in web.config passando da Common al nome del tenant dell'organizzazione, ad esempio contoso.onmicrosoft.com. Al termine, modificare l'argomento ValidateIssuer nella classe di avvio OWIN impostandolo su true.

Per consentire l'accesso solo agli utenti di un elenco di organizzazioni specifiche, impostare ValidateIssuer su true e usare il parametro ValidIssuers per specificare un elenco di organizzazioni.

Un'altra opzione consiste nell'implementare un metodo personalizzato per convalidare le autorità di certificazione usando il parametro IssuerValidator. Per altre informazioni su TokenValidationParameters, vedere questo articolo di MSDN.