Web app that signs in users: Code configuration

This article describes how to configure code for a web app that signs in users.

Microsoft libraries supporting web apps

The following Microsoft libraries are used to protect a web app (and a web API):

Language / framework Project on
GitHub
Package Getting
started
Sign in users Access web APIs Generally available (GA) or
Public preview1
.NET MSAL.NET Microsoft.Identity.Client Library cannot request ID tokens for user sign-in. Library can request access tokens for protected web APIs. GA
.NET Microsoft.IdentityModel Microsoft.IdentityModel Library cannot request ID tokens for user sign-in.2 Library cannot request access tokens for protected web APIs.2 GA
ASP.NET Core ASP.NET Core Microsoft.AspNetCore.Authentication Quickstart Library can request ID tokens for user sign-in. Library cannot request access tokens for protected web APIs. GA
ASP.NET Core Microsoft.Identity.Web Microsoft.Identity.Web Quickstart Library can request ID tokens for user sign-in. Library can request access tokens for protected web APIs. GA
Java MSAL4J msal4j Quickstart Library can request ID tokens for user sign-in. Library can request access tokens for protected web APIs. GA
Spring spring-cloud-azure-starter-active-directory spring-cloud-azure-starter-active-directory Tutorial Library can request ID tokens for user sign-in. Library can request access tokens for protected web APIs. GA
Node.js MSAL Node msal-node Quickstart Library can request ID tokens for user sign-in. Library can request access tokens for protected web APIs. GA
Python MSAL Python msal Library can request ID tokens for user sign-in. Library can request access tokens for protected web APIs. GA
Python identity identity Quickstart Library can request ID tokens for user sign-in. Library can request access tokens for protected web APIs. --

(1) Universal License Terms for Online Services apply to libraries in Public preview.

(2) The Microsoft.IdentityModel library only validates tokens - it can't request ID or access tokens.

Select the tab that corresponds to the platform you're interested in:

Code snippets in this article and the following are extracted from the ASP.NET Core web app incremental tutorial, chapter 1.

You might want to refer to this tutorial for full implementation details.

Configuration files

Web applications that sign in users by using the Microsoft identity platform are configured through configuration files. Those files must specify the following values:

  • The cloud instance if you want your app to run in national clouds, for example. The different options include;
    • https://login.microsoftonline.com/ for Azure public cloud
    • https://login.microsoftonline.us/ for Azure US government
    • https://login.microsoftonline.de/ for Microsoft Entra Germany
    • https://login.partner.microsoftonline.cn/common for Microsoft Entra China operated by 21Vianet
  • The audience in the tenant ID. The options vary depending on whether your app is single tenant or multitenant.
    • The tenant GUID obtained from the Azure portal to sign in users in your organization. You can also use a domain name.
    • organizations to sign in users in any work or school account
    • common to sign in users with any work or school account or Microsoft personal account
    • consumers to sign in users with a Microsoft personal account only
  • The client ID for your application, as copied from the Azure portal

You might also see references to the authority, a concatenation of the instance and tenant ID values.

In ASP.NET Core, these settings are located in the appsettings.json file, in the "Microsoft Entra ID" section.

{
  "AzureAd": {
    "Instance": "https://login.microsoftonline.com/",
    "TenantId": "[Enter the tenantId here]",

    // Client ID (application ID) obtained from the Azure portal
    "ClientId": "[Enter the Client Id here]",
    "CallbackPath": "/signin-oidc",
    "SignedOutCallbackPath": "/signout-oidc"
  }
}

In ASP.NET Core, another file (properties\launchSettings.json) contains the URL (applicationUrl) and the TLS/SSL port (sslPort) for your application and various profiles.

{
  "iisSettings": {
    "windowsAuthentication": false,
    "anonymousAuthentication": true,
    "iisExpress": {
      "applicationUrl": "http://localhost:3110/",
      "sslPort": 44321
    }
  },
  "profiles": {
    "IIS Express": {
      "commandName": "IISExpress",
      "launchBrowser": true,
      "environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "Development"
      }
    },
    "webApp": {
      "commandName": "Project",
      "launchBrowser": true,
      "environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "Development"
      },
      "applicationUrl": "http://localhost:3110/"
    }
  }
}

In the Azure portal, the redirect URIs that you register on the Authentication page for your application need to match these URLs. For the two preceding configuration files, they would be https://localhost:44321/signin-oidc. The reason is that applicationUrl is http://localhost:3110, but sslPort is specified (44321). CallbackPath is /signin-oidc, as defined in appsettings.json.

