private void ConfigureOpenIdConnectAuthentication(OpenIdConnectAuthenticationOptions options) { // from original template options.AutomaticAuthentication = true; options.ClientId = Configuration["Authentication:AzureAd:ClientId"]; options.Authority = Configuration["Authentication:AzureAd:AADInstance"] + Configuration["Authentication:AzureAd:Tenant"]; options.PostLogoutRedirectUri = Configuration["Authentication:AzureAd:PostLogoutRedirectUri"]; options.SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme; options.RedirectUri = Configuration["Authentication:AzureAd:PostLogoutRedirectUri"]; options.Scope = "openid"; options.ResponseType = "id_token"; //options.ConfigurationManager = new PolicyConfigurationManager(options.Authority + "/v2.0/.well-known/openid-configuration", // new string[] { "B2C_1_SiUp", "b2c_1_siin", "B2C_1_SiPe" }); var configurationManager = new PolicyConfigurationManager(); configurationManager.AddPolicy("common", "https://login.microsoftonline.com/common/v2.0/.well-known/openid-configuration"); configurationManager.AddPolicy("b2c_1_siup", string.Format(CultureInfo.InvariantCulture, "{0}{1}?p={2}", options.Authority, "/v2.0/.well-known/openid-configuration", "b2c_1_siup")); configurationManager.AddPolicy("b2c_1_siin", string.Format(CultureInfo.InvariantCulture, "{0}{1}?p={2}", options.Authority, "/v2.0/.well-known/openid-configuration", "b2c_1_siin")); configurationManager.AddPolicy("b2c_1_sipe", string.Format(CultureInfo.InvariantCulture, "{0}{1}?p={2}", options.Authority, "/v2.0/.well-known/openid-configuration", "b2c_1_sipe")); options.ConfigurationManager = configurationManager; options.TokenValidationParameters = new System.IdentityModel.Tokens.TokenValidationParameters() { //NameClaimType = "name" ValidateIssuer = false }; options.Notifications = CreateOpenIdConnectAuthenticationNotifications(); }
// This notification can be used to manipulate the OIDC request before it is sent. Here we use it to send the correct policy. private async Task OnRedirectToIdentityProvider(RedirectToIdentityProviderNotification <OpenIdConnectMessage, OpenIdConnectAuthenticationOptions> notification) { PolicyConfigurationManager mgr = notification.Options.ConfigurationManager as PolicyConfigurationManager; if (notification.ProtocolMessage.RequestType == OpenIdConnectRequestType.LogoutRequest) { OpenIdConnectConfiguration config = await mgr.GetConfigurationByPolicyAsync(CancellationToken.None, notification.OwinContext.Authentication.AuthenticationResponseRevoke.Properties.Dictionary[Startup.PolicyKey]); notification.ProtocolMessage.IssuerAddress = config.EndSessionEndpoint; } else { OpenIdConnectConfiguration config = await mgr.GetConfigurationByPolicyAsync(CancellationToken.None, notification.OwinContext.Authentication.AuthenticationResponseChallenge.Properties.Dictionary[Startup.PolicyKey]); notification.ProtocolMessage.IssuerAddress = config.AuthorizationEndpoint; } }
private OpenIdConnectAuthenticationNotifications CreateOpenIdConnectAuthenticationNotifications() { return(new OpenIdConnectAuthenticationNotifications() { MessageReceived = (context) => { return Task.FromResult(0); }, RedirectToIdentityProvider = async(context) => { PolicyConfigurationManager mgr = context.Options.ConfigurationManager as PolicyConfigurationManager; OpenIdConnectConfiguration config = null; if (context.HttpContext.Items.ContainsKey("b2cpolicy")) { string policyName = (string)context.HttpContext.Items["b2cpolicy"]; config = await mgr.GetConfigurationByPolicyAsync(System.Threading.CancellationToken.None, policyName); } else { config = await mgr.GetConfigurationByPolicyAsync(System.Threading.CancellationToken.None, "common"); } if (context.ProtocolMessage.RequestType == OpenIdConnectRequestType.LogoutRequest) { context.ProtocolMessage.IssuerAddress = config.EndSessionEndpoint; } else { context.ProtocolMessage.IssuerAddress = config.AuthorizationEndpoint; } }, SecurityTokenReceived = (context) => { return Task.FromResult(0); }, SecurityTokenValidated = (context) => { var principal = context.AuthenticationTicket.Principal; var identity = principal.Identities.First(); // TODO - We need to figure out what this looks like when multiple emails are sent. For now, we'll // assume just one. var emails = principal.FindFirst("emails")?.Value ?? principal.FindFirst("preferred_username")?.Value; if (!string.IsNullOrWhiteSpace(emails)) { identity.AddClaim(new Claim(ClaimTypes.Email, emails)); } // We need to normalize the name claim for the Identity model var name = principal.FindFirst("name")?.Value; if (!string.IsNullOrWhiteSpace(name)) { identity.AddClaim(new Claim(identity.NameClaimType, name)); } var identityProvider = principal.FindFirst( "http://schemas.microsoft.com/identity/claims/identityprovider")?.Value; if (string.IsNullOrWhiteSpace(identityProvider)) { // AAD doesn't provide this in B2C, so we'll add one. identity.AddClaim(new Claim("http://schemas.microsoft.com/identity/claims/identityprovider", "aad")); identity.AddClaim(new Claim("survey_tenant", principal.FindFirst("iss")?.Value)); } else { // Whenever we use an external auth provider besides AAD, we need to generate a "tenant" identifier, // since those users are in their own tenant. identity.AddClaim( new Claim("survey_tenant", principal.FindFirst("iss")?.Value + principal.FindFirst("http://schemas.microsoft.com/identity/claims/objectidentifier")?.Value)); } return Task.FromResult(0); }, AuthenticationFailed = (context) => { context.Response.Redirect("/Home/Error"); context.HandleResponse(); // Suppress the exception return Task.FromResult(0); } }); }