From 6c855e57c512a3bb467e0ba51ade9c0f3dd49ae2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ram=C3=B3n=20Tom=C3=A1s?= Date: Thu, 8 Jun 2017 17:45:07 +0200 Subject: [PATCH] Fix bug antiforgery decryption issue when deploying in a k8s cluster Changed in-memory grant store in idsrv to persist in db --- eShopOnContainers-ServicesAndWebApps.sln | 56 +++++++++++++++- k8s/deploy.ps1 | 2 +- k8s/deployments.yaml | 13 +++- k8s/keystore-data.yaml | 29 ++++++++ .../DataProtection/DataProtection.csproj | 13 ++++ .../DataProtectionBuilderExtensions.cs | 13 ++-- .../DataProtection}/RedisXmlRepository.cs | 24 +++---- .../Identity/Identity.API/Identity.API.csproj | 7 +- src/Services/Identity/Identity.API/Startup.cs | 66 ++++++++++--------- .../Identity/Identity.API/appsettings.json | 3 +- .../WebMVC/Controllers/AccountController.cs | 2 - src/Web/WebMVC/Startup.cs | 34 +++++----- src/Web/WebMVC/WebMVC.csproj | 1 + src/Web/WebMVC/appsettings.json | 1 + src/Web/WebMVC/wwwroot/css/site.min.css | 2 +- src/Web/WebSPA/Startup.cs | 11 +++- src/Web/WebSPA/WebSPA.csproj | 1 + 17 files changed, 196 insertions(+), 82 deletions(-) create mode 100644 k8s/keystore-data.yaml create mode 100644 src/BuildingBlocks/DataProtection/DataProtection/DataProtection.csproj rename src/{Services/Identity/Identity.API/Extensions => BuildingBlocks/DataProtection/DataProtection}/DataProtectionBuilderExtensions.cs (93%) rename src/{Services/Identity/Identity.API/Extensions => BuildingBlocks/DataProtection/DataProtection}/RedisXmlRepository.cs (95%) diff --git a/eShopOnContainers-ServicesAndWebApps.sln b/eShopOnContainers-ServicesAndWebApps.sln index d9c994954..edd18d523 100644 --- a/eShopOnContainers-ServicesAndWebApps.sln +++ b/eShopOnContainers-ServicesAndWebApps.sln @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 15 -VisualStudioVersion = 15.0.26430.12 +VisualStudioVersion = 15.0.26430.6 MinimumVisualStudioVersion = 10.0.40219.1 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{932D8224-11F6-4D07-B109-DA28AD288A63}" EndProject @@ -76,6 +76,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Extensions.Health EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EventBus.Tests", "src\BuildingBlocks\EventBus\EventBus.Tests\EventBus.Tests.csproj", "{89D80DF1-32E1-4AAF-970F-DA0AA6881F9D}" EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "DataProtection", "DataProtection", "{88B22DBB-AA8F-4290-A454-2C109352C345}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DataProtection", "src\BuildingBlocks\DataProtection\DataProtection\DataProtection.csproj", "{23A33F9B-7672-426D-ACF9-FF8436ADC81A}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Ad-Hoc|Any CPU = Ad-Hoc|Any CPU @@ -1002,6 +1006,54 @@ Global {89D80DF1-32E1-4AAF-970F-DA0AA6881F9D}.Release|x64.Build.0 = Release|Any CPU {89D80DF1-32E1-4AAF-970F-DA0AA6881F9D}.Release|x86.ActiveCfg = Release|Any CPU {89D80DF1-32E1-4AAF-970F-DA0AA6881F9D}.Release|x86.Build.0 = Release|Any CPU + {23A33F9B-7672-426D-ACF9-FF8436ADC81A}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU + {23A33F9B-7672-426D-ACF9-FF8436ADC81A}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU + {23A33F9B-7672-426D-ACF9-FF8436ADC81A}.Ad-Hoc|ARM.ActiveCfg = Debug|Any CPU + {23A33F9B-7672-426D-ACF9-FF8436ADC81A}.Ad-Hoc|ARM.Build.0 = Debug|Any CPU + {23A33F9B-7672-426D-ACF9-FF8436ADC81A}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU + {23A33F9B-7672-426D-ACF9-FF8436ADC81A}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU + {23A33F9B-7672-426D-ACF9-FF8436ADC81A}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {23A33F9B-7672-426D-ACF9-FF8436ADC81A}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU + {23A33F9B-7672-426D-ACF9-FF8436ADC81A}.Ad-Hoc|x64.ActiveCfg = Debug|Any CPU + {23A33F9B-7672-426D-ACF9-FF8436ADC81A}.Ad-Hoc|x64.Build.0 = Debug|Any CPU + {23A33F9B-7672-426D-ACF9-FF8436ADC81A}.Ad-Hoc|x86.ActiveCfg = Debug|Any CPU + {23A33F9B-7672-426D-ACF9-FF8436ADC81A}.Ad-Hoc|x86.Build.0 = Debug|Any CPU + {23A33F9B-7672-426D-ACF9-FF8436ADC81A}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU + {23A33F9B-7672-426D-ACF9-FF8436ADC81A}.AppStore|Any CPU.Build.0 = Debug|Any CPU + {23A33F9B-7672-426D-ACF9-FF8436ADC81A}.AppStore|ARM.ActiveCfg = Debug|Any CPU + {23A33F9B-7672-426D-ACF9-FF8436ADC81A}.AppStore|ARM.Build.0 = Debug|Any CPU + {23A33F9B-7672-426D-ACF9-FF8436ADC81A}.AppStore|iPhone.ActiveCfg = Debug|Any CPU + {23A33F9B-7672-426D-ACF9-FF8436ADC81A}.AppStore|iPhone.Build.0 = Debug|Any CPU + {23A33F9B-7672-426D-ACF9-FF8436ADC81A}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {23A33F9B-7672-426D-ACF9-FF8436ADC81A}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU + {23A33F9B-7672-426D-ACF9-FF8436ADC81A}.AppStore|x64.ActiveCfg = Debug|Any CPU + {23A33F9B-7672-426D-ACF9-FF8436ADC81A}.AppStore|x64.Build.0 = Debug|Any CPU + {23A33F9B-7672-426D-ACF9-FF8436ADC81A}.AppStore|x86.ActiveCfg = Debug|Any CPU + {23A33F9B-7672-426D-ACF9-FF8436ADC81A}.AppStore|x86.Build.0 = Debug|Any CPU + {23A33F9B-7672-426D-ACF9-FF8436ADC81A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {23A33F9B-7672-426D-ACF9-FF8436ADC81A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {23A33F9B-7672-426D-ACF9-FF8436ADC81A}.Debug|ARM.ActiveCfg = Debug|Any CPU + {23A33F9B-7672-426D-ACF9-FF8436ADC81A}.Debug|ARM.Build.0 = Debug|Any CPU + {23A33F9B-7672-426D-ACF9-FF8436ADC81A}.Debug|iPhone.ActiveCfg = Debug|Any CPU + {23A33F9B-7672-426D-ACF9-FF8436ADC81A}.Debug|iPhone.Build.0 = Debug|Any CPU + {23A33F9B-7672-426D-ACF9-FF8436ADC81A}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {23A33F9B-7672-426D-ACF9-FF8436ADC81A}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU + {23A33F9B-7672-426D-ACF9-FF8436ADC81A}.Debug|x64.ActiveCfg = Debug|Any CPU + {23A33F9B-7672-426D-ACF9-FF8436ADC81A}.Debug|x64.Build.0 = Debug|Any CPU + {23A33F9B-7672-426D-ACF9-FF8436ADC81A}.Debug|x86.ActiveCfg = Debug|Any CPU + {23A33F9B-7672-426D-ACF9-FF8436ADC81A}.Debug|x86.Build.0 = Debug|Any CPU + {23A33F9B-7672-426D-ACF9-FF8436ADC81A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {23A33F9B-7672-426D-ACF9-FF8436ADC81A}.Release|Any CPU.Build.0 = Release|Any CPU + {23A33F9B-7672-426D-ACF9-FF8436ADC81A}.Release|ARM.ActiveCfg = Release|Any CPU + {23A33F9B-7672-426D-ACF9-FF8436ADC81A}.Release|ARM.Build.0 = Release|Any CPU + {23A33F9B-7672-426D-ACF9-FF8436ADC81A}.Release|iPhone.ActiveCfg = Release|Any CPU + {23A33F9B-7672-426D-ACF9-FF8436ADC81A}.Release|iPhone.Build.0 = Release|Any CPU + {23A33F9B-7672-426D-ACF9-FF8436ADC81A}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU + {23A33F9B-7672-426D-ACF9-FF8436ADC81A}.Release|iPhoneSimulator.Build.0 = Release|Any CPU + {23A33F9B-7672-426D-ACF9-FF8436ADC81A}.Release|x64.ActiveCfg = Release|Any CPU + {23A33F9B-7672-426D-ACF9-FF8436ADC81A}.Release|x64.Build.0 = Release|Any CPU + {23A33F9B-7672-426D-ACF9-FF8436ADC81A}.Release|x86.ActiveCfg = Release|Any CPU + {23A33F9B-7672-426D-ACF9-FF8436ADC81A}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -1038,5 +1090,7 @@ Global {22A0F9C1-2D4A-4107-95B7-8459E6688BC5} = {A81ECBC2-6B00-4DCD-8388-469174033379} {4BD76717-3102-4969-8C2C-BAAA3F0263B6} = {A81ECBC2-6B00-4DCD-8388-469174033379} {89D80DF1-32E1-4AAF-970F-DA0AA6881F9D} = {807BB76E-B2BB-47A2-A57B-3D1B20FF5E7F} + {88B22DBB-AA8F-4290-A454-2C109352C345} = {DB0EFB20-B024-4E5E-A75C-52143C131D25} + {23A33F9B-7672-426D-ACF9-FF8436ADC81A} = {88B22DBB-AA8F-4290-A454-2C109352C345} EndGlobalSection EndGlobal diff --git a/k8s/deploy.ps1 b/k8s/deploy.ps1 index 0619dd8e8..9930474ba 100644 --- a/k8s/deploy.ps1 +++ b/k8s/deploy.ps1 @@ -58,7 +58,7 @@ ExecKube -cmd 'delete configmap urls' # start sql, rabbitmq, frontend deploymentsExecKube -cmd 'delete configmap config-files' ExecKube -cmd 'create configmap config-files --from-file=nginx-conf=nginx.conf' ExecKube -cmd 'label configmap config-files app=eshop' -ExecKube -cmd 'create -f sql-data.yaml -f basket-data.yaml -f rabbitmq.yaml -f services.yaml -f frontend.yaml' +ExecKube -cmd 'create -f sql-data.yaml -f basket-data.yaml -f keystore-data.yaml -f rabbitmq.yaml -f services.yaml -f frontend.yaml' # building and publishing docker images not necessary when deploying through CI VSTS if(-not $deployCI) { diff --git a/k8s/deployments.yaml b/k8s/deployments.yaml index a0b1df135..62352e2ef 100644 --- a/k8s/deployments.yaml +++ b/k8s/deployments.yaml @@ -69,7 +69,6 @@ kind: Deployment metadata: name: identity spec: - replicas: 3 paused: true template: metadata: @@ -86,6 +85,10 @@ spec: value: http://0.0.0.0:80/identity - name: ConnectionStrings__DefaultConnection value: "Server=sql-data;Initial Catalog=Microsoft.eShopOnContainers.Services.IdentityDb;User Id=sa;Password=Pass@word" + - name: DPConnectionString + value: keystore-data + - name: IsClusterEnv + value: 'True' - name: MvcClient valueFrom: configMapKeyRef: @@ -153,6 +156,10 @@ spec: env: - name: ASPNETCORE_URLS value: http://0.0.0.0:80/webmvc + - name: DPConnectionString + value: keystore-data + - name: IsClusterEnv + value: 'True' - name: BasketUrl valueFrom: configMapKeyRef: @@ -256,6 +263,10 @@ spec: env: - name: ASPNETCORE_URLS value: http://0.0.0.0:80 + - name: DPConnectionString + value: keystore-data + - name: IsClusterEnv + value: 'True' - name: BasketUrl valueFrom: configMapKeyRef: diff --git a/k8s/keystore-data.yaml b/k8s/keystore-data.yaml new file mode 100644 index 000000000..3340cce35 --- /dev/null +++ b/k8s/keystore-data.yaml @@ -0,0 +1,29 @@ +apiVersion: v1 +kind: Service +metadata: + labels: + app: eshop + component: keystore-data + name: keystore-data +spec: + ports: + - port: 6379 + selector: + app: eshop + component: keystore-data +--- +apiVersion: extensions/v1beta1 +kind: Deployment +metadata: + name: keystore-data +spec: + template: + metadata: + labels: + app: eshop + component: keystore-data + spec: + containers: + - name: keystore-data + image: redis:3.2-alpine + diff --git a/src/BuildingBlocks/DataProtection/DataProtection/DataProtection.csproj b/src/BuildingBlocks/DataProtection/DataProtection/DataProtection.csproj new file mode 100644 index 000000000..bfe61a85a --- /dev/null +++ b/src/BuildingBlocks/DataProtection/DataProtection/DataProtection.csproj @@ -0,0 +1,13 @@ + + + + netcoreapp1.1 + Microsoft.eShopOnContainers.BuildingBlocks + + + + + + + + \ No newline at end of file diff --git a/src/Services/Identity/Identity.API/Extensions/DataProtectionBuilderExtensions.cs b/src/BuildingBlocks/DataProtection/DataProtection/DataProtectionBuilderExtensions.cs similarity index 93% rename from src/Services/Identity/Identity.API/Extensions/DataProtectionBuilderExtensions.cs rename to src/BuildingBlocks/DataProtection/DataProtection/DataProtectionBuilderExtensions.cs index 11fc8342e..3db776b9a 100644 --- a/src/Services/Identity/Identity.API/Extensions/DataProtectionBuilderExtensions.cs +++ b/src/BuildingBlocks/DataProtection/DataProtection/DataProtectionBuilderExtensions.cs @@ -1,13 +1,11 @@ -namespace DataProtectionExtensions +namespace Microsoft.eShopOnContainers.BuildingBlocks { - using System; - using System.Linq; - using System.Security.Cryptography.X509Certificates; using Microsoft.AspNetCore.DataProtection; using Microsoft.AspNetCore.DataProtection.Repositories; - using Microsoft.AspNetCore.DataProtection.XmlEncryption; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; + using System; + using System.Linq; using System.Net; /// @@ -46,10 +44,11 @@ { throw new ArgumentException("Redis connection string may not be empty.", nameof(redisConnectionString)); } - + var ips = Dns.GetHostAddressesAsync(redisConnectionString).Result; - return builder.Use(ServiceDescriptor.Singleton(services => new RedisXmlRepository(ips.First().ToString(), services.GetRequiredService>()))); + return builder.Use(ServiceDescriptor.Singleton(services => + new RedisXmlRepository(ips.First().ToString(), services.GetRequiredService>()))); } /// diff --git a/src/Services/Identity/Identity.API/Extensions/RedisXmlRepository.cs b/src/BuildingBlocks/DataProtection/DataProtection/RedisXmlRepository.cs similarity index 95% rename from src/Services/Identity/Identity.API/Extensions/RedisXmlRepository.cs rename to src/BuildingBlocks/DataProtection/DataProtection/RedisXmlRepository.cs index ebb36c1b7..f5a903b65 100644 --- a/src/Services/Identity/Identity.API/Extensions/RedisXmlRepository.cs +++ b/src/BuildingBlocks/DataProtection/DataProtection/RedisXmlRepository.cs @@ -1,17 +1,13 @@ -using System; -using System.Collections.Generic; -using System.Diagnostics.CodeAnalysis; -using System.IO; -using System.Linq; -using System.Text; -using System.Text.RegularExpressions; -using System.Xml.Linq; -using Microsoft.AspNetCore.DataProtection.Repositories; -using Microsoft.Extensions.Logging; -using StackExchange.Redis; - -namespace DataProtectionExtensions +namespace Microsoft.eShopOnContainers.BuildingBlocks { + using Microsoft.AspNetCore.DataProtection.Repositories; + using Microsoft.Extensions.Logging; + using StackExchange.Redis; + using System; + using System.Collections.Generic; + using System.Text.RegularExpressions; + using System.Xml.Linq; + /// /// Key repository that stores XML encrypted keys in a Redis distributed cache. /// @@ -211,4 +207,4 @@ namespace DataProtectionExtensions } } } -} \ No newline at end of file +} diff --git a/src/Services/Identity/Identity.API/Identity.API.csproj b/src/Services/Identity/Identity.API/Identity.API.csproj index b3e499c6b..c27a51593 100644 --- a/src/Services/Identity/Identity.API/Identity.API.csproj +++ b/src/Services/Identity/Identity.API/Identity.API.csproj @@ -39,7 +39,6 @@ - @@ -59,6 +58,7 @@ + @@ -70,4 +70,9 @@ + + + + + diff --git a/src/Services/Identity/Identity.API/Startup.cs b/src/Services/Identity/Identity.API/Startup.cs index 98ed8578d..c5f72af13 100644 --- a/src/Services/Identity/Identity.API/Startup.cs +++ b/src/Services/Identity/Identity.API/Startup.cs @@ -1,29 +1,27 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; +using Identity.API.Certificate; +using Identity.API.Configuration; +using Identity.API.Data; +using Identity.API.Models; +using Identity.API.Services; +using IdentityServer4.EntityFramework.DbContexts; +using IdentityServer4.EntityFramework.Mappers; +using IdentityServer4.Services; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; +using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Identity.EntityFrameworkCore; using Microsoft.EntityFrameworkCore; +using Microsoft.eShopOnContainers.BuildingBlocks; +using Microsoft.eShopOnContainers.Services.Catalog.API.Infrastructure; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Logging; -using Identity.API.Data; -using Identity.API.Models; -using Identity.API.Services; -using Identity.API.Configuration; -using IdentityServer4.Services; -using System.Threading; -using Microsoft.eShopOnContainers.Services.Catalog.API.Infrastructure; -using Microsoft.AspNetCore.Identity; using Microsoft.Extensions.HealthChecks; -using Identity.API.Certificate; -using DataProtectionExtensions; +using Microsoft.Extensions.Logging; +using System; +using System.Collections.Generic; +using System.Linq; using System.Reflection; -using IdentityServer4.Test; -using IdentityServer4.EntityFramework.DbContexts; -using IdentityServer4.EntityFramework.Mappers; +using System.Threading.Tasks; namespace eShopOnContainers.Identity { @@ -39,7 +37,7 @@ namespace eShopOnContainers.Identity if (env.IsDevelopment()) { // For more details on using the user secret store see http://go.microsoft.com/fwlink/?LinkID=532709 - //builder.AddUserSecrets(); + builder.AddUserSecrets(); } builder.AddEnvironmentVariables(); @@ -63,10 +61,14 @@ namespace eShopOnContainers.Identity services.AddMvc(); - services.AddDataProtection(opts => + if (Configuration.GetValue("IsClusterEnv") == bool.TrueString) { - opts.ApplicationDiscriminator = "eshop.identity"; - });//.PersistKeysToRedis("basket.data"); + services.AddDataProtection(opts => + { + opts.ApplicationDiscriminator = "eshop.identity"; + }) + .PersistKeysToRedis(Configuration["DPConnectionString"]); + } services.AddHealthChecks(checks => { @@ -138,15 +140,15 @@ namespace eShopOnContainers.Identity template: "{controller=Home}/{action=Index}/{id?}"); }); - InitializeDatabase(app); + // Store idsrv grant config into db + InitializeGrantStoreAndConfiguration(app).Wait(); //Seed Data var hasher = new PasswordHasher(); - new ApplicationContextSeed(hasher).SeedAsync(app, loggerFactory) - .Wait(); + new ApplicationContextSeed(hasher).SeedAsync(app, loggerFactory).Wait(); } - private void InitializeDatabase(IApplicationBuilder app) + private async Task InitializeGrantStoreAndConfiguration(IApplicationBuilder app) { //callbacks urls from config: Dictionary clientUrls = new Dictionary(); @@ -164,27 +166,27 @@ namespace eShopOnContainers.Identity { foreach (var client in Config.GetClients(clientUrls)) { - context.Clients.Add(client.ToEntity()); + await context.Clients.AddAsync(client.ToEntity()); } - context.SaveChanges(); + await context.SaveChangesAsync(); } if (!context.IdentityResources.Any()) { foreach (var resource in Config.GetResources()) { - context.IdentityResources.Add(resource.ToEntity()); + await context.IdentityResources.AddAsync(resource.ToEntity()); } - context.SaveChanges(); + await context.SaveChangesAsync(); } if (!context.ApiResources.Any()) { foreach (var api in Config.GetApis()) { - context.ApiResources.Add(api.ToEntity()); + await context.ApiResources.AddAsync(api.ToEntity()); } - context.SaveChanges(); + await context.SaveChangesAsync(); } } } diff --git a/src/Services/Identity/Identity.API/appsettings.json b/src/Services/Identity/Identity.API/appsettings.json index c188cb721..557bac0c3 100644 --- a/src/Services/Identity/Identity.API/appsettings.json +++ b/src/Services/Identity/Identity.API/appsettings.json @@ -2,9 +2,10 @@ "ConnectionStrings": { "DefaultConnection": "Server=tcp:127.0.0.1,5433;Database=Microsoft.eShopOnContainers.Services.IdentityDb;User Id=sa;Password=Pass@word;" }, + "IsClusterEnv": "False", "MvcClient": "http://localhost:5100", "SpaClient": "http://localhost:5104", - "XamarinCallback": "http://localhost:5105/xamarincallback", + "XamarinCallback": "http://localhost:5105/xamarincallback", "Logging": { "IncludeScopes": false, "LogLevel": { diff --git a/src/Web/WebMVC/Controllers/AccountController.cs b/src/Web/WebMVC/Controllers/AccountController.cs index 531c6f547..a38207d58 100644 --- a/src/Web/WebMVC/Controllers/AccountController.cs +++ b/src/Web/WebMVC/Controllers/AccountController.cs @@ -24,8 +24,6 @@ namespace Microsoft.eShopOnContainers.WebMVC.Controllers var user = User as ClaimsPrincipal; var token = await HttpContext.Authentication.GetTokenAsync("access_token"); - //TODO - Not retrieving AccessToken yet - //var token = user.FindFirst("access_token"); if (token != null) { ViewData["access_token"] = token; diff --git a/src/Web/WebMVC/Startup.cs b/src/Web/WebMVC/Startup.cs index 1a6fc240b..f119e1d8e 100644 --- a/src/Web/WebMVC/Startup.cs +++ b/src/Web/WebMVC/Startup.cs @@ -1,22 +1,17 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; -using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; +using Microsoft.AspNetCore.Http; +using Microsoft.eShopOnContainers.BuildingBlocks; +using Microsoft.eShopOnContainers.BuildingBlocks.Resilience.Http; +using Microsoft.eShopOnContainers.WebMVC.Infrastructure; +using Microsoft.eShopOnContainers.WebMVC.Services; +using Microsoft.eShopOnContainers.WebMVC.ViewModels; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.HealthChecks; using Microsoft.Extensions.Logging; -using Microsoft.eShopOnContainers.WebMVC.ViewModels; -using Microsoft.eShopOnContainers.WebMVC.Services; +using System; using System.IdentityModel.Tokens.Jwt; -using Microsoft.IdentityModel.Tokens; -using Microsoft.AspNetCore.Http; -using System.Threading; -using Microsoft.Extensions.Options; -using Microsoft.Extensions.HealthChecks; -using Microsoft.eShopOnContainers.BuildingBlocks.Resilience.Http; -using Microsoft.eShopOnContainers.WebMVC.Infrastructure; namespace Microsoft.eShopOnContainers.WebMVC { @@ -46,12 +41,15 @@ namespace Microsoft.eShopOnContainers.WebMVC { services.AddMvc(); - services.AddDataProtection(opts => + if (Configuration.GetValue("IsClusterEnv") == bool.TrueString) { - opts.ApplicationDiscriminator = "eshop.webmvc"; - }); + services.AddDataProtection(opts => + { + opts.ApplicationDiscriminator = "eshop.webmvc"; + }) + .PersistKeysToRedis(Configuration["DPConnectionString"]); + } - services.Configure(Configuration); services.AddHealthChecks(checks => diff --git a/src/Web/WebMVC/WebMVC.csproj b/src/Web/WebMVC/WebMVC.csproj index 9686de6f0..a9507394c 100644 --- a/src/Web/WebMVC/WebMVC.csproj +++ b/src/Web/WebMVC/WebMVC.csproj @@ -54,6 +54,7 @@ + diff --git a/src/Web/WebMVC/appsettings.json b/src/Web/WebMVC/appsettings.json index 796bc972f..4cb9ec7b8 100644 --- a/src/Web/WebMVC/appsettings.json +++ b/src/Web/WebMVC/appsettings.json @@ -4,6 +4,7 @@ "BasketUrl": "http://localhost:5103", "IdentityUrl": "http://localhost:5105", "CallBackUrl": "http://localhost:5100/", + "IsClusterEnv": "True", "UseResilientHttp": "True", "Logging": { "IncludeScopes": false, diff --git a/src/Web/WebMVC/wwwroot/css/site.min.css b/src/Web/WebMVC/wwwroot/css/site.min.css index 2a4a53b47..4d03fa783 100644 --- a/src/Web/WebMVC/wwwroot/css/site.min.css +++ b/src/Web/WebMVC/wwwroot/css/site.min.css @@ -1 +1 @@ -.esh-app-footer{background-color:#000;border-top:1px solid #eee;margin-top:2.5rem;padding-bottom:2.5rem;padding-top:2.5rem;width:100%}.esh-app-footer-brand{height:50px;width:230px}.esh-app-footer-text{color:#83d01b;line-height:50px;text-align:right;width:100%}@font-face{font-family:Montserrat;font-weight:400;src:url("../fonts/Montserrat-Regular.eot?") format("eot"),url("../fonts/Montserrat-Regular.woff") format("woff"),url("../fonts/Montserrat-Regular.ttf") format("truetype"),url("../fonts/Montserrat-Regular.svg#Montserrat") format("svg")}@font-face{font-family:Montserrat;font-weight:700;src:url("../fonts/Montserrat-Bold.eot?") format("eot"),url("../fonts/Montserrat-Bold.woff") format("woff"),url("../fonts/Montserrat-Bold.ttf") format("truetype"),url("../fonts/Montserrat-Bold.svg#Montserrat") format("svg")}html,body{font-family:Montserrat,sans-serif;font-size:16px;font-weight:400;z-index:10}*,*::after,*::before{box-sizing:border-box}.preloading{color:#00a69c;display:block;font-size:1.5rem;left:50%;position:fixed;top:50%;transform:translate(-50%,-50%)}select::-ms-expand{display:none}@media screen and (min-width:992px){.form-input{max-width:360px;width:360px}}.form-input{border-radius:0;height:45px;padding:10px}.form-input-small{max-width:100px !important}.form-input-medium{width:150px !important}.alert{padding-left:0}.alert-danger{background-color:transparent;border:0;color:#fb0d0d;font-size:12px}a,a:active,a:hover,a:visited{color:#000;text-decoration:none;transition:color .35s}a:hover,a:active{color:#75b918;transition:color .35s}.esh-pager-wrapper{padding-top:1rem;text-align:center}.esh-pager-item{margin:0 5vw}.esh-pager-item--navigable{display:inline-block;cursor:pointer}.esh-pager-item--navigable.is-disabled{opacity:0;pointer-events:none}.esh-pager-item--navigable:hover{color:#83d01b}@media screen and (max-width:1280px){.esh-pager-item{font-size:.85rem}}@media screen and (max-width:1024px){.esh-pager-item{margin:0 4vw}}.esh-identity{line-height:3rem;position:relative;text-align:right}.esh-identity-section{display:inline-block;width:100%}.esh-identity-name{display:inline-block}.esh-identity-name--upper{text-transform:uppercase}@media screen and (max-width:768px){.esh-identity-name{font-size:.85rem}}.esh-identity-image{display:inline-block}.esh-identity-drop{background:#fff;height:0;min-width:14rem;right:0;overflow:hidden;padding:.5rem;position:absolute;top:2.5rem;transition:height .35s}.esh-identity:hover .esh-identity-drop{border:1px solid #eee;height:7rem;transition:height .35s}.esh-identity-item{cursor:pointer;display:block;transition:color .35s}.esh-identity-item:hover{color:#75b918;transition:color .35s}.esh-header{background-color:#00a69c;height:4rem}.esh-header-back{color:rgba(255,255,255,.5) !important;line-height:4rem;text-transform:uppercase;text-decoration:none;transition:color .35s}.esh-header-back:hover{color:#fff !important;transition:color .35s}.esh-orders{min-height:80vh;overflow-x:hidden}.esh-orders-header{background-color:#00a69c;height:4rem}.esh-orders-back{color:rgba(255,255,255,.4);line-height:4rem;text-transform:uppercase;text-decoration:none;transition:color .35s}.esh-orders-back:hover{color:#fff;transition:color .35s}.esh-orders-titles{padding-bottom:1rem;padding-top:2rem}.esh-orders-title{text-transform:uppercase}.esh-orders-items{height:2rem;line-height:2rem;position:relative}.esh-orders-items:nth-of-type(2n+1):before{background-color:#eef;content:'';height:100%;left:0;margin-left:-100vw;position:absolute;top:0;width:200vw;z-index:-1}.esh-orders-item{font-weight:300}.esh-orders-item--hover{opacity:0;pointer-events:none}.esh-orders-items:hover .esh-orders-item--hover{opacity:1;pointer-events:all}.esh-orders-link{color:#83d01b;text-decoration:none;transition:color .35s}.esh-orders-link:hover{color:#75b918;transition:color .35s}.esh-orders_new{min-height:80vh}.esh-orders_new-header{background-color:#00a69c;height:4rem}.esh-orders_new-back{color:rgba(255,255,255,.4);line-height:4rem;text-decoration:none;text-transform:uppercase;transition:color .35s}.esh-orders_new-back:hover{color:#fff;transition:color .35s}.esh-orders_new-section{padding:1rem 0}.esh-orders_new-section--right{text-align:right}.esh-orders_new-placeOrder{background-color:#83d01b;border:0;border-radius:0;color:#fff;display:inline-block;font-size:1rem;font-weight:400;margin-top:1rem;padding:1rem 1.5rem;text-align:center;text-transform:uppercase;transition:all .35s}.esh-orders_new-placeOrder:hover{background-color:#4a760f;transition:all .35s}.esh-orders_new-titles{padding-bottom:1rem;padding-top:2rem}.esh-orders_new-title{font-size:1.25rem;text-transform:uppercase}.esh-orders_new-items--border{border-bottom:1px solid #eee;padding:.5rem 0}.esh-orders_new-items--border:last-of-type{border-color:transparent}.esh-orders_new-item{font-size:1rem;font-weight:300}.esh-orders_new-item--middle{line-height:8rem}@media screen and (max-width:768px){.esh-orders_new-item--middle{line-height:1rem}}.esh-orders_new-item--mark{color:#83d01b}.esh-orders_new-image{height:8rem}.esh-orders_detail{min-height:80vh}.esh-orders_detail-section{padding:1rem 0}.esh-orders_detail-section--right{text-align:right}.esh-orders_detail-titles{padding-bottom:1rem;padding-top:2rem}.esh-orders_detail-title{text-transform:uppercase}.esh-orders_detail-items--border{border-bottom:1px solid #eee;padding:.5rem 0}.esh-orders_detail-items--border:last-of-type{border-color:transparent}.esh-orders_detail-item{font-size:1rem;font-weight:300}.esh-orders_detail-item--middle{line-height:8rem}@media screen and (max-width:768px){.esh-orders_detail-item--middle{line-height:1rem}}.esh-orders_detail-item--mark{color:#83d01b}.esh-orders_detail-image{height:8rem}.esh-catalog-hero{background-image:url("../images/main_banner.png");background-size:cover;height:260px;width:100%}.esh-catalog-title{position:relative;top:74.28571px}.esh-catalog-filters{background-color:#00a69c;height:65px}.esh-catalog-filter{background-color:transparent;border-color:#00d9cc;color:#fff;cursor:pointer;margin-right:1rem;margin-top:.5rem;outline-color:#83d01b;padding-bottom:0;padding-left:.5rem;padding-right:.5rem;padding-top:1.5rem;min-width:140px;-webkit-appearance:none}.esh-catalog-filter option{background-color:#00a69c}.esh-catalog-label{display:inline-block;position:relative;z-index:0}.esh-catalog-label::before{color:rgba(255,255,255,.5);content:attr(data-title);font-size:.65rem;margin-top:.65rem;margin-left:.5rem;position:absolute;text-transform:uppercase;z-index:1}.esh-catalog-label::after{background-image:url("../images/arrow-down.png");height:7px;content:'';position:absolute;right:1.5rem;top:2.5rem;width:10px;z-index:1}.esh-catalog-send{background-color:#83d01b;color:#fff;cursor:pointer;font-size:1rem;transform:translateY(.5rem);padding:.5rem;transition:all .35s}.esh-catalog-send:hover{background-color:#4a760f;transition:all .35s}.esh-catalog-items{margin-top:1rem}.esh-catalog-item{text-align:center;margin-bottom:1.5rem;width:33%;display:inline-block;float:none !important}@media screen and (max-width:1024px){.esh-catalog-item{width:50%}}@media screen and (max-width:768px){.esh-catalog-item{width:100%}}.esh-catalog-thumbnail{max-width:370px;width:100%}.esh-catalog-button{background-color:#83d01b;border:none;color:#fff;cursor:pointer;font-size:1rem;height:3rem;margin-top:1rem;transition:all .35s;width:80%}.esh-catalog-button.is-disabled{opacity:.5;pointer-events:none}.esh-catalog-button:hover{background-color:#4a760f;transition:all .35s}.esh-catalog-name{font-size:1rem;font-weight:300;margin-top:.5rem;text-align:center;text-transform:uppercase}.esh-catalog-price{text-align:center;font-weight:900;font-size:28px}.esh-catalog-price::before{content:'$'}.esh-basket{min-height:80vh}.esh-basket-titles{padding-bottom:1rem;padding-top:2rem}.esh-basket-titles--clean{padding-bottom:0;padding-top:0}.esh-basket-title{text-transform:uppercase}.esh-basket-items--border{border-bottom:1px solid #eee;padding:.5rem 0}.esh-basket-items--border:last-of-type{border-color:transparent}.esh-basket-item{font-size:1rem;font-weight:300}.esh-basket-item--middle{line-height:8rem}@media screen and (max-width:1024px){.esh-basket-item--middle{line-height:1rem}}.esh-basket-item--mark{color:#00a69c}.esh-basket-image{height:8rem}.esh-basket-input{line-height:1rem;width:100%}.esh-basket-checkout{border:none;border-radius:0;background-color:#83d01b;color:#fff;display:inline-block;font-size:1rem;font-weight:400;margin-top:1rem;padding:1rem 1.5rem;text-align:center;text-transform:uppercase;transition:all .35s}.esh-basket-checkout:hover{background-color:#4a760f;transition:all .35s}.esh-basket-margin12{margin-left:12px}.esh-basketstatus{cursor:pointer;display:inline-block;float:right;position:relative;transition:all .35s}.esh-basketstatus.is-disabled{opacity:.5;pointer-events:none}.esh-basketstatus-image{height:36px;margin-top:.5rem}.esh-basketstatus-badge{background-color:#83d01b;border-radius:50%;color:#fff;display:block;height:1.5rem;left:50%;position:absolute;text-align:center;top:0;transform:translateX(-38%);transition:all .35s;width:1.5rem}.esh-basketstatus:hover .esh-basketstatus-badge{background-color:transparent;color:#75b918;transition:all .35s} \ No newline at end of file +.esh-app-footer{background-color:#000;border-top:1px solid #eee;margin-top:2.5rem;padding-bottom:2.5rem;padding-top:2.5rem;width:100%}.esh-app-footer-brand{height:50px;width:230px}.esh-app-footer-text{color:#83d01b;line-height:50px;text-align:right;width:100%}@font-face{font-family:Montserrat;font-weight:400;src:url("../fonts/Montserrat-Regular.eot?") format("eot"),url("../fonts/Montserrat-Regular.woff") format("woff"),url("../fonts/Montserrat-Regular.ttf") format("truetype"),url("../fonts/Montserrat-Regular.svg#Montserrat") format("svg")}@font-face{font-family:Montserrat;font-weight:700;src:url("../fonts/Montserrat-Bold.eot?") format("eot"),url("../fonts/Montserrat-Bold.woff") format("woff"),url("../fonts/Montserrat-Bold.ttf") format("truetype"),url("../fonts/Montserrat-Bold.svg#Montserrat") format("svg")}html,body{font-family:Montserrat,sans-serif;font-size:16px;font-weight:400;z-index:10}*,*::after,*::before{box-sizing:border-box}.preloading{color:#00a69c;display:block;font-size:1.5rem;left:50%;position:fixed;top:50%;transform:translate(-50%,-50%)}select::-ms-expand{display:none}@media screen and (min-width:992px){.form-input{max-width:360px;width:360px}}.form-input{border-radius:0;height:45px;padding:10px}.form-input-small{max-width:100px !important}.form-input-medium{width:150px !important}.alert{padding-left:0}.alert-danger{background-color:transparent;border:0;color:#fb0d0d;font-size:12px}a,a:active,a:hover,a:visited{color:#000;text-decoration:none;transition:color .35s}a:hover,a:active{color:#75b918;transition:color .35s}.esh-basket{min-height:80vh}.esh-basket-titles{padding-bottom:1rem;padding-top:2rem}.esh-basket-titles--clean{padding-bottom:0;padding-top:0}.esh-basket-title{text-transform:uppercase}.esh-basket-items--border{border-bottom:1px solid #eee;padding:.5rem 0}.esh-basket-items--border:last-of-type{border-color:transparent}.esh-basket-item{font-size:1rem;font-weight:300}.esh-basket-item--middle{line-height:8rem}@media screen and (max-width:1024px){.esh-basket-item--middle{line-height:1rem}}.esh-basket-item--mark{color:#00a69c}.esh-basket-image{height:8rem}.esh-basket-input{line-height:1rem;width:100%}.esh-basket-checkout{border:none;border-radius:0;background-color:#83d01b;color:#fff;display:inline-block;font-size:1rem;font-weight:400;margin-top:1rem;padding:1rem 1.5rem;text-align:center;text-transform:uppercase;transition:all .35s}.esh-basket-checkout:hover{background-color:#4a760f;transition:all .35s}.esh-basket-margin12{margin-left:12px}.esh-basketstatus{cursor:pointer;display:inline-block;float:right;position:relative;transition:all .35s}.esh-basketstatus.is-disabled{opacity:.5;pointer-events:none}.esh-basketstatus-image{height:36px;margin-top:.5rem}.esh-basketstatus-badge{background-color:#83d01b;border-radius:50%;color:#fff;display:block;height:1.5rem;left:50%;position:absolute;text-align:center;top:0;transform:translateX(-38%);transition:all .35s;width:1.5rem}.esh-basketstatus:hover .esh-basketstatus-badge{background-color:transparent;color:#75b918;transition:all .35s}.esh-catalog-hero{background-image:url("../images/main_banner.png");background-size:cover;height:260px;width:100%}.esh-catalog-title{position:relative;top:74.28571px}.esh-catalog-filters{background-color:#00a69c;height:65px}.esh-catalog-filter{background-color:transparent;border-color:#00d9cc;color:#fff;cursor:pointer;margin-right:1rem;margin-top:.5rem;outline-color:#83d01b;padding-bottom:0;padding-left:.5rem;padding-right:.5rem;padding-top:1.5rem;min-width:140px;-webkit-appearance:none}.esh-catalog-filter option{background-color:#00a69c}.esh-catalog-label{display:inline-block;position:relative;z-index:0}.esh-catalog-label::before{color:rgba(255,255,255,.5);content:attr(data-title);font-size:.65rem;margin-top:.65rem;margin-left:.5rem;position:absolute;text-transform:uppercase;z-index:1}.esh-catalog-label::after{background-image:url("../images/arrow-down.png");height:7px;content:'';position:absolute;right:1.5rem;top:2.5rem;width:10px;z-index:1}.esh-catalog-send{background-color:#83d01b;color:#fff;cursor:pointer;font-size:1rem;transform:translateY(.5rem);padding:.5rem;transition:all .35s}.esh-catalog-send:hover{background-color:#4a760f;transition:all .35s}.esh-catalog-items{margin-top:1rem}.esh-catalog-item{text-align:center;margin-bottom:1.5rem;width:33%;display:inline-block;float:none !important}@media screen and (max-width:1024px){.esh-catalog-item{width:50%}}@media screen and (max-width:768px){.esh-catalog-item{width:100%}}.esh-catalog-thumbnail{max-width:370px;width:100%}.esh-catalog-button{background-color:#83d01b;border:none;color:#fff;cursor:pointer;font-size:1rem;height:3rem;margin-top:1rem;transition:all .35s;width:80%}.esh-catalog-button.is-disabled{opacity:.5;pointer-events:none}.esh-catalog-button:hover{background-color:#4a760f;transition:all .35s}.esh-catalog-name{font-size:1rem;font-weight:300;margin-top:.5rem;text-align:center;text-transform:uppercase}.esh-catalog-price{text-align:center;font-weight:900;font-size:28px}.esh-catalog-price::before{content:'$'}.esh-orders{min-height:80vh;overflow-x:hidden}.esh-orders-header{background-color:#00a69c;height:4rem}.esh-orders-back{color:rgba(255,255,255,.4);line-height:4rem;text-transform:uppercase;text-decoration:none;transition:color .35s}.esh-orders-back:hover{color:#fff;transition:color .35s}.esh-orders-titles{padding-bottom:1rem;padding-top:2rem}.esh-orders-title{text-transform:uppercase}.esh-orders-items{height:2rem;line-height:2rem;position:relative}.esh-orders-items:nth-of-type(2n+1):before{background-color:#eef;content:'';height:100%;left:0;margin-left:-100vw;position:absolute;top:0;width:200vw;z-index:-1}.esh-orders-item{font-weight:300}.esh-orders-item--hover{opacity:0;pointer-events:none}.esh-orders-items:hover .esh-orders-item--hover{opacity:1;pointer-events:all}.esh-orders-link{color:#83d01b;text-decoration:none;transition:color .35s}.esh-orders-link:hover{color:#75b918;transition:color .35s}.esh-orders_detail{min-height:80vh}.esh-orders_detail-section{padding:1rem 0}.esh-orders_detail-section--right{text-align:right}.esh-orders_detail-titles{padding-bottom:1rem;padding-top:2rem}.esh-orders_detail-title{text-transform:uppercase}.esh-orders_detail-items--border{border-bottom:1px solid #eee;padding:.5rem 0}.esh-orders_detail-items--border:last-of-type{border-color:transparent}.esh-orders_detail-item{font-size:1rem;font-weight:300}.esh-orders_detail-item--middle{line-height:8rem}@media screen and (max-width:768px){.esh-orders_detail-item--middle{line-height:1rem}}.esh-orders_detail-item--mark{color:#83d01b}.esh-orders_detail-image{height:8rem}.esh-orders_new{min-height:80vh}.esh-orders_new-header{background-color:#00a69c;height:4rem}.esh-orders_new-back{color:rgba(255,255,255,.4);line-height:4rem;text-decoration:none;text-transform:uppercase;transition:color .35s}.esh-orders_new-back:hover{color:#fff;transition:color .35s}.esh-orders_new-section{padding:1rem 0}.esh-orders_new-section--right{text-align:right}.esh-orders_new-placeOrder{background-color:#83d01b;border:0;border-radius:0;color:#fff;display:inline-block;font-size:1rem;font-weight:400;margin-top:1rem;padding:1rem 1.5rem;text-align:center;text-transform:uppercase;transition:all .35s}.esh-orders_new-placeOrder:hover{background-color:#4a760f;transition:all .35s}.esh-orders_new-titles{padding-bottom:1rem;padding-top:2rem}.esh-orders_new-title{font-size:1.25rem;text-transform:uppercase}.esh-orders_new-items--border{border-bottom:1px solid #eee;padding:.5rem 0}.esh-orders_new-items--border:last-of-type{border-color:transparent}.esh-orders_new-item{font-size:1rem;font-weight:300}.esh-orders_new-item--middle{line-height:8rem}@media screen and (max-width:768px){.esh-orders_new-item--middle{line-height:1rem}}.esh-orders_new-item--mark{color:#83d01b}.esh-orders_new-image{height:8rem}.esh-header{background-color:#00a69c;height:4rem}.esh-header-back{color:rgba(255,255,255,.5) !important;line-height:4rem;text-transform:uppercase;text-decoration:none;transition:color .35s}.esh-header-back:hover{color:#fff !important;transition:color .35s}.esh-identity{line-height:3rem;position:relative;text-align:right}.esh-identity-section{display:inline-block;width:100%}.esh-identity-name{display:inline-block}.esh-identity-name--upper{text-transform:uppercase}@media screen and (max-width:768px){.esh-identity-name{font-size:.85rem}}.esh-identity-image{display:inline-block}.esh-identity-drop{background:#fff;height:0;min-width:14rem;right:0;overflow:hidden;padding:.5rem;position:absolute;top:2.5rem;transition:height .35s}.esh-identity:hover .esh-identity-drop{border:1px solid #eee;height:7rem;transition:height .35s}.esh-identity-item{cursor:pointer;display:block;transition:color .35s}.esh-identity-item:hover{color:#75b918;transition:color .35s}.esh-pager-wrapper{padding-top:1rem;text-align:center}.esh-pager-item{margin:0 5vw}.esh-pager-item--navigable{display:inline-block;cursor:pointer}.esh-pager-item--navigable.is-disabled{opacity:0;pointer-events:none}.esh-pager-item--navigable:hover{color:#83d01b}@media screen and (max-width:1280px){.esh-pager-item{font-size:.85rem}}@media screen and (max-width:1024px){.esh-pager-item{margin:0 4vw}} \ No newline at end of file diff --git a/src/Web/WebSPA/Startup.cs b/src/Web/WebSPA/Startup.cs index 53476266a..d9e9d093b 100644 --- a/src/Web/WebSPA/Startup.cs +++ b/src/Web/WebSPA/Startup.cs @@ -10,6 +10,7 @@ using Microsoft.Extensions.Logging; using Microsoft.Extensions.HealthChecks; using Newtonsoft.Json.Serialization; using eShopOnContainers.WebSPA; +using Microsoft.eShopOnContainers.BuildingBlocks; namespace eShopConContainers.WebSPA { @@ -59,10 +60,14 @@ namespace eShopConContainers.WebSPA services.Configure(Configuration); - services.AddDataProtection(opts => + if (Configuration.GetValue("IsClusterEnv") == bool.TrueString) { - opts.ApplicationDiscriminator = "eshop.webspa"; - }); + services.AddDataProtection(opts => + { + opts.ApplicationDiscriminator = "eshop.webspa"; + }) + .PersistKeysToRedis(Configuration["DPConnectionString"]); + } services.AddAntiforgery(options => options.HeaderName = "X-XSRF-TOKEN"); diff --git a/src/Web/WebSPA/WebSPA.csproj b/src/Web/WebSPA/WebSPA.csproj index 6f8678a74..90f2905dd 100644 --- a/src/Web/WebSPA/WebSPA.csproj +++ b/src/Web/WebSPA/WebSPA.csproj @@ -79,6 +79,7 @@ --> +