Microsoft authentication in .NET Core

2 
years ago
  by Valeriy Novytskyy  at Emerald Line/ 4 min
to read

How to let users login with a Microsoft account in .NET Core

overview

Follow this tutorial to enable users to sign in to your ASP.NET Core application with their work, school, or personal Microsoft account by using the official Microsoft.AspNetCore.Authentication.MicrosoftAccount NuGet package.

To create a new .NET Core application in Visual Studio:

  • Select the ASP.NET Core Web App template and name the project
  • Select Individual User Accounts as the Authentication type

To create a new .NET Core application in Visual Studio Code on Mac:

dotnet new webapp -o projectname -au Individual

SQLite will be used as the database by default.

To create a new .NET Core application in Visual Studio Code on Windows:

dotnet new webapp -o projectname -au Individual -uld

LocalDB will be used as the database with the -uld option.

Install the MicrosoftAccount package used for authentication in this tutorial:

dotnet add package \
Microsoft.AspNetCore.Authentication.MicrosoftAccount

Run the new application to verify the initial setup was successful:

dotnet run

app registration

Signing in with an OAuth provider like Microsoft requires registering your application to get a unique Client ID and Client Secret which are like a user name and password used by the provider to identify your application. For Microsoft accounts this is done by creating an App Registration in Azure Portal.

  1. Sign in to the Azure Portal
  2. Open the App Registrations blade of Azure Active Directory service
  3. Click New Registration

Enter a Name and select a Supported account type:

  • The MicrosoftAccount package used in this tutorial supports “Accounts in any organizational directory (Any Azure AD directory - Multitenant)” and “Accounts in any organizational directory (Any Azure AD directory - Multitenant) and personal Microsoft accounts (e.g. Skype, Xbox) ” options by default.
  • To use the other options you will have to pass in additional settings when configuring the authentication middleware in the next step.

Select the Web platform under Redirect URI and enter your development URL, appending /signin-microsoft to the end, for example:

https://localhost:7158/signin-microsoft
/*

The Microsoft authentication middleware automatically handles requests at /signin-microsoft route to implement the OAuth flow. The route name can be customized when configuring the middleware later.

*/

Click Register to create the App Registration.

secret storage

With .NET core you have many options for storing sensitive settings:

Multiple providers can be configured to merge settings from different sources. For example you can use the Secret Manager for local development and your application will switch to Azure KeyVault when it’s running in the cloud.

In this tutorial we’ll stick to the Secret Manager even though Environment Variables are a more universal way to load settings because .NET Core does not support .env files out of the box. See the Dusted Codes tutorial for creating a custom settings provider to load from .env if you’re interested.

Locate the Application (client) ID field on the Overview page of the new App Registration and substitute it for <client-id> in the following command:

dotnet user-secrets \
set "Authentication:Microsoft:ClientId" "<client-id>"

Generate and configure a secret for your App Registration:

  1. Go to the Certificates & secrets blade of the App Registration and click New client secret
  2. Enter your description and select expiration
  3. Click Add on the bottom of the blade

You will see a new row added to Client secrets on Certificates & secrets blade, with the Value field containing the secret you need for this step.

/*

Ignore the Secret ID field as that’s a unique ID for the secret itself, needed because Azure lets you configure multiple secrets.

*/

Configure the client secret for your application using the Secret Manager:

dotnet user-secrets \
set "Authentication:Microsoft:ClientSecret" "<secret>"

auth middleware

The last step is to configure the Microsoft authentication middleware by calling AddAuthentication and then AddMicrosoftAccount:

builder.Services
.AddAuthentication()
.AddMicrosoftAccount(microsoftOptions =>
{
microsoftOptions.ClientId = builder.Configuration
["Authentication:Microsoft:ClientId"];
microsoftOptions.ClientSecret = builder.Configuration
["Authentication:Microsoft:ClientSecret"];
});

If you selected “Accounts in this organizational directory only (Default Directory only - Single tenant)” or “Personal Microsoft accounts only” account type when creating the App Registration, click Endpoints on the App Registration Overview blade to look up the endpoints to use.

/*

The account type selected when creating the App Registration is available on Authentication blade under Supported account types.

*/

  • The OAuth 2.0 authorization endpoint (v2) contains the value for AuthorizationEnpoint option in the snippet below.
  • The OAuth 2.0 token endpoint (v2) contains the value for TokenEndpoint option in the snippet below.

These settings are not secrets and can be stored in appsettings.json. Plug them into the call to AddMicrosoftAccount added in the previous listing:

microsoftOptions.AuthorizationEndpoint = builder.Configuration
["Authentication:Microsoft:AuthorizationEndpoint"];
microsoftOptions.TokenEndpoint = builder.Configuration
["Authentication:Microsoft:TokenEndpoint"];

test authentication

Your users will have to go through the following steps to create a new account:

  • Click Login on the top navigation
  • On the Login page under Use Another Service to Login, click Microsoft
  • You will be redirected to login with your Microsoft account
  • Accept to be redirected back to your application to finish registration
  • Register to create a new user account in the database using the email address extracted from the user’s Microsoft account
  • Confirm your email to complete the new account setup

how it works

The package used in this tutorial implements the OAuth 2 Authorization Code Grant on the backend. See Aaron Parecki’s friendly description of this flow.

test
Browser.NET AppAzure ADBrowserBrowserAzure ADAzure AD.NET App.NET App123564

  1. The user clicks LoginLogin with Another ProviderMicrosoft
  2. The OAuth middleware in MicrosoftAccount package redirects the user to oauth2/v2.0/authorize endpoint
  3. Azure AD redirects back to your ASP.NET backend, sending either the authorization code or an error
  4. The middleware in MicrosoftAccount package intercepts the request and calls the Azure Active Directory token endpoint to exchange the authorization code it received with an access token
  5. Azure AD returns an OAuth 2.0 token to your ASP.NET backend, which can be used to access user profile information
  6. The user is authorized to access password-protected parts of your application, and has an option to create an individual account so that they can access your application directly without the Microsoft login

The following section details what happens during the authorization grant process.

authorizecodecodetokencookieFrontendProviderBackend

The OAuth middleware in MicrosoftAccount package redirects the user to oauth2/v2.0/authorize endpoint:

query parametervalue
client idApp Registration Client ID
response_typecode
stateUnique authorization request identifier
redirect_uriMust match redirect URI in App Registration
scopeprofile

Azure AD redirects back to your ASP.NET backend, sending either the authorization code or an error:

query parametervalue
codeAuthorization code
stateThe same value provided for state earlier

The middleware in MicrosoftAccount package intercepts the request and calls the Azure Active Directory token endpoint to exchange the authorization code it received with an access token:

form parametervalue
grant_typeauthorization_code
codeThe value received from the previous request
redirect_uriMust match the same value from the first request
client_idApp Registration Client ID
client_secretApp Registration Secret

When the .NET application returns the successful response back to the browser, it will set .AspNetCore.Identity.Application cookie containing a session for the logged in user account.

Loading comments...