From 0c90e1989502c9a50c60e223984e9df6ab1d389f Mon Sep 17 00:00:00 2001 From: morbalint Date: Wed, 27 Dec 2023 16:30:16 +0100 Subject: [PATCH] add Google login --- .../Pages/Account/ExternalLogin.cshtml.cs | 44 ++++++++++++++----- Kemkas.Web/Kemkas.Web.csproj | 1 + Kemkas.Web/Program.cs | 8 +++- Kemkas.Web/nginx.conf | 6 +++ Kemkas.Web/packages.lock.json | 6 +++ 5 files changed, 53 insertions(+), 12 deletions(-) diff --git a/Kemkas.Web/Areas/Identity/Pages/Account/ExternalLogin.cshtml.cs b/Kemkas.Web/Areas/Identity/Pages/Account/ExternalLogin.cshtml.cs index 5b4931f..e312d95 100644 --- a/Kemkas.Web/Areas/Identity/Pages/Account/ExternalLogin.cshtml.cs +++ b/Kemkas.Web/Areas/Identity/Pages/Account/ExternalLogin.cshtml.cs @@ -123,20 +123,42 @@ namespace Kemkas.Web.Areas.Identity.Pages.Account { return RedirectToPage("./Lockout"); } - else + + // If the user does not have an account, and no email claim, then ask the user to create an account. + ReturnUrl = returnUrl; + ProviderDisplayName = info.ProviderDisplayName; + if (!info.Principal.HasClaim(c => c.Type == ClaimTypes.Email)) { - // If the user does not have an account, then ask the user to create an account. - ReturnUrl = returnUrl; - ProviderDisplayName = info.ProviderDisplayName; - if (info.Principal.HasClaim(c => c.Type == ClaimTypes.Email)) - { - Input = new InputModel - { - Email = info.Principal.FindFirstValue(ClaimTypes.Email) - }; - } return Page(); } + + // User doesn't have account but external provider has email claim. => Register with claimed email. + Input = new InputModel + { + Email = info.Principal.FindFirstValue(ClaimTypes.Email) + }; + var user = CreateUser(); + await _userStore.SetUserNameAsync(user, Input.Email, CancellationToken.None); + await _emailStore.SetEmailAsync(user, Input.Email, CancellationToken.None); + var registrationResult = await _userManager.CreateAsync(user); + if (registrationResult.Succeeded) + { + registrationResult = await _userManager.AddLoginAsync(user, info); + if (registrationResult.Succeeded) + { + _logger.LogInformation("User created an account using {Name} provider.", info.LoginProvider); + var code = await _userManager.GenerateEmailConfirmationTokenAsync(user); + await _userManager.ConfirmEmailAsync(user, code); + await _signInManager.SignInAsync(user, isPersistent: false, info.LoginProvider); + return LocalRedirect(returnUrl); + } + } + foreach (var error in registrationResult.Errors) + { + ModelState.AddModelError(string.Empty, error.Description); + } + + return Page(); } public async Task OnPostConfirmationAsync(string returnUrl = null) diff --git a/Kemkas.Web/Kemkas.Web.csproj b/Kemkas.Web/Kemkas.Web.csproj index 80ce963..89d50d7 100644 --- a/Kemkas.Web/Kemkas.Web.csproj +++ b/Kemkas.Web/Kemkas.Web.csproj @@ -17,6 +17,7 @@ + diff --git a/Kemkas.Web/Program.cs b/Kemkas.Web/Program.cs index 61b09df..8822826 100644 --- a/Kemkas.Web/Program.cs +++ b/Kemkas.Web/Program.cs @@ -33,7 +33,13 @@ builder.Services.AddSingleton(); builder.Services.AddDefaultIdentity(options => options.SignIn.RequireConfirmedAccount = true) .AddEntityFrameworkStores(); -builder.Services.AddAuthentication(); +builder.Services.AddAuthentication() + .AddGoogle(options => + { + var googleAuthNSection = builder.Configuration.GetSection("Authentication:Google"); + options.ClientId = googleAuthNSection["ClientId"]; + options.ClientSecret = googleAuthNSection["ClientSecret"]; + }); builder.Services.AddControllersWithViews().AddJsonOptions(options => { diff --git a/Kemkas.Web/nginx.conf b/Kemkas.Web/nginx.conf index e31f974..c45c4e2 100644 --- a/Kemkas.Web/nginx.conf +++ b/Kemkas.Web/nginx.conf @@ -70,7 +70,13 @@ http { proxy_set_header X-Forwarded-Proto "$scheme"; proxy_set_header X-Forwarded-Host "$http_host"; proxy_pass https://backend; + } + location /signin-google/ { proxy_pass_request_headers on; + proxy_set_header X-Forwarded-For "$proxy_add_x_forwarded_for"; + proxy_set_header X-Forwarded-Proto "$scheme"; + proxy_set_header X-Forwarded-Host "$http_host"; + proxy_pass https://backend; } location /lib/ { diff --git a/Kemkas.Web/packages.lock.json b/Kemkas.Web/packages.lock.json index 810fae6..5c2d8c6 100644 --- a/Kemkas.Web/packages.lock.json +++ b/Kemkas.Web/packages.lock.json @@ -2,6 +2,12 @@ "version": 1, "dependencies": { "net8.0": { + "Microsoft.AspNetCore.Authentication.Google": { + "type": "Direct", + "requested": "[8.0.0, )", + "resolved": "8.0.0", + "contentHash": "dPE/IiHhBqnJ7WrD72T20+DcHGCaR9F4RmIFap83W1Ts/ze5gBVe4Ii02qJdJzkUniQy5S/v42zpRIgJTPzPqQ==" + }, "Microsoft.AspNetCore.DataProtection.EntityFrameworkCore": { "type": "Direct", "requested": "[8.0.0, )",