In 5 easy steps, I will show you how to implement secured user login using Azure AD with React.js and ASP.NET Core Web API. Azure Active Directory (Azure AD) is a cloud-based identity and access management (IAM) service that helps you secure access to your applications and resources. Here are some reasons why you would want to consider using a secured login service like AzureAd.
- Strong authentication
- Single sign-on
- Conditional access
- Reporting and auditing
- Cost-effectiveness
- Ease of use
- Reliability
Now that I have convinced you to use Azure AD to secure your next big application. Follow the steps outlined below to step up login authentication using React and ASP.Net web API
- Set up an Azure AD Application:
- Go to the Azure portal (portal.azure.com) and sign in.
- Navigate to Azure Active Directory and select “App registrations.”
- Click on “New Registration” to create a new Azure AD application.
- Provide a name for your application, choose the supported account types, and specify the redirect URI for your React.js application (e.g., http://localhost:3000/callback).
- After creating the application, note down the “Application (client) ID” and “Directory (tenant) ID” as you will need them later.
- Configure Azure AD Authentication for your ASP.NET Core Web API:
- In your ASP.NET Core Web API project, install Microsoft.Identity.Web NuGet package.
- Open the appsettings.json file and add the Azure AD configuration settings, including the “Scopes” “ClientId” (Application ID), “TenantId” (Directory ID) and Instance obtained from the Azure portal.
- Implement Authentication in the React.js Application:
- Install the msal.js library using npm install msal.
- Create a file, e.g., authConfig.js, to store your Azure AD configuration settings for the React.js application.
- In this file, define the msalConfig object with the “clientId” and “authority” (use the https://login.microsoftonline.com/your-tenant-id format) properties.
- Create a AuthService.js file to handle the authentication logic using the msal.js library. Implement methods like login, logout, and getAccessToken.
- Inside your React.js components, use the AuthService to authenticate users and obtain access tokens.
- Secure your ASP.NET Core Web API:
- In the Startup.cs file of your Web API project, configure Azure AD authentication using services.AddAuthentication().AddAzureADBearer(options => Configuration.Bind(“AzureAd”, options)).
- Add the [Authorize] attribute to protect the appropriate controller or action methods.
- Test the User Login:
- Run your React.js application and test the login functionality. It should redirect to the Azure AD login page.
- After successful login, the React.js application should receive an access token.
- Use this access token to make authenticated requests to your ASP.NET Core Web API. The API should validate the token and allow access to authorized endpoints.
Code explanation for step 2
Let’s see the code in action after you have set up your AzureAD in your Azure portal. Let us jump to step two. It is important that you put AzureAd credentials in your appsettings like so
"AzureAd": { "Instance": "https://login.microsoftonline.com/", "Domain": "mydomain.com", "TenantId": "<Tenantid here>", "ClientId": "<ClientId hete>", "scopes": "api://<ClientId hete>" },
You might need to enable extra logging in your appsettings as well, and this will help to see the errors encountered so you can fix them accordingly.
"LogLevel": { "Default": "Information", "Microsoft.AspNetCore": "Warning", "Microsoft.IdentityModel": "Information", "Microsoft.AspNetCore.Authentication": "Information" }
You might need to enable extra logging in your appsettings as well, and this will help to see the errors encountered so you can fix them accordingly.
Code explanation for step 2
Implement Authentication in the React.js Application
Create a file and name it authConfig.js, then add the code below to it:
const azureAdConfig = { clientId: '<your-client-id>', authority: 'https://login.microsoftonline.com/your-tenant-id' }; export default azureAdConfig;
After that, create another file and name it AuthService.js
And add the code below
import { PublicClientApplication } from '@azure/msal-browser'; const msalConfig = { auth: { clientId: 'your-client-id', authority: 'https://login.microsoftonline.com/your-tenant-id', redirectUri: 'http://localhost:3000/callback' } }; const loginRequest = { scopes: ['openid', 'profile'] }; const authService = new PublicClientApplication(msalConfig); const login = async () => { try { await authService.loginPopup(loginRequest); // Handle successful login } catch (error) { // Handle login error } }; const logout = () => { authService.logout(); }; const getAccessToken = async () => { try { const response = await authService.acquireTokenSilent(loginRequest); return response.accessToken; } catch (error) { // Handle token acquisition error } }; export { login, logout, getAccessToken };
Code explanation for step 4: Securing your ASP.NET Core Web API
In your program.cs file or startup file, add the code below and import the namespaces
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) .AddMicrosoftIdentityWebApi(builder.Configuration.GetSection("AzureAd")); // Configure the HTTP request pipeline. if (app.Environment.IsDevelopment()) { app.UseSwagger(); app.UseSwaggerUI(); IdentityModelEventSource.ShowPII = true; } app.UseHttpsRedirection(); app.UseRouting(); app.UseAuthentication(); app.UseAuthorization();
If you have problems with roles, add the code below to your program file and appsettings
var roleSettings = builder.Configuration.GetSection("AdRole").Get<AdRole>(); if (string.IsNullOrWhiteSpace(roleSettings.Role1)) roleSettings.Role1 = ClaimTypes.Role; builder.Services.AddAuthorization(options => { options.AddPolicy("role1", policy => policy.RequireClaim(roleSettings.Role1, "role1", "role2")); options.AddPolicy("role2", policy => policy.RequireClaim(roleSettings.Role1, "role2")); });
Code explanation for step 5: Test the User Login
import { login, logout, getAccessToken } from './AuthService'; function App() { const handleLogin = async () => { await login(); }; const handleLogout = () => { logout(); }; const handleProtectedApiCall = async () => { const accessToken = await getAccessToken(); // Make API call with the access token }; return ( <div> <button onClick={handleLogin}>Login</button> <button onClick={handleLogout}>Logout</button> <button onClick={handleProtectedApiCall}>Call Protected API</button> </div> ); }