diff --git a/apps/public-web/src/EShopOnAbp.PublicWeb/EShopOnAbpPublicWebModule.cs b/apps/public-web/src/EShopOnAbp.PublicWeb/EShopOnAbpPublicWebModule.cs index b0078b9b..12440571 100644 --- a/apps/public-web/src/EShopOnAbp.PublicWeb/EShopOnAbpPublicWebModule.cs +++ b/apps/public-web/src/EShopOnAbp.PublicWeb/EShopOnAbpPublicWebModule.cs @@ -22,8 +22,14 @@ using Microsoft.IdentityModel.Protocols.OpenIdConnect; using Polly; using StackExchange.Redis; using System; +using System.Collections.Generic; +using System.Linq; using System.Net.Http.Headers; +using System.Security.Claims; using Microsoft.AspNetCore.Authentication.OAuth.Claims; +using Microsoft.AspNetCore.Http; +using Microsoft.Extensions.Logging; +using Microsoft.IdentityModel.Tokens; using Volo.Abp; using Volo.Abp.Account; using Volo.Abp.AspNetCore.Authentication.OpenIdConnect; @@ -38,6 +44,7 @@ using Volo.Abp.AspNetCore.SignalR; using Volo.Abp.AutoMapper; using Volo.Abp.Caching; using Volo.Abp.Caching.StackExchangeRedis; +using Volo.Abp.EventBus.Distributed; using Volo.Abp.EventBus.RabbitMq; using Volo.Abp.Http.Client; using Volo.Abp.Http.Client.IdentityModel.Web; @@ -167,12 +174,23 @@ public class EShopOnAbpPublicWebModule : AbpModule // options.NonceCookie.SameSite = SameSiteMode.Unspecified; // options.CorrelationCookie.SameSite = SameSiteMode.Unspecified; // - // options.TokenValidationParameters = new TokenValidationParameters - // { - // NameClaimType = "name", - // RoleClaimType = ClaimTypes.Role, - // ValidateIssuer = true - // }; + options.TokenValidationParameters = new TokenValidationParameters + { + NameClaimType = "name", + RoleClaimType = ClaimTypes.Role, + ValidateIssuer = true + }; + + options.Events.OnAuthorizationCodeReceived = async (authContext) => + { + var userLoggedInEto = CreateUserLoggedInEto(authContext.Principal, authContext.HttpContext); + if (userLoggedInEto != null) + { + var eventBus = + authContext.HttpContext.RequestServices.GetRequiredService(); + await eventBus.PublishAsync(userLoggedInEto); + } + }; if (AbpClaimTypes.UserName != "preferred_username") { @@ -181,6 +199,7 @@ public class EShopOnAbpPublicWebModule : AbpModule options.ClaimActions.RemoveDuplicate(AbpClaimTypes.UserName); } }); + if (Convert.ToBoolean(configuration["AuthServer:IsOnProd"])) { context.Services.Configure("oidc", options => @@ -248,33 +267,6 @@ public class EShopOnAbpPublicWebModule : AbpModule }); } - private void ConfigureBasketHttpClient(ServiceConfigurationContext context) - { - context.Services.AddStaticHttpClientProxies( - typeof(BasketServiceContractsModule).Assembly, - remoteServiceConfigurationName: BasketServiceConstants.RemoteServiceName - ); - - Configure(options => - { - options.FileSets.AddEmbedded(); - }); - } - - private void ConfigurePayment(IConfiguration configuration) - { - Configure(options => - { - options.PaymentSuccessfulCallbackUrl = - configuration["App:SelfUrl"].EnsureEndsWith('/') + "PaymentCompleted"; - }); - - Configure(options => - { - options.ConfigureIcon(PaymentMethodNames.PayPal, "fa-cc-paypal paypal"); - }); - } - public override void OnApplicationInitialization(ApplicationInitializationContext context) { var app = context.GetApplicationBuilder(); @@ -317,4 +309,66 @@ public class EShopOnAbpPublicWebModule : AbpModule // endpoints.MapMetrics(); }); } + + private void ConfigureBasketHttpClient(ServiceConfigurationContext context) + { + context.Services.AddStaticHttpClientProxies( + typeof(BasketServiceContractsModule).Assembly, + remoteServiceConfigurationName: BasketServiceConstants.RemoteServiceName + ); + + Configure(options => + { + options.FileSets.AddEmbedded(); + }); + } + + private void ConfigurePayment(IConfiguration configuration) + { + Configure(options => + { + options.PaymentSuccessfulCallbackUrl = + configuration["App:SelfUrl"].EnsureEndsWith('/') + "PaymentCompleted"; + }); + + Configure(options => + { + options.ConfigureIcon(PaymentMethodNames.PayPal, "fa-cc-paypal paypal"); + }); + } + + private UserLoggedInEto CreateUserLoggedInEto(ClaimsPrincipal principal, HttpContext httpContext) + { + var logger = httpContext.RequestServices.GetRequiredService>(); + + if (principal == null) + { + logger.LogWarning($"AuthorizationCode does not contain principal to create/update user!"); + return null; + } + + var claims = principal.Claims.ToList(); + + var userNameClaim = claims.FirstOrDefault(x => x.Type == "preferred_username"); + var emailClaim = claims.FirstOrDefault(x => x.Type == ClaimTypes.Email); + var isEmailVerified = claims.FirstOrDefault(x => x.Type == "email_verified")?.Value == "true"; + var phoneNumberClaim = claims.FirstOrDefault(x => x.Type == "phone"); + var userIdString = claims.First(t => t.Type == ClaimTypes.NameIdentifier).Value; + + if (!Guid.TryParse(userIdString, out Guid userId)) + { + logger.LogWarning( + $"Handling UserLoggedInEvent... User creation failed! {userIdString} can not be parsed!"); + return null; + } + + return new UserLoggedInEto + { + Id = userId, + Email = emailClaim?.Value, + UserName = userNameClaim?.Value, + Phone = phoneNumberClaim?.Value, + IsEmailVerified = isEmailVerified + }; + } } \ No newline at end of file diff --git a/apps/public-web/src/EShopOnAbp.PublicWeb/UserLoggedInEto.cs b/apps/public-web/src/EShopOnAbp.PublicWeb/UserLoggedInEto.cs new file mode 100644 index 00000000..f7ffa497 --- /dev/null +++ b/apps/public-web/src/EShopOnAbp.PublicWeb/UserLoggedInEto.cs @@ -0,0 +1,16 @@ +using System; +using Volo.Abp.Domain.Entities.Events.Distributed; +using Volo.Abp.EventBus; + +namespace EShopOnAbp.PublicWeb; + +[EventName("EShopOnAbp.Identity.UserLoggedIn")] +[Serializable] +public class UserLoggedInEto : EtoBase +{ + public Guid Id { get; set; } + public string Email { get; set; } + public string Phone { get; set; } + public string UserName { get; set; } + public bool IsEmailVerified { get; set; } +} \ No newline at end of file