services | platforms | author | level | service | endpoint |
---|---|---|---|---|---|
active-directory |
dotnet |
jmprieur |
100 |
ASP.NET Core Web App |
AAD V2 |
This sample is for ASP.NET Core 2.0. A newer version of this sample for ASP.NET Core2.1 is available from the aspnetcore2-2 branch.
This sample shows how to build a .NET Core 2.0 and 2.1 MVC Web app that uses OpenID Connect to sign in users. Users can use personal accounts (including outlook.com, live.com, and others) as well as work and school accounts from any company or organization that has integrated with Azure Active Directory. It leverages the ASP.NET Core OpenID Connect middleware.
An on-demand video was created for the Build 2018 event, featuring this scenario and this sample. See the video Building Web App Solutions With Authentication, and the associated PowerPoint deck
This is the first of a set of tutorials. Once you understand how to sign-in users in an ASP.NET Core Web App with Open Id Connect, learn how to enable your Web App to call a Web API in the name of the user
To run this sample:
Pre-requisites: Install .NET Core (for example for Windows) by following the instructions at .NET and C# - Get Started in 10 Minutes. In addition to developing on Windows, you can develop on Linux, Mac, or Docker.
- Sign in to the Application registration portal either using a personal Microsoft account (live.com or hotmail.com) or work or school account.
- Give a name to your Application, make sure that the Guided Setup option is Unchecked. Then press Create. The portal will assign your app a globally unique Application ID that you'll use later in your code.
- Click Add Platform, and select Web.
- In the Redirect URLs field, add
http://localhost:3110/
andhttp://localhost:3110/signin-oidc
. The port number needs to be consistent with the port in the Properties/launchSettings.json file.
Note: The base address in the Sign-on URL and Logout URL settings is
http://localhost:3110
. This localhost address allows the sample app to run insecurely from your local system. If the port was not specified (in the lauchsettings.json file), port 5000 would be used as the default port for the Kestrel server. You will need to update these URLs if you configure the app for production use (for example,https://www.contoso.com/signin-oidc
andhttps://www.contoso.com/signout-oidc
).
This sample was created from the dotnet core 2.0 dotnet new mvc template with SingleOrg
authentication, and then tweaked to support tokens for the Azure AD V2 endpoint. You can clone/download this repository or create the sample from the command line:
You can clone this sample from your shell or command line:
git clone https://github.com/Azure-Samples/active-directory-aspnetcore-webapp-openidconnect-v2.git
In the appsettings.json file, replace the ClientID
value with the Application ID from the application you registered in Application Registration portal on Step 1.
-
Run the following command to create a sample from the command line using the
SingleOrg
template:dotnet new mvc --auth SingleOrg --client-id <Enter_the_Application_Id_here>
Note: Replace
Enter_the_Application_Id_here
with the Application Id from the application Id you just registered in the Application Registration Portal. -
Open Extensions\AzureAdAuthenticationBuilderExtensions.cs file and replace the
Configure
method with:public void Configure(string name, OpenIdConnectOptions options) { options.ClientId = _azureOptions.ClientId; options.Authority = $"{_azureOptions.Instance}common/v2.0"; // V2 Endpoint options.UseTokenLifetime = true; options.RequireHttpsMetadata = false; options.TokenValidationParameters.ValidateIssuer = false; // accept any tenant }
-
Modify
Views\Shared\_LoginPartial.cshtml
to have the following content:@using System.Security.Claims @if (User.Identity.IsAuthenticated) { var identity = User.Identity as ClaimsIdentity; // Azure AD V2 endpoint specific string preferred_username = identity.Claims.FirstOrDefault(c => c.Type == "preferred_username")?.Value; <ul class="nav navbar-nav navbar-right"> <li class="navbar-text">Hello @preferred_username</li> <li><a asp-area="" asp-controller="Account" asp-action="SignOut">Sign out</a></li> </ul> } else { <ul class="nav navbar-nav navbar-right"> <li><a asp-area="" asp-controller="Account" asp-action="Signin">Sign in</a></li> </ul> }
Note: This change is needed because certain token claims from Azure AD V1 endpoint (on which the original .NET core template is based) are different than Azure AD V2 endpoint.
-
Build the solution and run it.
-
Open your web browser and make a request to the app. The app immediately attempts to authenticate you via the Azure AD v2 endpoint. Sign in with your personal account or with work or school account.
By default, when you use the dotnet core template with SingleOrg
authentication option and follow the instructions in this guide to configure the application to use the Azure Active Directory v2 endpoint, both personal accounts - like outlook.com, live.com, and others - as well as Work or school accounts from any organizations that are integrated with Azure AD can sign in to your application. This is typically used on SaaS applications.
To restrict accounts type that can sign in to your application, use one of the options:
You can restrict sign-in access for your application to only user accounts that are in a single Azure AD tenant - including guest accounts of that tenant. This scenario is a common for line-of-business applications:
-
Open appsettings.json and replace the line containing the
TenantId
value with the domain of your tenant, for example, contoso.onmicrosoft.com or the guid for the Tenant ID:"TenantId": "[Enter the domain of your tenant, e.g. contoso.onmicrosoft.com or the Tenant Id]",
-
In your Extensions\AzureAdAuthenticationBuilderExtensions.cs file, replace the
Configure
method with:public void Configure(string name, OpenIdConnectOptions options) { options.ClientId = _azureOptions.ClientId; options.Authority = $"{_azureOptions.Instance}{_azureOptions.TenantId}/v2.0"; // V2 Endpoint options.UseTokenLifetime = true; options.RequireHttpsMetadata = false; options.TokenValidationParameters.ValidateIssuer = true; // Validate the tenant }
You can restrict sign-in access to only user accounts that are in a specific list of Azure AD organizations:
- In your Extensions\AzureAdAuthenticationBuilderExtensions.cs file, set the
ValidateIssuer
argument totrue
- Add a
ValidIssuers
TokenValidationParameters
parameter containing the list of allowed organizations.
You can implement a custom method to validate issuers by using the IssuerValidator parameter. For more information about how to use this parameter, read about the TokenValidationParameters class on MSDN.
You can also decide which types of user accounts can sign in to your Web App by changing the Authority. The picture below shows all the possibilities
This sample shows how to use the OpenID Connect ASP.NET Core middleware to sign in users from a single Azure AD tenant. The middleware is initialized in the Startup.cs
file by passing it the Client ID of the app and the URL of the Azure AD tenant where the app is registered, which is read from the appsettings.json
file. The middleware takes care of:
- Downloading the Azure AD metadata, finding the signing keys, and finding the issuer name for the tenant.
- Processing OpenID Connect sign-in responses by validating the signature and issuer in an incoming JWT, extracting the user's claims, and putting the claims in
ClaimsPrincipal.Current
. - Integrating with the session cookie ASP.NET Core middleware to establish a session for the user.
You can trigger the middleware to send an OpenID Connect sign-in request by decorating a class or method with the [Authorize]
attribute or by issuing a challenge (see the AccountController.cs
file):
return Challenge(
new AuthenticationProperties { RedirectUri = redirectUrl },
OpenIdConnectDefaults.AuthenticationScheme);
Similarly, you can send a sign-out request:
return SignOut(
new AuthenticationProperties { RedirectUri = callbackUrl },
CookieAuthenticationDefaults.AuthenticationScheme,
OpenIdConnectDefaults.AuthenticationScheme);
The middleware in this project is created as a part of the open-source ASP.NET Security project.
The token validation is performed by the classes of the Identity Model Extensions for DotNet library. Learn how to customize token validation by reading the Conceptual Documentation section of ValidatingTokens.
Now that you understand how to sign in users in an ASP.NET Core Web App with Open ID Connect, learn how to enable your Web App to call a Web API in the name of the user.