From 17e18302db19b1905b179f7fa18e0cbf800a5f7a Mon Sep 17 00:00:00 2001 From: support Date: Sun, 18 Oct 2026 12:45:53 +0200 Subject: [PATCH 1/2] Move the HTTP authentication services to Web.Common CookieAuthenticationService and ApiAuthenticationService were the last Grand.Business.* classes reading HttpContext. They do nothing but HTTP work (the customer cookie, SignInAsync/SignOutAsync, the Authorization header, AuthenticateAsync for the JWT schemes), so no explicit argument could replace the ambient read: they belong in the web layer. IGrandAuthenticationService stays in Business.Core, because ExternalAuthenticationService and plugins use it; only its cookie implementation and DI registration move. IApiAuthenticationService and ICookieOptionsFactory have no users outside Web, so the interfaces move with their implementations, which also takes Microsoft.AspNetCore.Http CookieOptions out of the Business.Core contracts. Everything the moved classes depend on is a Business.Core contract, so Web.Common does not gain a dependency on a Business implementation. The JwtBearerAuthenticationService tests that lived in ApiAuthenticationServiceTests stay in Grand.Business.Authentication.Tests as JwtBearerAuthenticationServiceTests. --- .../Startup/StartupApplication.cs | 3 - ...=> JwtBearerAuthenticationServiceTests.cs} | 119 +-------------- .../RequestCustomerResolversTests.cs | 1 + .../ApiAuthenticationServiceTests.cs | 135 ++++++++++++++++++ .../CookieAuthenticationServiceTests.cs | 6 +- .../CookieOptionsFactoryTests.cs | 6 +- .../Security/Oidc/OidcWorkContextTests.cs | 1 + .../WorkContextSetterRequestResolverTests.cs | 1 + .../Infrastructure/AdminThemeContext.cs | 4 +- .../ApiUserCustomerResolver.cs | 2 +- .../ApiAuthenticationService.cs | 5 +- .../CookieAuthenticationService.cs | 2 +- .../Authentication}/CookieOptionsFactory.cs | 5 +- .../IApiAuthenticationService.cs | 2 +- .../Authentication/ICookieOptionsFactory.cs | 2 +- .../Startup/StartupApplication.cs | 5 + .../Grand.Web.Common/Themes/ThemeContext.cs | 4 +- .../Themes/ThemeContextBase.cs | 2 +- .../Infrastructure/StoreThemeContext.cs | 4 +- .../Grand.Web/Controllers/CommonController.cs | 4 +- 20 files changed, 169 insertions(+), 144 deletions(-) rename src/Tests/Grand.Business.Authentication.Tests/Services/{ApiAuthenticationServiceTests.cs => JwtBearerAuthenticationServiceTests.cs} (61%) create mode 100644 src/Tests/Grand.Web.Common.Tests/Security/Authentication/ApiAuthenticationServiceTests.cs rename src/Tests/{Grand.Business.Authentication.Tests/Services => Grand.Web.Common.Tests/Security/Authentication}/CookieAuthenticationServiceTests.cs (99%) rename src/Tests/{Grand.Business.Authentication.Tests/Services => Grand.Web.Common.Tests/Security/Authentication}/CookieOptionsFactoryTests.cs (94%) rename src/{Business/Grand.Business.Authentication/Services => Web/Grand.Web.Common/Security/Authentication}/ApiAuthenticationService.cs (96%) rename src/{Business/Grand.Business.Authentication/Services => Web/Grand.Web.Common/Security/Authentication}/CookieAuthenticationService.cs (99%) rename src/{Business/Grand.Business.Authentication/Services => Web/Grand.Web.Common/Security/Authentication}/CookieOptionsFactory.cs (86%) rename src/{Business/Grand.Business.Core/Interfaces => Web/Grand.Web.Common/Security}/Authentication/IApiAuthenticationService.cs (80%) rename src/{Business/Grand.Business.Core/Interfaces => Web/Grand.Web.Common/Security}/Authentication/ICookieOptionsFactory.cs (90%) diff --git a/src/Business/Grand.Business.Authentication/Startup/StartupApplication.cs b/src/Business/Grand.Business.Authentication/Startup/StartupApplication.cs index cebea41ce4..1463a56385 100644 --- a/src/Business/Grand.Business.Authentication/Startup/StartupApplication.cs +++ b/src/Business/Grand.Business.Authentication/Startup/StartupApplication.cs @@ -17,9 +17,6 @@ public class StartupApplication : IStartupApplication { public void ConfigureServices(IServiceCollection services, IConfiguration configuration) { - services.AddScoped(); - services.AddScoped(); - services.AddScoped(); services.AddScoped(); services.AddScoped(); services.AddScoped(); diff --git a/src/Tests/Grand.Business.Authentication.Tests/Services/ApiAuthenticationServiceTests.cs b/src/Tests/Grand.Business.Authentication.Tests/Services/JwtBearerAuthenticationServiceTests.cs similarity index 61% rename from src/Tests/Grand.Business.Authentication.Tests/Services/ApiAuthenticationServiceTests.cs rename to src/Tests/Grand.Business.Authentication.Tests/Services/JwtBearerAuthenticationServiceTests.cs index ccb889e232..d3dfbb41fd 100644 --- a/src/Tests/Grand.Business.Authentication.Tests/Services/ApiAuthenticationServiceTests.cs +++ b/src/Tests/Grand.Business.Authentication.Tests/Services/JwtBearerAuthenticationServiceTests.cs @@ -1,15 +1,11 @@ using Grand.Business.Authentication.Services; using Grand.Business.Core.Interfaces.Authentication; -using Grand.Business.Core.Interfaces.Common.Directory; using Grand.Business.Core.Interfaces.Customers; using Grand.Domain.Customers; +using Grand.Infrastructure.Configuration; using Microsoft.AspNetCore.Authentication; using Microsoft.AspNetCore.Authentication.JwtBearer; using Microsoft.AspNetCore.Http; -using Microsoft.Extensions.DependencyInjection; -using Grand.Infrastructure.Configuration; -using Grand.SharedKernel.Attributes; -using Grand.SharedKernel.Extensions; using Microsoft.VisualStudio.TestTools.UnitTesting; using Moq; using System.Security.Claims; @@ -19,12 +15,9 @@ namespace Grand.Business.Authentication.Tests.Services; [TestClass] -public class ApiAuthenticationServiceTests +public class JwtBearerAuthenticationServiceTests { - private IApiAuthenticationService _authService; private Mock _customerService; - private Mock _groupService; - private Mock _httpContextAccessorMoc; private IJwtBearerAuthenticationService _jwtBearerAuthenticationService; private Mock _userApiServiceMock; private OidcLoginConfig _oidcLoginConfig; @@ -32,12 +25,8 @@ public class ApiAuthenticationServiceTests [TestInitialize] public void Init() { - _httpContextAccessorMoc = new Mock(); _customerService = new Mock(); _userApiServiceMock = new Mock(); - _groupService = new Mock(); - _authService = new ApiAuthenticationService(_customerService.Object, _groupService.Object, - _httpContextAccessorMoc.Object, new Mock().Object); _oidcLoginConfig = new OidcLoginConfig(); _jwtBearerAuthenticationService = new JwtBearerAuthenticationService(_customerService.Object, _userApiServiceMock.Object, _oidcLoginConfig); @@ -172,7 +161,6 @@ public async Task Valid_ActiveUserApi_ReturnTrue() Assert.IsTrue(result); } - [TestMethod] public async Task Valid_ProviderOnly_ActiveUserApi_ReturnFalse() { @@ -195,105 +183,4 @@ public async Task Valid_ProviderOnly_ActiveUserApi_ReturnFalse() Assert.AreEqual("Sign-in with API users is disabled: use access tokens from the identity provider", await _jwtBearerAuthenticationService.ErrorMessage()); } - - [TestMethod] - public async Task GetAuthenticatedCustomer_NullAuthHeader_GetNull() - { - var customer = new Customer { Email = "johny@gmail.com" }; - var httpContext = new Mock(); - var req = new Mock(); - req.Setup(c => c.Path).Returns(new PathString("/api/...")); - req.Setup(c => c.Headers).Returns(new HeaderDictionary()); - httpContext.Setup(c => c.Request).Returns(req.Object); - _httpContextAccessorMoc.Setup(c => c.HttpContext).Returns(httpContext.Object); - _customerService.Setup(c => c.GetCustomerBySystemName(It.IsAny())) - .Returns(() => Task.FromResult(customer)); - var result = await _authService.GetAuthenticatedCustomer(); - Assert.IsNull(result); - } - - private static HttpContext CreateHttpContext(Action configure, Endpoint endpoint = null) - { - var services = new ServiceCollection(); - services.AddLogging(); - var builder = services.AddAuthentication(); - configure?.Invoke(builder); - var context = new DefaultHttpContext { RequestServices = services.BuildServiceProvider() }; - context.Request.Headers["Authorization"] = "Bearer anything"; - if (endpoint != null) context.SetEndpoint(endpoint); - return context; - } - - private IApiAuthenticationService CreateService(HttpContext context) - { - _httpContextAccessorMoc.Setup(c => c.HttpContext).Returns(context); - return new ApiAuthenticationService(_customerService.Object, _groupService.Object, - _httpContextAccessorMoc.Object, - context.RequestServices.GetRequiredService()); - } - - [TestMethod] - public async Task GetAuthenticatedCustomer_BearerHeaderWithoutJwtScheme_ReturnsNull() - { - var context = CreateHttpContext(null); - var result = await CreateService(context).GetAuthenticatedCustomer(); - Assert.IsNull(result); - } - - [TestMethod] - public async Task GetAuthenticatedCustomer_FrontApiEndpointWithoutFrontScheme_ReturnsNull() - { - var endpoint = new Endpoint(null, - new EndpointMetadataCollection(new ApiGroupAttribute(ApiConstants.ApiGroupNameV2)), "front"); - var context = CreateHttpContext(null, endpoint); - var result = await CreateService(context).GetAuthenticatedCustomer(); - Assert.IsNull(result); - } - - [TestMethod] - public async Task GetAuthenticatedCustomer_JwtSchemeRegisteredAndSucceeds_ReturnsCustomer() - { - var customer = new Customer { Id = "c1", Active = true }; - _customerService.Setup(c => c.GetCustomerById("c1")).ReturnsAsync(customer); - _groupService.Setup(g => g.IsRegistered(customer)).ReturnsAsync(true); - var context = CreateHttpContext(b => b.AddScheme( - JwtBearerDefaults.AuthenticationScheme, null)); - var result = await CreateService(context).GetAuthenticatedCustomer(); - Assert.AreSame(customer, result); - } - - [TestMethod] - public async Task GetAuthenticatedCustomer_BearerForwardedToOidc_ReturnsNull() - { - //a provider token the Bearer scheme forwards to the Oidc scheme: its CustomerId claim was not issued by GrandNode - var customer = new Customer { Id = "c1", Active = true }; - _customerService.Setup(c => c.GetCustomerById("c1")).ReturnsAsync(customer); - _groupService.Setup(g => g.IsRegistered(customer)).ReturnsAsync(true); - var context = CreateHttpContext(b => b - .AddScheme(JwtBearerDefaults.AuthenticationScheme, - o => o.ForwardDefault = "Oidc") - .AddScheme("Oidc", null)); - - var result = await CreateService(context).GetAuthenticatedCustomer(); - - Assert.IsNull(result); - _customerService.Verify(c => c.GetCustomerById(It.IsAny()), Times.Never); - _customerService.Verify(c => c.GetCustomerByEmail(It.IsAny()), Times.Never); - } - - private class OkHandler : AuthenticationHandler - { - public OkHandler(Microsoft.Extensions.Options.IOptionsMonitor options, - Microsoft.Extensions.Logging.ILoggerFactory logger, System.Text.Encodings.Web.UrlEncoder encoder) - : base(options, logger, encoder) - { - } - - protected override Task HandleAuthenticateAsync() - { - var identity = new ClaimsIdentity(new[] { new Claim("CustomerId", "c1") }, "test"); - return Task.FromResult(AuthenticateResult.Success( - new AuthenticationTicket(new ClaimsPrincipal(identity), Scheme.Name))); - } - } -} \ No newline at end of file +} diff --git a/src/Tests/Grand.Web.Common.Tests/RequestCustomerResolversTests.cs b/src/Tests/Grand.Web.Common.Tests/RequestCustomerResolversTests.cs index bd2683160a..dce7834e54 100644 --- a/src/Tests/Grand.Web.Common.Tests/RequestCustomerResolversTests.cs +++ b/src/Tests/Grand.Web.Common.Tests/RequestCustomerResolversTests.cs @@ -3,6 +3,7 @@ using Grand.Business.Core.Interfaces.Customers; using Grand.Domain.Customers; using Grand.Web.Common.RequestCustomerResolvers; +using Grand.Web.Common.Security.Authentication; using Grand.Web.Common.UserAgent; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Http; diff --git a/src/Tests/Grand.Web.Common.Tests/Security/Authentication/ApiAuthenticationServiceTests.cs b/src/Tests/Grand.Web.Common.Tests/Security/Authentication/ApiAuthenticationServiceTests.cs new file mode 100644 index 0000000000..6bdac8dc1f --- /dev/null +++ b/src/Tests/Grand.Web.Common.Tests/Security/Authentication/ApiAuthenticationServiceTests.cs @@ -0,0 +1,135 @@ +using Grand.Business.Core.Interfaces.Common.Directory; +using Grand.Business.Core.Interfaces.Customers; +using Grand.Domain.Customers; +using Grand.SharedKernel.Attributes; +using Grand.SharedKernel.Extensions; +using Grand.Web.Common.Security.Authentication; +using Microsoft.AspNetCore.Authentication; +using Microsoft.AspNetCore.Authentication.JwtBearer; +using Microsoft.AspNetCore.Http; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using Moq; +using System.Security.Claims; + +namespace Grand.Web.Common.Tests.Security.Authentication; + +[TestClass] +public class ApiAuthenticationServiceTests +{ + private IApiAuthenticationService _authService; + private Mock _customerService; + private Mock _groupService; + private Mock _httpContextAccessorMoc; + + [TestInitialize] + public void Init() + { + _httpContextAccessorMoc = new Mock(); + _customerService = new Mock(); + _groupService = new Mock(); + _authService = new ApiAuthenticationService(_customerService.Object, _groupService.Object, + _httpContextAccessorMoc.Object, new Mock().Object); + } + + [TestMethod] + public async Task GetAuthenticatedCustomer_NullAuthHeader_GetNull() + { + var customer = new Customer { Email = "johny@gmail.com" }; + var httpContext = new Mock(); + var req = new Mock(); + req.Setup(c => c.Path).Returns(new PathString("/api/...")); + req.Setup(c => c.Headers).Returns(new HeaderDictionary()); + httpContext.Setup(c => c.Request).Returns(req.Object); + _httpContextAccessorMoc.Setup(c => c.HttpContext).Returns(httpContext.Object); + _customerService.Setup(c => c.GetCustomerBySystemName(It.IsAny())) + .Returns(() => Task.FromResult(customer)); + var result = await _authService.GetAuthenticatedCustomer(); + Assert.IsNull(result); + } + + private static HttpContext CreateHttpContext(Action configure, Endpoint endpoint = null) + { + var services = new ServiceCollection(); + services.AddLogging(); + var builder = services.AddAuthentication(); + configure?.Invoke(builder); + var context = new DefaultHttpContext { RequestServices = services.BuildServiceProvider() }; + context.Request.Headers["Authorization"] = "Bearer anything"; + if (endpoint != null) context.SetEndpoint(endpoint); + return context; + } + + private IApiAuthenticationService CreateService(HttpContext context) + { + _httpContextAccessorMoc.Setup(c => c.HttpContext).Returns(context); + return new ApiAuthenticationService(_customerService.Object, _groupService.Object, + _httpContextAccessorMoc.Object, + context.RequestServices.GetRequiredService()); + } + + [TestMethod] + public async Task GetAuthenticatedCustomer_BearerHeaderWithoutJwtScheme_ReturnsNull() + { + var context = CreateHttpContext(null); + var result = await CreateService(context).GetAuthenticatedCustomer(); + Assert.IsNull(result); + } + + [TestMethod] + public async Task GetAuthenticatedCustomer_FrontApiEndpointWithoutFrontScheme_ReturnsNull() + { + var endpoint = new Endpoint(null, + new EndpointMetadataCollection(new ApiGroupAttribute(ApiConstants.ApiGroupNameV2)), "front"); + var context = CreateHttpContext(null, endpoint); + var result = await CreateService(context).GetAuthenticatedCustomer(); + Assert.IsNull(result); + } + + [TestMethod] + public async Task GetAuthenticatedCustomer_JwtSchemeRegisteredAndSucceeds_ReturnsCustomer() + { + var customer = new Customer { Id = "c1", Active = true }; + _customerService.Setup(c => c.GetCustomerById("c1")).ReturnsAsync(customer); + _groupService.Setup(g => g.IsRegistered(customer)).ReturnsAsync(true); + var context = CreateHttpContext(b => b.AddScheme( + JwtBearerDefaults.AuthenticationScheme, null)); + var result = await CreateService(context).GetAuthenticatedCustomer(); + Assert.AreSame(customer, result); + } + + [TestMethod] + public async Task GetAuthenticatedCustomer_BearerForwardedToOidc_ReturnsNull() + { + //a provider token the Bearer scheme forwards to the Oidc scheme: its CustomerId claim was not issued by GrandNode + var customer = new Customer { Id = "c1", Active = true }; + _customerService.Setup(c => c.GetCustomerById("c1")).ReturnsAsync(customer); + _groupService.Setup(g => g.IsRegistered(customer)).ReturnsAsync(true); + var context = CreateHttpContext(b => b + .AddScheme(JwtBearerDefaults.AuthenticationScheme, + o => o.ForwardDefault = "Oidc") + .AddScheme("Oidc", null)); + + var result = await CreateService(context).GetAuthenticatedCustomer(); + + Assert.IsNull(result); + _customerService.Verify(c => c.GetCustomerById(It.IsAny()), Times.Never); + _customerService.Verify(c => c.GetCustomerByEmail(It.IsAny()), Times.Never); + } + + private class OkHandler : AuthenticationHandler + { + public OkHandler(Microsoft.Extensions.Options.IOptionsMonitor options, + Microsoft.Extensions.Logging.ILoggerFactory logger, System.Text.Encodings.Web.UrlEncoder encoder) + : base(options, logger, encoder) + { + } + + protected override Task HandleAuthenticateAsync() + { + var identity = new ClaimsIdentity(new[] { new Claim("CustomerId", "c1") }, "test"); + return Task.FromResult(AuthenticateResult.Success( + new AuthenticationTicket(new ClaimsPrincipal(identity), Scheme.Name))); + } + } +} \ No newline at end of file diff --git a/src/Tests/Grand.Business.Authentication.Tests/Services/CookieAuthenticationServiceTests.cs b/src/Tests/Grand.Web.Common.Tests/Security/Authentication/CookieAuthenticationServiceTests.cs similarity index 99% rename from src/Tests/Grand.Business.Authentication.Tests/Services/CookieAuthenticationServiceTests.cs rename to src/Tests/Grand.Web.Common.Tests/Security/Authentication/CookieAuthenticationServiceTests.cs index f264057997..3374f47187 100644 --- a/src/Tests/Grand.Business.Authentication.Tests/Services/CookieAuthenticationServiceTests.cs +++ b/src/Tests/Grand.Web.Common.Tests/Security/Authentication/CookieAuthenticationServiceTests.cs @@ -1,11 +1,11 @@ -using Grand.Business.Authentication.Services; -using Grand.Business.Core.Interfaces.Authentication; +using Grand.Business.Core.Interfaces.Authentication; using Grand.Business.Core.Interfaces.Common.Directory; using Grand.Business.Core.Interfaces.Customers; using Grand.Business.Core.Utilities.Authentication; using Grand.Domain.Common; using Grand.Domain.Customers; using Grand.Infrastructure.Configuration; +using Grand.Web.Common.Security.Authentication; using Microsoft.AspNetCore.Authentication; using Microsoft.AspNetCore.Http; using Microsoft.Extensions.Logging.Abstractions; @@ -13,7 +13,7 @@ using Moq; using System.Security.Claims; -namespace Grand.Business.Authentication.Tests.Services; +namespace Grand.Web.Common.Tests.Security.Authentication; [TestClass] public class CookieAuthenticationServiceTests diff --git a/src/Tests/Grand.Business.Authentication.Tests/Services/CookieOptionsFactoryTests.cs b/src/Tests/Grand.Web.Common.Tests/Security/Authentication/CookieOptionsFactoryTests.cs similarity index 94% rename from src/Tests/Grand.Business.Authentication.Tests/Services/CookieOptionsFactoryTests.cs rename to src/Tests/Grand.Web.Common.Tests/Security/Authentication/CookieOptionsFactoryTests.cs index 76e19337d6..b31a9271f9 100644 --- a/src/Tests/Grand.Business.Authentication.Tests/Services/CookieOptionsFactoryTests.cs +++ b/src/Tests/Grand.Web.Common.Tests/Security/Authentication/CookieOptionsFactoryTests.cs @@ -1,9 +1,9 @@ -using Grand.Business.Authentication.Services; -using Grand.Infrastructure.Configuration; +using Grand.Infrastructure.Configuration; +using Grand.Web.Common.Security.Authentication; using Microsoft.AspNetCore.Http; using Microsoft.VisualStudio.TestTools.UnitTesting; -namespace Grand.Business.Authentication.Tests.Services; +namespace Grand.Web.Common.Tests.Security.Authentication; [TestClass] public class CookieOptionsFactoryTests diff --git a/src/Tests/Grand.Web.Common.Tests/Security/Oidc/OidcWorkContextTests.cs b/src/Tests/Grand.Web.Common.Tests/Security/Oidc/OidcWorkContextTests.cs index 1257bec63a..7d3bc8fe5a 100644 --- a/src/Tests/Grand.Web.Common.Tests/Security/Oidc/OidcWorkContextTests.cs +++ b/src/Tests/Grand.Web.Common.Tests/Security/Oidc/OidcWorkContextTests.cs @@ -10,6 +10,7 @@ using Grand.Domain.Tax; using Grand.Infrastructure.Configuration; using Grand.Web.Common.RequestCustomerResolvers; +using Grand.Web.Common.Security.Authentication; using Grand.Web.Common.Security.Oidc; using Grand.Web.Common.UserAgent; using Microsoft.AspNetCore.Authentication; diff --git a/src/Tests/Grand.Web.Common.Tests/WorkContextSetterRequestResolverTests.cs b/src/Tests/Grand.Web.Common.Tests/WorkContextSetterRequestResolverTests.cs index 42297678e8..ca95480220 100644 --- a/src/Tests/Grand.Web.Common.Tests/WorkContextSetterRequestResolverTests.cs +++ b/src/Tests/Grand.Web.Common.Tests/WorkContextSetterRequestResolverTests.cs @@ -11,6 +11,7 @@ using Grand.Domain.Tax; using Grand.Infrastructure.Configuration; using Grand.Web.Common.RequestCustomerResolvers; +using Grand.Web.Common.Security.Authentication; using Grand.Web.Common.UserAgent; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Http; diff --git a/src/Web/Grand.Web.Admin/Infrastructure/AdminThemeContext.cs b/src/Web/Grand.Web.Admin/Infrastructure/AdminThemeContext.cs index 8a9bb5d129..1b02c3096a 100644 --- a/src/Web/Grand.Web.Admin/Infrastructure/AdminThemeContext.cs +++ b/src/Web/Grand.Web.Admin/Infrastructure/AdminThemeContext.cs @@ -1,6 +1,6 @@ -using Grand.Business.Core.Interfaces.Authentication; -using Grand.Domain.Stores; +using Grand.Domain.Stores; using Grand.Web.Admin.Extensions; +using Grand.Web.Common.Security.Authentication; using Grand.Web.Common.Themes; namespace Grand.Web.Admin.Infrastructure; diff --git a/src/Web/Grand.Web.Common/RequestCustomerResolvers/ApiUserCustomerResolver.cs b/src/Web/Grand.Web.Common/RequestCustomerResolvers/ApiUserCustomerResolver.cs index 48c580d4ed..55d1c995a4 100644 --- a/src/Web/Grand.Web.Common/RequestCustomerResolvers/ApiUserCustomerResolver.cs +++ b/src/Web/Grand.Web.Common/RequestCustomerResolvers/ApiUserCustomerResolver.cs @@ -1,6 +1,6 @@ -using Grand.Business.Core.Interfaces.Authentication; using Grand.Business.Core.Interfaces.Customers; using Grand.Domain.Customers; +using Grand.Web.Common.Security.Authentication; using Microsoft.AspNetCore.Http; using Microsoft.Net.Http.Headers; diff --git a/src/Business/Grand.Business.Authentication/Services/ApiAuthenticationService.cs b/src/Web/Grand.Web.Common/Security/Authentication/ApiAuthenticationService.cs similarity index 96% rename from src/Business/Grand.Business.Authentication/Services/ApiAuthenticationService.cs rename to src/Web/Grand.Web.Common/Security/Authentication/ApiAuthenticationService.cs index f87a24d45a..eea79cfcc3 100644 --- a/src/Business/Grand.Business.Authentication/Services/ApiAuthenticationService.cs +++ b/src/Web/Grand.Web.Common/Security/Authentication/ApiAuthenticationService.cs @@ -1,5 +1,4 @@ -using Grand.Business.Core.Interfaces.Authentication; -using Grand.Business.Core.Interfaces.Common.Directory; +using Grand.Business.Core.Interfaces.Common.Directory; using Grand.Business.Core.Interfaces.Customers; using Grand.Domain.Customers; using Grand.Infrastructure.Configuration; @@ -11,7 +10,7 @@ using Microsoft.AspNetCore.Http; using Microsoft.Net.Http.Headers; -namespace Grand.Business.Authentication.Services; +namespace Grand.Web.Common.Security.Authentication; public class ApiAuthenticationService : IApiAuthenticationService { diff --git a/src/Business/Grand.Business.Authentication/Services/CookieAuthenticationService.cs b/src/Web/Grand.Web.Common/Security/Authentication/CookieAuthenticationService.cs similarity index 99% rename from src/Business/Grand.Business.Authentication/Services/CookieAuthenticationService.cs rename to src/Web/Grand.Web.Common/Security/Authentication/CookieAuthenticationService.cs index c9b1754708..dfbfd66de5 100644 --- a/src/Business/Grand.Business.Authentication/Services/CookieAuthenticationService.cs +++ b/src/Web/Grand.Web.Common/Security/Authentication/CookieAuthenticationService.cs @@ -10,7 +10,7 @@ using Microsoft.Extensions.Logging; using System.Security.Claims; -namespace Grand.Business.Authentication.Services; +namespace Grand.Web.Common.Security.Authentication; /// /// Represents service using cookie middleware for the authentication diff --git a/src/Business/Grand.Business.Authentication/Services/CookieOptionsFactory.cs b/src/Web/Grand.Web.Common/Security/Authentication/CookieOptionsFactory.cs similarity index 86% rename from src/Business/Grand.Business.Authentication/Services/CookieOptionsFactory.cs rename to src/Web/Grand.Web.Common/Security/Authentication/CookieOptionsFactory.cs index 459fca7248..80984f7a0b 100644 --- a/src/Business/Grand.Business.Authentication/Services/CookieOptionsFactory.cs +++ b/src/Web/Grand.Web.Common/Security/Authentication/CookieOptionsFactory.cs @@ -1,8 +1,7 @@ -using Grand.Business.Core.Interfaces.Authentication; -using Grand.Infrastructure.Configuration; +using Grand.Infrastructure.Configuration; using Microsoft.AspNetCore.Http; -namespace Grand.Business.Authentication.Services; +namespace Grand.Web.Common.Security.Authentication; /// /// Factory for creating secure cookie options diff --git a/src/Business/Grand.Business.Core/Interfaces/Authentication/IApiAuthenticationService.cs b/src/Web/Grand.Web.Common/Security/Authentication/IApiAuthenticationService.cs similarity index 80% rename from src/Business/Grand.Business.Core/Interfaces/Authentication/IApiAuthenticationService.cs rename to src/Web/Grand.Web.Common/Security/Authentication/IApiAuthenticationService.cs index 62e8e79218..777874940e 100644 --- a/src/Business/Grand.Business.Core/Interfaces/Authentication/IApiAuthenticationService.cs +++ b/src/Web/Grand.Web.Common/Security/Authentication/IApiAuthenticationService.cs @@ -1,6 +1,6 @@ using Grand.Domain.Customers; -namespace Grand.Business.Core.Interfaces.Authentication; +namespace Grand.Web.Common.Security.Authentication; public interface IApiAuthenticationService { diff --git a/src/Business/Grand.Business.Core/Interfaces/Authentication/ICookieOptionsFactory.cs b/src/Web/Grand.Web.Common/Security/Authentication/ICookieOptionsFactory.cs similarity index 90% rename from src/Business/Grand.Business.Core/Interfaces/Authentication/ICookieOptionsFactory.cs rename to src/Web/Grand.Web.Common/Security/Authentication/ICookieOptionsFactory.cs index e743eb5b20..1ef2912d28 100644 --- a/src/Business/Grand.Business.Core/Interfaces/Authentication/ICookieOptionsFactory.cs +++ b/src/Web/Grand.Web.Common/Security/Authentication/ICookieOptionsFactory.cs @@ -1,6 +1,6 @@ using Microsoft.AspNetCore.Http; -namespace Grand.Business.Core.Interfaces.Authentication; +namespace Grand.Web.Common.Security.Authentication; // /// Interface for factory creating secure cookie options diff --git a/src/Web/Grand.Web.Common/Startup/StartupApplication.cs b/src/Web/Grand.Web.Common/Startup/StartupApplication.cs index 72ed2561eb..32341410d5 100644 --- a/src/Web/Grand.Web.Common/Startup/StartupApplication.cs +++ b/src/Web/Grand.Web.Common/Startup/StartupApplication.cs @@ -1,3 +1,4 @@ +using Grand.Business.Core.Interfaces.Authentication; using Grand.Business.Core.Interfaces.Common.Pdf; using Grand.Business.Core.Interfaces.System.Admin; using Grand.Data; @@ -15,6 +16,7 @@ using Grand.Web.Common.Page; using Grand.Web.Common.RequestCustomerResolvers; using Grand.Web.Common.Routing; +using Grand.Web.Common.Security.Authentication; using Grand.Web.Common.Security.Authorization; using Grand.Web.Common.Security.Captcha; using Grand.Web.Common.TagHelpers; @@ -122,6 +124,9 @@ private static void RegisterFramework(IServiceCollection serviceCollection) serviceCollection.AddScoped(); serviceCollection.AddScoped(); + serviceCollection.AddScoped(); + serviceCollection.AddScoped(); + serviceCollection.AddScoped(); serviceCollection.AddScoped(); if (DataSettingsManager.DatabaseIsInstalled()) { diff --git a/src/Web/Grand.Web.Common/Themes/ThemeContext.cs b/src/Web/Grand.Web.Common/Themes/ThemeContext.cs index 7977ad5734..120aabe0a6 100644 --- a/src/Web/Grand.Web.Common/Themes/ThemeContext.cs +++ b/src/Web/Grand.Web.Common/Themes/ThemeContext.cs @@ -1,5 +1,5 @@ -using Grand.Business.Core.Interfaces.Authentication; -using Grand.Domain.Stores; +using Grand.Domain.Stores; +using Grand.Web.Common.Security.Authentication; using Microsoft.AspNetCore.Http; namespace Grand.Web.Common.Themes; diff --git a/src/Web/Grand.Web.Common/Themes/ThemeContextBase.cs b/src/Web/Grand.Web.Common/Themes/ThemeContextBase.cs index 7c42db7ec8..3b2bb5a44f 100644 --- a/src/Web/Grand.Web.Common/Themes/ThemeContextBase.cs +++ b/src/Web/Grand.Web.Common/Themes/ThemeContextBase.cs @@ -1,4 +1,4 @@ -using Grand.Business.Core.Interfaces.Authentication; +using Grand.Web.Common.Security.Authentication; using Microsoft.AspNetCore.Http; namespace Grand.Web.Common.Themes; diff --git a/src/Web/Grand.Web.Store/Infrastructure/StoreThemeContext.cs b/src/Web/Grand.Web.Store/Infrastructure/StoreThemeContext.cs index d2b684d87d..f15467f544 100644 --- a/src/Web/Grand.Web.Store/Infrastructure/StoreThemeContext.cs +++ b/src/Web/Grand.Web.Store/Infrastructure/StoreThemeContext.cs @@ -1,5 +1,5 @@ -using Grand.Business.Core.Interfaces.Authentication; -using Grand.Domain.Stores; +using Grand.Domain.Stores; +using Grand.Web.Common.Security.Authentication; using Grand.Web.Store.Extensions; using Grand.Web.Common.Themes; diff --git a/src/Web/Grand.Web/Controllers/CommonController.cs b/src/Web/Grand.Web/Controllers/CommonController.cs index 139d23312e..2453d4afbf 100644 --- a/src/Web/Grand.Web/Controllers/CommonController.cs +++ b/src/Web/Grand.Web/Controllers/CommonController.cs @@ -1,5 +1,4 @@ -using Grand.Business.Core.Interfaces.Authentication; -using Grand.Business.Core.Interfaces.Cms; +using Grand.Business.Core.Interfaces.Cms; using Grand.Business.Core.Interfaces.Common.Directory; using Grand.Business.Core.Interfaces.Common.Localization; using Grand.Business.Core.Interfaces.Common.Stores; @@ -17,6 +16,7 @@ using Grand.Web.Commands.Models.Customers; using Grand.Web.Common.Controllers; using Grand.Web.Common.Filters; +using Grand.Web.Common.Security.Authentication; using Grand.Web.Common.Themes; using Grand.Web.Events; using Grand.Web.Features.Models.Common; From 1957577e08963cd1297dbaeb11084e40cc817681 Mon Sep 17 00:00:00 2001 From: support Date: Sun, 18 Oct 2026 13:12:57 +0200 Subject: [PATCH 2/2] Fix the summary tag of ICookieOptionsFactory --- .../Security/Authentication/ICookieOptionsFactory.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Web/Grand.Web.Common/Security/Authentication/ICookieOptionsFactory.cs b/src/Web/Grand.Web.Common/Security/Authentication/ICookieOptionsFactory.cs index 1ef2912d28..7ca6568122 100644 --- a/src/Web/Grand.Web.Common/Security/Authentication/ICookieOptionsFactory.cs +++ b/src/Web/Grand.Web.Common/Security/Authentication/ICookieOptionsFactory.cs @@ -2,7 +2,7 @@ namespace Grand.Web.Common.Security.Authentication; -// +/// /// Interface for factory creating secure cookie options /// public interface ICookieOptionsFactory