diff --git a/Areas/AzureADB2C/Pages/Account/SignedOut.cshtml b/Areas/MicrosoftIdentity/Pages/Account/SignedOut.cshtml similarity index 87% rename from Areas/AzureADB2C/Pages/Account/SignedOut.cshtml rename to Areas/MicrosoftIdentity/Pages/Account/SignedOut.cshtml index 370b23d..036db74 100644 --- a/Areas/AzureADB2C/Pages/Account/SignedOut.cshtml +++ b/Areas/MicrosoftIdentity/Pages/Account/SignedOut.cshtml @@ -1,5 +1,4 @@ -@page "/AzureADB2C/Account/SignedOut" -@namespace BlazorSimpleSurvey.Pages +@namespace BlazorSimpleSurvey.Pages @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers @{ Layout = null; diff --git a/BlazorSimpleSurvey.csproj b/BlazorSimpleSurvey.csproj index 092cd40..885c830 100644 --- a/BlazorSimpleSurvey.csproj +++ b/BlazorSimpleSurvey.csproj @@ -6,13 +6,14 @@ - + + - + diff --git a/Shared/LoginDisplay.razor b/Shared/LoginDisplay.razor index ea36c02..240b0e1 100644 --- a/Shared/LoginDisplay.razor +++ b/Shared/LoginDisplay.razor @@ -1,22 +1,22 @@ -@using Microsoft.AspNetCore.Authentication.AzureADB2C.UI +@using Microsoft.Identity.Web @using Microsoft.Extensions.Options -@inject IOptionsMonitor AzureADB2COptions +@inject IOptionsMonitor microsoftIdentityOptions @inject AuthenticationStateProvider AuthenticationStateProvider @if (canEditProfile) { - Hello, @FirstName! + Hello, @FirstName! } else { Hello, @FirstName! } - Log out + Log out - Log in + Log in @@ -26,7 +26,7 @@ protected override async Task OnInitializedAsync() { - var options = AzureADB2COptions.Get(AzureADB2CDefaults.AuthenticationScheme); + var options = microsoftIdentityOptions.CurrentValue; canEditProfile = !string.IsNullOrEmpty(options.EditProfilePolicyId); var authState = await AuthenticationStateProvider.GetAuthenticationStateAsync(); diff --git a/Startup.cs b/Startup.cs index 2930825..fa03870 100644 --- a/Startup.cs +++ b/Startup.cs @@ -4,7 +4,6 @@ using System.Threading.Tasks; using BlazorSimpleSurvey.Data; using Microsoft.AspNetCore.Authentication; -using Microsoft.AspNetCore.Authentication.AzureADB2C.UI; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Components; using Microsoft.AspNetCore.Hosting; @@ -19,6 +18,8 @@ using BlazorSimpleSurvey.Models; using System.Linq.Dynamic.Core; using Radzen; +using Microsoft.Identity.Web; +using Microsoft.Identity.Web.UI; namespace BlazorSimpleSurvey { @@ -38,220 +39,219 @@ public void ConfigureServices(IServiceCollection services) services.AddDbContext(options => options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection"))); - services.AddAuthentication(AzureADB2CDefaults.AuthenticationScheme) - .AddAzureADB2C(options => Configuration.Bind("AzureAdB2C", options)); - // This is where you wire up to events to detect when a user logs in - services.Configure(AzureADB2CDefaults.OpenIdScheme, options => - { - options.Events = new OpenIdConnectEvents + services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme) + .AddMicrosoftIdentityWebApp(options => { - OnRedirectToIdentityProvider = async ctxt => - { - // Invoked before redirecting to the identity provider to authenticate. - // This can be used to set ProtocolMessage.State - // that will be persisted through the authentication process. - // The ProtocolMessage can also be used to add or customize - // parameters sent to the identity provider. - await Task.Yield(); - }, - OnAuthenticationFailed = async ctxt => + Configuration.Bind("AzureAdB2C", options); + options.Events = new OpenIdConnectEvents { - // They tried to log in but it failed - await Task.Yield(); - }, - OnTicketReceived = async ctxt => - { - if (ctxt.Principal.Identity is ClaimsIdentity identity) + OnRedirectToIdentityProvider = async ctxt => { - // Set common values - AuthClaims objAuthClaims = new AuthClaims(); - - var colClaims = await ctxt.Principal.Claims.ToDynamicListAsync(); - - objAuthClaims.IdentityProvider = colClaims.FirstOrDefault( - c => c.Type == "http://schemas.microsoft.com/identity/claims/identityprovider")?.Value; - - objAuthClaims.Objectidentifier = colClaims.FirstOrDefault( - c => c.Type == "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier")?.Value; - - objAuthClaims.EmailAddress = colClaims.FirstOrDefault( - c => c.Type == "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress")?.Value; + // Invoked before redirecting to the identity provider to authenticate. + // This can be used to set ProtocolMessage.State + // that will be persisted through the authentication process. + // The ProtocolMessage can also be used to add or customize + // parameters sent to the identity provider. + await Task.Yield(); + }, + OnAuthenticationFailed = async ctxt => + { + // They tried to log in but it failed + await Task.Yield(); + }, + OnTicketReceived = async ctxt => + { + if (ctxt.Principal.Identity is ClaimsIdentity identity) + { + // Set common values + AuthClaims objAuthClaims = new AuthClaims(); - objAuthClaims.FirstName = colClaims.FirstOrDefault( - c => c.Type == "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname")?.Value; + var colClaims = await ctxt.Principal.Claims.ToDynamicListAsync(); - objAuthClaims.LastName = colClaims.FirstOrDefault( - c => c.Type == "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/surname")?.Value; + objAuthClaims.IdentityProvider = colClaims.FirstOrDefault( + c => c.Type == "http://schemas.microsoft.com/identity/claims/identityprovider")?.Value; - objAuthClaims.AzureB2CFlow = colClaims.FirstOrDefault( - c => c.Type == "http://schemas.microsoft.com/claims/authnclassreference")?.Value; + objAuthClaims.Objectidentifier = colClaims.FirstOrDefault( + c => c.Type == "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier")?.Value; - objAuthClaims.auth_time = colClaims.FirstOrDefault( - c => c.Type == "auth_time")?.Value; + objAuthClaims.EmailAddress = colClaims.FirstOrDefault( + c => c.Type == "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress")?.Value; - objAuthClaims.DisplayName = colClaims.FirstOrDefault( - c => c.Type == "name")?.Value; + objAuthClaims.FirstName = colClaims.FirstOrDefault( + c => c.Type == "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname")?.Value; - objAuthClaims.idp_access_token = colClaims.FirstOrDefault( - c => c.Type == "idp_access_token")?.Value; + objAuthClaims.LastName = colClaims.FirstOrDefault( + c => c.Type == "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/surname")?.Value; - // Google login - if (objAuthClaims.IdentityProvider.ToLower().Contains("google")) - { - objAuthClaims.AuthenticationType = "Google"; - } + objAuthClaims.AzureB2CFlow = colClaims.FirstOrDefault( + c => c.Type == "http://schemas.microsoft.com/claims/authnclassreference")?.Value; - // Microsoft account login - if (objAuthClaims.IdentityProvider.ToLower().Contains("live")) - { - objAuthClaims.AuthenticationType = "Microsoft"; - } + objAuthClaims.auth_time = colClaims.FirstOrDefault( + c => c.Type == "auth_time")?.Value; - // Twitter login - if (objAuthClaims.IdentityProvider.ToLower().Contains("twitter")) - { - objAuthClaims.AuthenticationType = "Twitter"; - } + objAuthClaims.DisplayName = colClaims.FirstOrDefault( + c => c.Type == "name")?.Value; - // Azure Active Directory login - // But this will only work if Azure B2C Custom Policy is configured - // to pass the idp_access_token - // See \!AzureB2CConfig\TrustFrameworkExtensions.xml - // for an example that does that - if (objAuthClaims.idp_access_token != null) - { - objAuthClaims.AuthenticationType = "Azure Active Directory"; + objAuthClaims.idp_access_token = colClaims.FirstOrDefault( + c => c.Type == "idp_access_token")?.Value; - try + // Google login + if (objAuthClaims.IdentityProvider.ToLower().Contains("google")) { - var token = new System.IdentityModel.Tokens.Jwt.JwtSecurityToken(objAuthClaims.idp_access_token); - objAuthClaims.EmailAddress = token.Claims.FirstOrDefault(c => c.Type == "upn")?.Value; + objAuthClaims.AuthenticationType = "Google"; } - catch (System.Exception) + + // Microsoft account login + if (objAuthClaims.IdentityProvider.ToLower().Contains("live")) { - // Could not decode - do nothing + objAuthClaims.AuthenticationType = "Microsoft"; } - } - - var request = ctxt.HttpContext.Request; - var host = request.Host.ToUriComponent(); - - // Insert into Database - var optionsBuilder = new DbContextOptionsBuilder(); - optionsBuilder.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")); - SimpleSurveyContext _context = new SimpleSurveyContext(optionsBuilder.Options); - - var ExistingUser = _context.Users - .Where(x => x.Objectidentifier == objAuthClaims.Objectidentifier) - .FirstOrDefault(); - if (ExistingUser == null) - { - // New User - - // Create User object - var objUser = new Users(); - - try + // Twitter login + if (objAuthClaims.IdentityProvider.ToLower().Contains("twitter")) { - objUser.Objectidentifier = objAuthClaims.Objectidentifier; - objUser.AuthenticationType = objAuthClaims.AuthenticationType; - objUser.IdentityProvider = objAuthClaims.IdentityProvider; - objUser.SigninMethod = objAuthClaims.AzureB2CFlow; - objUser.DisplayName = objAuthClaims.DisplayName; - objUser.Email = objAuthClaims.EmailAddress; - objUser.FirstName = objAuthClaims.FirstName; - objUser.LastName = objAuthClaims.LastName; - objUser.LastAuthTime = Convert.ToInt32(objAuthClaims.auth_time); - objUser.LastidpAccessToken = objAuthClaims.idp_access_token; - objUser.LastIpaddress = host; - objUser.CreatedDate = DateTime.Now; - - _context.Users.Add(objUser); - _context.SaveChanges(); - - // Write to Log - var objLogs = new Logs(); - - objLogs.LogType = "Login"; - objLogs.LogDate = DateTime.Now; - objLogs.LogDetail = "New User"; - objLogs.LogUserId = objUser.Id; - objLogs.LogIpaddress = host; - - _context.Logs.Add(objLogs); - _context.SaveChanges(); + objAuthClaims.AuthenticationType = "Twitter"; } - catch (Exception ex) + + // Azure Active Directory login + // But this will only work if Azure B2C Custom Policy is configured + // to pass the idp_access_token + // See \!AzureB2CConfig\TrustFrameworkExtensions.xml + // for an example that does that + if (objAuthClaims.idp_access_token != null) { - // Write to Log - var objLogs = new Logs(); + objAuthClaims.AuthenticationType = "Azure Active Directory"; + + try + { + var token = new System.IdentityModel.Tokens.Jwt.JwtSecurityToken(objAuthClaims.idp_access_token); + objAuthClaims.EmailAddress = token.Claims.FirstOrDefault(c => c.Type == "upn")?.Value; + } + catch (System.Exception) + { + // Could not decode - do nothing + } + } - objLogs.LogType = "Login Error - New User"; - objLogs.LogDate = DateTime.Now; - objLogs.LogDetail = String.Format($"User: {objUser.DisplayName} Objectidentifier: {objUser.Objectidentifier} Message: {ex.GetBaseException().Message}"); - objLogs.LogIpaddress = host; + var request = ctxt.HttpContext.Request; + var host = request.Host.ToUriComponent(); - _context.Logs.Add(objLogs); - _context.SaveChanges(); - } - } - else - { - // Update Existing User + // Insert into Database + var optionsBuilder = new DbContextOptionsBuilder(); + optionsBuilder.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")); + SimpleSurveyContext _context = new SimpleSurveyContext(optionsBuilder.Options); + + var ExistingUser = _context.Users + .Where(x => x.Objectidentifier == objAuthClaims.Objectidentifier) + .FirstOrDefault(); - try + if (ExistingUser == null) { - ExistingUser.AuthenticationType = objAuthClaims.AuthenticationType; - ExistingUser.IdentityProvider = objAuthClaims.IdentityProvider; - ExistingUser.SigninMethod = objAuthClaims.AzureB2CFlow; - ExistingUser.DisplayName = objAuthClaims.DisplayName; - ExistingUser.Email = objAuthClaims.EmailAddress; - ExistingUser.FirstName = objAuthClaims.FirstName; - ExistingUser.LastName = objAuthClaims.LastName; - ExistingUser.LastAuthTime = Convert.ToInt32(objAuthClaims.auth_time); - ExistingUser.LastidpAccessToken = objAuthClaims.idp_access_token; - ExistingUser.LastIpaddress = host; - ExistingUser.UpdatedDate = DateTime.Now; - - _context.SaveChanges(); - - // Write to Log - - var objLogs = new Logs(); - - objLogs.LogType = "Login"; - objLogs.LogDate = DateTime.Now; - objLogs.LogDetail = "Existing User"; - objLogs.LogUserId = ExistingUser.Id; - objLogs.LogIpaddress = host; - - _context.Logs.Add(objLogs); - _context.SaveChanges(); + // New User + + // Create User object + var objUser = new Users(); + + try + { + objUser.Objectidentifier = objAuthClaims.Objectidentifier; + objUser.AuthenticationType = objAuthClaims.AuthenticationType; + objUser.IdentityProvider = objAuthClaims.IdentityProvider; + objUser.SigninMethod = objAuthClaims.AzureB2CFlow; + objUser.DisplayName = objAuthClaims.DisplayName; + objUser.Email = objAuthClaims.EmailAddress; + objUser.FirstName = objAuthClaims.FirstName; + objUser.LastName = objAuthClaims.LastName; + objUser.LastAuthTime = Convert.ToInt32(objAuthClaims.auth_time); + objUser.LastidpAccessToken = objAuthClaims.idp_access_token; + objUser.LastIpaddress = host; + objUser.CreatedDate = DateTime.Now; + + _context.Users.Add(objUser); + _context.SaveChanges(); + + // Write to Log + var objLogs = new Logs(); + + objLogs.LogType = "Login"; + objLogs.LogDate = DateTime.Now; + objLogs.LogDetail = "New User"; + objLogs.LogUserId = objUser.Id; + objLogs.LogIpaddress = host; + + _context.Logs.Add(objLogs); + _context.SaveChanges(); + } + catch (Exception ex) + { + // Write to Log + var objLogs = new Logs(); + + objLogs.LogType = "Login Error - New User"; + objLogs.LogDate = DateTime.Now; + objLogs.LogDetail = String.Format($"User: {objUser.DisplayName} Objectidentifier: {objUser.Objectidentifier} Message: {ex.GetBaseException().Message}"); + objLogs.LogIpaddress = host; + + _context.Logs.Add(objLogs); + _context.SaveChanges(); + } } - catch (Exception ex) + else { - // Write to Log - var objLogs = new Logs(); - - objLogs.LogType = "Login Error - Existing User"; - objLogs.LogDate = DateTime.Now; - objLogs.LogUserId = ExistingUser.Id; - objLogs.LogDetail = ex.GetBaseException().Message; - objLogs.LogIpaddress = host; - - _context.Logs.Add(objLogs); - _context.SaveChanges(); + // Update Existing User + + try + { + ExistingUser.AuthenticationType = objAuthClaims.AuthenticationType; + ExistingUser.IdentityProvider = objAuthClaims.IdentityProvider; + ExistingUser.SigninMethod = objAuthClaims.AzureB2CFlow; + ExistingUser.DisplayName = objAuthClaims.DisplayName; + ExistingUser.Email = objAuthClaims.EmailAddress; + ExistingUser.FirstName = objAuthClaims.FirstName; + ExistingUser.LastName = objAuthClaims.LastName; + ExistingUser.LastAuthTime = Convert.ToInt32(objAuthClaims.auth_time); + ExistingUser.LastidpAccessToken = objAuthClaims.idp_access_token; + ExistingUser.LastIpaddress = host; + ExistingUser.UpdatedDate = DateTime.Now; + + _context.SaveChanges(); + + // Write to Log + + var objLogs = new Logs(); + + objLogs.LogType = "Login"; + objLogs.LogDate = DateTime.Now; + objLogs.LogDetail = "Existing User"; + objLogs.LogUserId = ExistingUser.Id; + objLogs.LogIpaddress = host; + + _context.Logs.Add(objLogs); + _context.SaveChanges(); + } + catch (Exception ex) + { + // Write to Log + var objLogs = new Logs(); + + objLogs.LogType = "Login Error - Existing User"; + objLogs.LogDate = DateTime.Now; + objLogs.LogUserId = ExistingUser.Id; + objLogs.LogDetail = ex.GetBaseException().Message; + objLogs.LogIpaddress = host; + + _context.Logs.Add(objLogs); + _context.SaveChanges(); + } } } + await Task.Yield(); + }, + }; + }); - } - - await Task.Yield(); - }, - }; - }); + services.AddControllersWithViews().AddMicrosoftIdentityUI(); services.AddRazorPages(); services.AddServerSideBlazor();