In the same way, the sign-out URI would be set to https://localhost:44321/signout-oidc.

Note

SignedOutCallbackPath should set either to portal or the application to avoid conflict while handling the event.

Initialization code

The initialization code differences are platform dependent. For ASP.NET Core and ASP.NET, signing in users is delegated to the OpenID Connect middleware. The ASP.NET or ASP.NET Core template generates web applications for the Azure AD v1.0 endpoint. Some configuration is required to adapt them to the Microsoft identity platform.

In ASP.NET Core web apps (and web APIs), the application is protected because you have a Authorize attribute on the controllers or the controller actions. This attribute checks that the user is authenticated. Prior to the release of .NET 6, the code initialization was in the Startup.cs file. New ASP.NET Core projects with .NET 6 no longer contain a Startup.cs file. Taking its place is the Program.cs file. The rest of this tutorial pertains to .NET 5 or lower.

Note

If you want to start directly with the new ASP.NET Core templates for Microsoft identity platform, that leverage Microsoft.Identity.Web, you can download a preview NuGet package containing project templates for .NET 5.0. Then, once installed, you can directly instantiate ASP.NET Core web applications (MVC or Blazor). See Microsoft.Identity.Web web app project templates for details. This is the simplest approach as it will do all the following steps for you.

If you prefer to start your project with the current default ASP.NET Core web project within Visual Studio or by using dotnet new mvc --auth SingleOrg or dotnet new webapp --auth SingleOrg, you'll see code like the following:

 services.AddAuthentication(AzureADDefaults.AuthenticationScheme)
         .AddAzureAD(options => Configuration.Bind("AzureAd", options));

This code uses the legacy Microsoft.AspNetCore.Authentication.AzureAD.UI NuGet package which is used to create an Azure Active Directory v1.0 application. This article explains how to create a Microsoft identity platform v2.0 application which replaces that code.

  1. Add the Microsoft.Identity.Web and Microsoft.Identity.Web.UI NuGet packages to your project. Remove the Microsoft.AspNetCore.Authentication.AzureAD.UI NuGet package if it's present.

  2. Update the code in ConfigureServices so that it uses the AddMicrosoftIdentityWebApp and AddMicrosoftIdentityUI methods.

    public class Startup
    {
     ...
     // This method gets called by the runtime. Use this method to add services to the container.
     public void ConfigureServices(IServiceCollection services)
     {
      services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
             .AddMicrosoftIdentityWebApp(Configuration, "AzureAd");
    
      services.AddRazorPages().AddMvcOptions(options =>
      {
       var policy = new AuthorizationPolicyBuilder()
                     .RequireAuthenticatedUser()
                     .Build();
       options.Filters.Add(new AuthorizeFilter(policy));
      }).AddMicrosoftIdentityUI();
    
  3. In the Configure method in Startup.cs, enable authentication with a call to app.UseAuthentication(); and app.MapControllers();.

    // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
     // more code here
     app.UseAuthentication();
     app.UseAuthorization();
    
     app.MapRazorPages();
     app.MapControllers();
     // more code here
    }
    

In that code:

  • The AddMicrosoftIdentityWebApp extension method is defined in Microsoft.Identity.Web, which;

    • Configures options to read the configuration file (here from the "Microsoft Entra ID" section)
    • Configures the OpenID Connect options so that the authority is the Microsoft identity platform.
    • Validates the issuer of the token.
    • Ensures that the claims corresponding to name are mapped from the preferred_username claim in the ID token.
  • In addition to the configuration object, you can specify the name of the configuration section when calling AddMicrosoftIdentityWebApp. By default, it's AzureAd.

  • AddMicrosoftIdentityWebApp has other parameters for advanced scenarios. For example, tracing OpenID Connect middleware events can help you troubleshoot your web application if authentication doesn't work. Setting the optional parameter subscribeToOpenIdConnectMiddlewareDiagnosticsEvents to true will show you how information is processed by the set of ASP.NET Core middleware as it progresses from the HTTP response to the identity of the user in HttpContext.User.

  • The AddMicrosoftIdentityUI extension method is defined in Microsoft.Identity.Web.UI. It provides a default controller to handle sign-in and sign-out.

For more information about how Microsoft.Identity.Web enables you to create web apps, see Web Apps in microsoft-identity-web.

Next step