From 272ca7b315c224ebd71929c12826ab78172c2f2e Mon Sep 17 00:00:00 2001 From: Galip Tolga Erdem Date: Sat, 28 Mar 2020 05:13:28 +0300 Subject: [PATCH] added initial post --- docs/en/Blog-Posts/2020-04-01/Post.md | 176 ++++++++++++++++++++++++++ 1 file changed, 176 insertions(+) create mode 100644 docs/en/Blog-Posts/2020-04-01/Post.md diff --git a/docs/en/Blog-Posts/2020-04-01/Post.md b/docs/en/Blog-Posts/2020-04-01/Post.md new file mode 100644 index 0000000000..bc3148ec5e --- /dev/null +++ b/docs/en/Blog-Posts/2020-04-01/Post.md @@ -0,0 +1,176 @@ +# Using Azure Active Directory Authentication in ABP 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 covarage; + +- **AddOpenIdConnect** (Default Microsoft.AspNetCore.Authentication.OpenIdConnect package) +- **AddAzureAD** (Microsoft.AspNetCore.Authentication.AzureAD.UI package) + + + +## AddOpenIdConnect + +#### **Update your `appsettings.json`** + +In your **.Web** application, add the following section filled with your AzureAD application settings. + +````xml + "AzureAd": { + "Instance": "https://login.microsoftonline.com/", + "TenantId": "", + "ClientSecret": "", + "Domain": "domain.onmicrosoft.com", + "CallbackPath": "/signin-azuread-oidc" + } +```` + +Modify `ConfigureAuthentication` method of your **BookStoreWebModule** with the following: + +````xml +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.ClientSecret = configuration["AzureAd:ClientSecret"]; + options.RequireHttpsMetadata = false; + options.SaveTokens = true; + options.GetClaimsFromUserInfoEndpoint = true; + }); + } +```` + + + +## 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. + +Notice that you don't need to add `ClientSecret` when you are using `Microsoft.AspNetCore.Authentication.AzureAD.UI` package. + +````xml + "AzureAd": { + "Instance": "https://login.microsoftonline.com/", + "TenantId": "", + "Domain": "domain.onmicrosoft.com", + "CallbackPath": "/signin-azuread-oidc" + } +```` + +Modify `ConfigureAuthentication` method of your **BookStoreWebModule** with the following: + +````xml +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(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"); + }); + } +```` + + + +# FAQ + +* Help! `GetExternalLoginInfoAsync` returns `null`! + + * There can be 2 reasons for this; + + 1. You are trying to authenticate against wrong scheme. Check if you set **SignInScheme** to `IdentityConstants.ExternalScheme`: + + ````xml + options.SignInScheme = IdentityConstants.ExternalScheme; + ```` + + 2. Your `ClaimTypes.NameIdentifier` is null. Check if you added claim mapping: + + ````xml + 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: + + ````xml + "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`. + +* 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: + + ````xml + 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 behaviour by [Customizing Login Page in Abp Framework](will be link here). +