6.8 KiB
How to Use the Azure Active Directory Authentication for MVC / Razor Page Applications
Introduction
This post demonstrates how to integrate AzureAD to an ABP application that enables users to sign in using OAuth 2.0 with credentials from Azure Active Directory.
Adding Azure Active Directory is pretty straightforward in ABP framework. Couple of configurations needs to be done correctly.
There will be two samples of connections for better coverage;
- AddAzureAD (Microsoft.AspNetCore.Authentication.AzureAD.UI package)
- AddOpenIdConnect (Default Microsoft.AspNetCore.Authentication.OpenIdConnect package)
Sample Code
https://github.com/abpframework/abp-samples/tree/master/aspnet-core/BookStore-AzureAD
Setup
Update your appsettings.json
in your .Web application and add the following section filled with your AzureAD application settings.
"AzureAd": {
"Instance": "https://login.microsoftonline.com/",
"TenantId": "<your-tenant-id",
"ClientId": "<your-client-id>",
"Domain": "domain.onmicrosoft.com",
"CallbackPath": "/signin-azuread-oidc"
}
AddAzureAD
Update your appsettings.json
Install Microsoft.AspNetCore.Authentication.AzureAD.UI
package to your .Web application.
In your .Web application, add the following section filled with your AzureAD application settings. Modify ConfigureAuthentication
method of your BookStoreWebModule with the following:
private void ConfigureAuthentication(ServiceConfigurationContext context, IConfiguration configuration)
{
JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();
JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Add("sub", ClaimTypes.NameIdentifier);
context.Services.AddAuthentication()
.AddIdentityServerAuthentication(options =>
{
options.Authority = configuration["AuthServer:Authority"];
options.RequireHttpsMetadata = false;
options.ApiName = "Acme.BookStore";
})
.AddAzureAD(options => configuration.Bind("AzureAd", options));
context.Services.Configure<OpenIdConnectOptions>(AzureADDefaults.OpenIdScheme, options =>
{
options.Authority = options.Authority + "/v2.0/";
options.ClientId = configuration["AzureAd:ClientId"];
options.CallbackPath = configuration["AzureAd:CallbackPath"];
options.ResponseType = OpenIdConnectResponseType.IdToken;
options.RequireHttpsMetadata = false;
options.TokenValidationParameters.ValidateIssuer = false;
options.GetClaimsFromUserInfoEndpoint = true;
options.SaveTokens = true;
options.SignInScheme = IdentityConstants.ExternalScheme;
options.Scope.Add("email");
});
}
AddOpenIdConnect
Modify ConfigureAuthentication
method of your BookStoreWebModule with the following:
private void ConfigureAuthentication(ServiceConfigurationContext context, IConfiguration configuration)
{
JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();
JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Add("sub", ClaimTypes.NameIdentifier);
context.Services.AddAuthentication()
.AddIdentityServerAuthentication(options =>
{
options.Authority = configuration["AuthServer:Authority"];
options.RequireHttpsMetadata = false;
options.ApiName = "BookStore";
})
.AddOpenIdConnect("AzureOpenId", "AzureAD", options =>
{
options.Authority = "https://login.microsoftonline.com/" + configuration["AzureAd:TenantId"];
options.ClientId = configuration["AzureAd:ClientId"];
options.ResponseType = OpenIdConnectResponseType.CodeIdToken;
options.CallbackPath = configuration["AzureAd:CallbackPath"];
options.RequireHttpsMetadata = false;
options.SaveTokens = true;
options.GetClaimsFromUserInfoEndpoint = true;
});
}
FAQ
-
Help!
GetExternalLoginInfoAsync
returnsnull
!-
There can be 2 reasons for this;
-
You are trying to authenticate against wrong scheme. Check if you set SignInScheme to
IdentityConstants.ExternalScheme
:options.SignInScheme = IdentityConstants.ExternalScheme;
-
Your
ClaimTypes.NameIdentifier
isnull
. Check if you added claim mapping:JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear(); JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Add("sub", ClaimTypes.NameIdentifier);
-
-
-
Help! I keep getting AADSTS50011: The reply URL specified in the request does not match the reply URLs configured for the application error!
-
If you set your CallbackPath in appsettings as:
"AzureAd": { ... "CallbackPath": "/signin-azuread-oidc" }
your Redirect URI of your application in azure portal must be with domain like
https://localhost:44320/signin-azuread-oidc
, not only/signin-azuread-oidc
.
-
-
Help! I am getting System.ArgumentNullException: Value cannot be null. (Parameter 'userName') error!
-
This occurs when you use Azure Authority v2.0 endpoint without requesting
email
scope. Abp checks unique email to create user. Simply addoptions.Scope.Add("email");
to your openid configuration.
-
-
How can I debug/watch which claims I get before they get mapped?
-
You can add a simple event under openid configuration to debug before mapping like:
options.Events.OnTokenValidated = (async context => { var claimsFromOidcProvider = context.Principal.Claims.ToList(); await Task.CompletedTask; });
-
-
I want to debug further, how can I implement my custom SignInManager?
- You can check [Customizing SignInManager in Abp Framework](link here) post.
-
I want to add extra properties to user while they are being created. How can I do that?
- You can check Customizing Login Page in Abp Framework post.
-
Why can't I see External Register Page after I sign in from external provider for the first time?
- ABP framework automatically registers your user with supported email claim from your external authentication provider. You can change this behavior by [Customizing Login Page in Abp Framework](will be link here).