Exemplo n.º 1
0
    private void DeserializeTokens(
        HttpContext httpContext,
        AntiforgeryTokenSet antiforgeryTokenSet,
        out AntiforgeryToken cookieToken,
        out AntiforgeryToken requestToken)
    {
        var antiforgeryFeature = GetAntiforgeryFeature(httpContext);

        if (antiforgeryFeature.HaveDeserializedCookieToken)
        {
            cookieToken = antiforgeryFeature.CookieToken !;
        }
        else
        {
            cookieToken = _tokenSerializer.Deserialize(antiforgeryTokenSet.CookieToken !);

            antiforgeryFeature.CookieToken = cookieToken;
            antiforgeryFeature.HaveDeserializedCookieToken = true;
        }

        if (antiforgeryFeature.HaveDeserializedRequestToken)
        {
            requestToken = antiforgeryFeature.RequestToken !;
        }
        else
        {
            requestToken = _tokenSerializer.Deserialize(antiforgeryTokenSet.RequestToken !);

            antiforgeryFeature.RequestToken = requestToken;
            antiforgeryFeature.HaveDeserializedRequestToken = true;
        }
    }
Exemplo n.º 2
0
    private void ValidateTokens(HttpContext httpContext, AntiforgeryTokenSet antiforgeryTokenSet)
    {
        Debug.Assert(!string.IsNullOrEmpty(antiforgeryTokenSet.CookieToken));
        Debug.Assert(!string.IsNullOrEmpty(antiforgeryTokenSet.RequestToken));

        // Extract cookie & request tokens
        AntiforgeryToken deserializedCookieToken;
        AntiforgeryToken deserializedRequestToken;

        DeserializeTokens(
            httpContext,
            antiforgeryTokenSet,
            out deserializedCookieToken,
            out deserializedRequestToken);

        // Validate
        if (!_tokenGenerator.TryValidateTokenSet(
                httpContext,
                deserializedCookieToken,
                deserializedRequestToken,
                out var message))
        {
            throw new AntiforgeryValidationException(message);
        }
    }
Exemplo n.º 3
0
        public static string GetAntiforgeryToken(this HttpContext context)
        {
            IAntiforgery        antiforgery = (IAntiforgery)context.RequestServices.GetService(typeof(IAntiforgery));
            AntiforgeryTokenSet tokenSet    = antiforgery.GetAndStoreTokens(context);

            return(tokenSet.RequestToken);
        }
Exemplo n.º 4
0
        public async Task ValidateRequestAsync_FormRequest_NoRequestTokenValue_Throws()
        {
            // Arrange
            var context = CreateMockContext(new AntiforgeryOptions()
            {
                CookieName    = "cookie-name",
                FormFieldName = "form-field-name",
                HeaderName    = "header-name",
            });

            context.HttpContext.Request.ContentType = "application/x-www-form-urlencoded";

            var tokenSet = new AntiforgeryTokenSet(null, "cookie-token", "form-field-name", "header-name");

            context.TokenStore
            .Setup(s => s.GetRequestTokensAsync(context.HttpContext))
            .Returns(Task.FromResult(tokenSet));

            var antiforgery = GetAntiforgery(context);

            // Act & Assert
            var exception = await Assert.ThrowsAsync <AntiforgeryValidationException>(
                () => antiforgery.ValidateRequestAsync(context.HttpContext));

            Assert.Equal(
                "The required antiforgery request token was not provided in either form field \"form-field-name\" " +
                "or header value \"header-name\".",
                exception.Message);
        }
        public override void OnActionExecuted(ActionExecutedContext context)
        {
            var antiforgery            = context.HttpContext.RequestServices.GetService <IAntiforgery>();
            AntiforgeryTokenSet tokens = antiforgery.GetAndStoreTokens(context.HttpContext);

            context.HttpContext.Response.Cookies.Append("XSRF-TOKEN", tokens.RequestToken, new CookieOptions
            {
                HttpOnly = false
            });
        }
Exemplo n.º 6
0
        public IActionResult GetXSRFToken()
        {
            AntiforgeryTokenSet tokens = iAntiForgery.GetAndStoreTokens(HttpContext);

            return(new ObjectResult(new
            {
                token = tokens.RequestToken,
                tokenHeader = tokens.HeaderName
            }));
        }
        public override void OnActionExecuted(ActionExecutedContext context)
        {
            IAntiforgery antiforgery = context.HttpContext.RequestServices.GetService <IAntiforgery>();

            // We can send the request token as a JavaScript-readable cookie, and jquery will use it by default.
            AntiforgeryTokenSet tokens = antiforgery.GetAndStoreTokens(context.HttpContext);

            context.HttpContext.Response.Cookies.Append("XSRF-TOKEN", tokens.RequestToken, new CookieOptions {
                HttpOnly = false
            });
        }
Exemplo n.º 8
0
        GetHtml(HttpContext httpContext, XcstWriter output)
        {
            IAntiforgery antiforgery = GetAntiforgeryService(httpContext);

            AntiforgeryTokenSet tokenSet = antiforgery.GetAndStoreTokens(httpContext);

            output.WriteStartElement("input");
            output.WriteAttributeString("type", "hidden");
            output.WriteAttributeString("name", tokenSet.FormFieldName);
            output.WriteAttributeString("value", tokenSet.RequestToken);
            output.WriteEndElement();
        }
		public override void OnActionExecuted([NotNull] ActionExecutedContext context)
		{
			IAntiforgery antiForgery = context.HttpContext.RequestServices.GetService<IAntiforgery>();
			// We can send the request token as a JavaScript-readable cookie, 
			// and Angular will use it by default.
			AntiforgeryTokenSet tokens = antiForgery?.GetAndStoreTokens(context.HttpContext);
			if (tokens?.RequestToken == null) return;
			context.HttpContext.Response.Cookies.Append(essentialMix.Web.CookieNames.AntiForgeryToken, tokens.RequestToken, new CookieOptions
			{
				HttpOnly = false
			});
		}
Exemplo n.º 10
0
        private AntiforgeryTokenSet SetAntiForgeryTokens()
        {
            IAntiforgery antiforgery = (IAntiforgery)Context.RequestServices.GetService(typeof(IAntiforgery));
            IOptions <AntiforgeryOptions> options = (IOptions <AntiforgeryOptions>)Context.RequestServices.GetService(typeof(IOptions <AntiforgeryOptions>));

            // Save cookie
            AntiforgeryTokenSet tokens = antiforgery.GetAndStoreTokens(Context);

            // Set response header
            Context.Response.Headers[options.Value.FormFieldName] = tokens.RequestToken;

            return(tokens);
        }
Exemplo n.º 11
0
        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IHostingEnvironment env, IAntiforgery antiforgery)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                app.UseExceptionHandler("/Error");
                app.UseHsts();
            }

            /// Add the anti-forgery cookie to the context response
            app.Use(next => context =>
            {
                switch (context.Request.Path.Value)
                {
                case "/":
                    AntiforgeryTokenSet tokens = antiforgery.GetAndStoreTokens(context);
                    context.Response.Cookies.Append(
                        "AntiForgery-TOKEN",
                        tokens.RequestToken,
                        new CookieOptions()
                    {
                        HttpOnly = false
                    });
                    break;
                }
                return(next(context));
            });

            /// App setup to use the following middle-wares
            app.UseAuthentication();
            app.UseHttpsRedirection();
            app.UseStaticFiles();
            app.UseSpaStaticFiles();

            /// User MVC Routes for the api calls
            app.UseMvc();

            app.UseSpa(spa =>
            {
                spa.Options.SourcePath = "ClientApp";
                if (env.IsDevelopment())
                {
                    spa.UseReactDevelopmentServer(npmScript: "start");
                }
            });
        }
Exemplo n.º 12
0
        public static void AddAntiforgeryCookies(this IAntiforgery antiforgery, HttpContext context)
        {
            AntiforgeryTokenSet tokenSet = antiforgery.GetAndStoreTokens(context);

            context.
            Response.
            Cookies.
            Append(
                "XSRF-TOKEN",
                tokenSet.RequestToken,
                new CookieOptions()
            {
                // Allows client side scripts to access cookie
                HttpOnly = false
            });
        }
Exemplo n.º 13
0
        public void GetHtml_RendersInputField()
        {
            // Arrange
            var antiforgery = new Mock<IAntiforgery>(MockBehavior.Strict);
            var tokenSet = new AntiforgeryTokenSet("request-token", "cookie-token", "form-field", "header");
            antiforgery
                .Setup(a => a.GetAndStoreTokens(It.IsAny<HttpContext>()))
                .Returns(tokenSet);

            // Act
            var inputElement = AntiforgeryExtensions.GetHtml(antiforgery.Object, new DefaultHttpContext());

            // Assert
            Assert.Equal(
                @"<input name=""HtmlEncode[[form-field]]"" type=""hidden"" value=""HtmlEncode[[request-token]]"" />",
                HtmlContentUtilities.HtmlContentToString(inputElement));
        }
        public void GetHtml_RendersInputField()
        {
            // Arrange
            var antiforgery = new Mock <IAntiforgery>(MockBehavior.Strict);
            var tokenSet    = new AntiforgeryTokenSet("request-token", "cookie-token", "form-field", "header");

            antiforgery
            .Setup(a => a.GetAndStoreTokens(It.IsAny <HttpContext>()))
            .Returns(tokenSet);

            // Act
            var inputElement = AntiforgeryExtensions.GetHtml(antiforgery.Object, new DefaultHttpContext());

            // Assert
            Assert.Equal(
                @"<input name=""HtmlEncode[[form-field]]"" type=""hidden"" value=""HtmlEncode[[request-token]]"" />",
                HtmlContentUtilities.HtmlContentToString(inputElement));
        }
Exemplo n.º 15
0
        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env, IAntiforgery antiforgery)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            app.UseCors("EnableCORS");
            app.UseHttpsRedirection();

            app.UseRouting();

            app.UseAuthorization();

            /* Configure the app to provide a token in a cookie called XSRF-TOKEN */

            /* Custom Middleware Component is required to Set the cookie which is named XSRF-TOKEN
             * The Value for this cookie is obtained from IAntiForgery service
             * We must configure this cookie with HttpOnly option set to false so that browser will allow JS to read this cookie
             */
            app.Use(nextDelegate => context =>
            {
                string path         = context.Request.Path.Value.ToLower();
                string[] directUrls = { "/admin", "/store", "/cart", "checkout", "/login" };
                if (path.StartsWith("/swagger") || path.StartsWith("/api") || string.Equals("/", path) || directUrls.Any(url => path.StartsWith(url)))
                {
                    AntiforgeryTokenSet tokens = antiforgery.GetAndStoreTokens(context);
                    context.Response.Cookies.Append("XSRF-TOKEN", tokens.RequestToken, new CookieOptions()
                    {
                        HttpOnly    = false,
                        Secure      = false,
                        IsEssential = true,
                        SameSite    = SameSiteMode.Strict
                    });
                }

                return(nextDelegate(context));
            });

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllers();
            });
        }
Exemplo n.º 16
0
        private void SetAntiforgeryCookie()
        {
            CookieOptions antiForgeryCookieOptions = new CookieOptions()
            {
                HttpOnly = false,
                SameSite = SameSiteMode.Lax,
                Secure   = true,
            };

            if (_WebHostingEnv.IsProduction())
            {
                antiForgeryCookieOptions.Domain = AppConst.Settings.AppDomains.AntiforgeryCookieDomain;
            }
            AntiforgeryTokenSet tokens = _Antiforgery.GetAndStoreTokens(HttpContext);

            Response.Cookies.Append(
                "AF-TOKEN",
                tokens.RequestToken,
                antiForgeryCookieOptions);
        }
Exemplo n.º 17
0
    private bool TryDeserializeTokens(
        HttpContext httpContext,
        AntiforgeryTokenSet antiforgeryTokenSet,
        [NotNullWhen(true)] out AntiforgeryToken?cookieToken,
        [NotNullWhen(true)] out AntiforgeryToken?requestToken)
    {
        try
        {
            DeserializeTokens(httpContext, antiforgeryTokenSet, out cookieToken, out requestToken);
            return(true);
        }
        catch (AntiforgeryValidationException ex)
        {
            _logger.FailedToDeserialzeTokens(ex);

            cookieToken  = null;
            requestToken = null;
            return(false);
        }
    }
        public async override void OnActionExecuting(ActionExecutingContext context)
        {
            IAntiforgery        antiforgery = (IAntiforgery)context.HttpContext.RequestServices.GetService(typeof(IAntiforgery));
            AntiforgeryTokenSet tokens      = antiforgery.GetAndStoreTokens(context.HttpContext);

            if (!context.HttpContext.Request.Form.ContainsKey(tokens.FormFieldName))
            {
                return;
            }
            var currentFormId = context.HttpContext.Request.Form[tokens.FormFieldName].ToString();
            var lastToken     = "" + context.HttpContext.Session.GetString(UniqFormuId);

            if (lastToken.Equals(currentFormId))
            {
                context.ModelState.AddModelError(string.Empty, $"{DateTime.Now.ToShortTimeString()}--重复提交");
                return;
            }
            context.HttpContext.Session.Remove(UniqFormuId);
            context.HttpContext.Session.SetString(UniqFormuId, currentFormId);
            await context.HttpContext.Session.CommitAsync();
        }
    public override async void OnActionExecuting(ActionExecutingContext context)
    {
        IAntiforgery        antiforgery = (IAntiforgery)context.HttpContext.RequestServices.GetService(typeof(IAntiforgery));
        AntiforgeryTokenSet tokens      = antiforgery.GetAndStoreTokens(context.HttpContext);

        if (!context.HttpContext.Request.Form.ContainsKey(tokens.FormFieldName))
        {
            return;
        }

        var currentFormId = context.HttpContext.Request.Form[tokens.FormFieldName].ToString();
        var lastToken     = "" + context.HttpContext.Session.GetString(UniqFormuId);

        if (lastToken.Equals(currentFormId))
        {
            context.ModelState.AddModelError(string.Empty, "Looks like you accidentally submitted the same form twice.");
            return;
        }
        context.HttpContext.Session.Remove(UniqFormuId);
        context.HttpContext.Session.SetString(UniqFormuId, currentFormId);
        await context.HttpContext.Session.CommitAsync();
    }
Exemplo n.º 20
0
        /// <inheritdoc />
        public void GetAndStoreTokens(HttpContext httpContext)
        {
            AntiforgeryTokenSet set = _internalAntiForgery.GetAndStoreTokens(httpContext);

            if (set.RequestToken == null)
            {
                throw new InvalidOperationException("Could not resolve a request token.");
            }

            // We need to set 2 cookies:
            // The cookie value that angular will use to set a header value on each request - we need to manually set this here
            // The validation cookie value generated by the anti-forgery helper that we validate the header token against - set above in GetAndStoreTokens
            httpContext.Response.Cookies.Append(
                Constants.Web.AngularCookieName,
                set.RequestToken,
                new CookieOptions
            {
                Path = "/",
                //must be js readable
                HttpOnly = false,
                Secure   = _globalSettings.UseHttps
            });
        }
Exemplo n.º 21
0
        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env, IAntiforgery antiforgery)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            app.UseCors("EnableCORS");
            app.UseHttpsRedirection();

            app.UseRouting();

            app.UseAuthorization();

            app.Use(nextDelegate => context =>
            {
                string path         = context.Request.Path.Value.ToLower();
                string[] directUrls = { "/admin", "/store", "/cart", "checkout", "/login" };
                if (path.StartsWith("/swagger") || path.StartsWith("/api") || string.Equals("/", path) || directUrls.Any(url => path.StartsWith(url)))
                {
                    AntiforgeryTokenSet tokens = antiforgery.GetAndStoreTokens(context);
                    context.Response.Cookies.Append("XSRF-TOKEN", tokens.RequestToken, new CookieOptions()
                    {
                        HttpOnly    = false,
                        Secure      = false,
                        IsEssential = true,
                        SameSite    = SameSiteMode.Strict
                    });
                }

                return(nextDelegate(context));
            });

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllers();
            });
        }
Exemplo n.º 22
0
        public async Task ValidateRequestAsync_NonFormRequest_HeaderDisabled_Throws()
        {
            // Arrange
            var context = CreateMockContext(new AntiforgeryOptions()
            {
                CookieName    = "cookie-name",
                FormFieldName = "form-field-name",
                HeaderName    = null,
            });

            var tokenSet = new AntiforgeryTokenSet(null, "cookie-token", "form-field-name", null);

            context.TokenStore
            .Setup(s => s.GetRequestTokensAsync(context.HttpContext))
            .Returns(Task.FromResult(tokenSet));

            var antiforgery = GetAntiforgery(context);

            // Act & Assert
            var exception = await Assert.ThrowsAsync <AntiforgeryValidationException>(
                () => antiforgery.ValidateRequestAsync(context.HttpContext));

            Assert.Equal("The required antiforgery form field \"form-field-name\" is not present.", exception.Message);
        }
Exemplo n.º 23
0
        public async Task Invoke(HttpContext httpContext, IAntiforgery antiforgery)
        {
            string path = httpContext.Request.Path.Value;

            if (httpContext.Request.Method == HttpMethods.Get &&
                (
                    string.Equals(path, "/", StringComparison.OrdinalIgnoreCase) ||
                    string.Equals(path, "/index.html", StringComparison.OrdinalIgnoreCase) ||
                    string.Equals(path, "/login", StringComparison.OrdinalIgnoreCase) ||
                    string.Equals(path, "/index-login.html", StringComparison.OrdinalIgnoreCase)
                ))
            {
                // The request token can be sent as a JavaScript-readable cookie,
                // and Angular uses it by default.
                AntiforgeryTokenSet tokens = antiforgery.GetAndStoreTokens(httpContext);
                httpContext.Response.Cookies.Append(_clientCookieName,
                                                    tokens.RequestToken,
                                                    new CookieOptions {
                    HttpOnly = false
                });
            }

            await _next(httpContext);
        }
Exemplo n.º 24
0
 public InputContent(AntiforgeryTokenSet tokenSet)
 {
     _fieldName    = tokenSet.FormFieldName;
     _requestToken = tokenSet.RequestToken !;
 }
Exemplo n.º 25
0
        private void DeserializeTokens(
            HttpContext httpContext,
            AntiforgeryTokenSet antiforgeryTokenSet,
            out AntiforgeryToken cookieToken,
            out AntiforgeryToken requestToken)
        {
            var antiforgeryFeature = GetAntiforgeryFeature(httpContext);

            if (antiforgeryFeature.HaveDeserializedCookieToken)
            {
                cookieToken = antiforgeryFeature.CookieToken;
            }
            else
            {
                cookieToken = _tokenSerializer.Deserialize(antiforgeryTokenSet.CookieToken);

                antiforgeryFeature.CookieToken = cookieToken;
                antiforgeryFeature.HaveDeserializedCookieToken = true;
            }

            if (antiforgeryFeature.HaveDeserializedRequestToken)
            {
                requestToken = antiforgeryFeature.RequestToken;
            }
            else
            {
                requestToken = _tokenSerializer.Deserialize(antiforgeryTokenSet.RequestToken);

                antiforgeryFeature.RequestToken = requestToken;
                antiforgeryFeature.HaveDeserializedRequestToken = true;
            }
        }
Exemplo n.º 26
0
        private void ValidateTokens(HttpContext httpContext, AntiforgeryTokenSet antiforgeryTokenSet)
        {
            Debug.Assert(!string.IsNullOrEmpty(antiforgeryTokenSet.CookieToken));
            Debug.Assert(!string.IsNullOrEmpty(antiforgeryTokenSet.RequestToken));

            // Extract cookie & request tokens
            AntiforgeryToken deserializedCookieToken;
            AntiforgeryToken deserializedRequestToken;
            DeserializeTokens(
                httpContext,
                antiforgeryTokenSet,
                out deserializedCookieToken,
                out deserializedRequestToken);

            // Validate
            string message;
            if (!_tokenGenerator.TryValidateTokenSet(
                httpContext,
                deserializedCookieToken,
                deserializedRequestToken,
                out message))
            {
                throw new AntiforgeryValidationException(message);
            }
        }
Exemplo n.º 27
0
        public AntiforgeryTokenSet GetAndStoreTokens(HttpContext httpContext)
        {
            var result = new AntiforgeryTokenSet("requestToken", "cookieToken", "test", "test");

            return(result);
        }
Exemplo n.º 28
0
        private BankIdLoginViewModel GetLoginViewModel(string returnUrl, string loginOptions, BankIdLoginOptions unprotectedLoginOptions, AntiforgeryTokenSet antiforgeryTokens)
        {
            var loginScriptOptions = new BankIdLoginScriptOptions
            {
                RefreshIntervalMs = BankIdAuthenticationDefaults.StatusRefreshIntervalMs,

                InitialStatusMessage = _bankIdUserMessageLocalizer.GetLocalizedString(MessageShortName.RFA13),
                UnknownErrorMessage  = _bankIdUserMessageLocalizer.GetLocalizedString(MessageShortName.RFA22),

                UnsupportedBrowserErrorMessage = _localizer["UnsupportedBrowser_ErrorMessage"],

                BankIdInitializeApiUrl = Url.Action(nameof(BankIdApiController.InitializeAsync), "BankIdApi"),
                BankIdStatusApiUrl     = Url.Action(nameof(BankIdApiController.StatusAsync), "BankIdApi")
            };

            return(new BankIdLoginViewModel
            {
                ReturnUrl = returnUrl,

                AutoLogin = unprotectedLoginOptions.IsAutoLogin(),
                PersonalIdentityNumber = unprotectedLoginOptions.PersonalIdentityNumber?.To12DigitString() ?? string.Empty,

                LoginOptions = loginOptions,
                UnprotectedLoginOptions = unprotectedLoginOptions,

                AntiXsrfRequestToken = antiforgeryTokens.RequestToken,
                LoginScriptOptions = loginScriptOptions,
                LoginScriptOptionsJson = SystemRuntimeJsonSerializer.Serialize(loginScriptOptions)
            });
        }
Exemplo n.º 29
0
 static public string XsrfToXpt(AntiforgeryTokenSet xpt) => Serialize(new
 {
     __xpt_cookie      = xpt.CookieToken,
     __xpt_request     = xpt.RequestToken,
     __xpt_header_name = xpt.HeaderName
 });
Exemplo n.º 30
0
        private BankIdLoginViewModel GetLoginViewModel(string returnUrl, string loginOptions, BankIdLoginOptions unprotectedLoginOptions, AntiforgeryTokenSet antiforgeryTokens)
        {
            var initialStatusMessage = GetInitialStatusMessage(unprotectedLoginOptions);
            var loginScriptOptions   = new BankIdLoginScriptOptions(
                Url.Action("Initialize", "BankIdApi"),
                Url.Action("Status", "BankIdApi"),
                Url.Action("Cancel", "BankIdApi")
                )
            {
                RefreshIntervalMs = BankIdDefaults.StatusRefreshIntervalMs,

                InitialStatusMessage = _bankIdUserMessageLocalizer.GetLocalizedString(initialStatusMessage),
                UnknownErrorMessage  = _bankIdUserMessageLocalizer.GetLocalizedString(MessageShortName.RFA22),

                UnsupportedBrowserErrorMessage = _localizer["UnsupportedBrowser_ErrorMessage"]
            };

            return(new BankIdLoginViewModel(
                       returnUrl,
                       Url.Content(unprotectedLoginOptions.CancelReturnUrl),
                       unprotectedLoginOptions.IsAutoLogin(),
                       unprotectedLoginOptions.PersonalIdentityNumber?.To12DigitString() ?? string.Empty,
                       loginOptions,
                       unprotectedLoginOptions,
                       loginScriptOptions,
                       SystemRuntimeJsonSerializer.Serialize(loginScriptOptions),
                       antiforgeryTokens.RequestToken
                       ));
        }
Exemplo n.º 31
0
        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(
            IApplicationBuilder app,
            IWebHostEnvironment env,
            IAntiforgery antiforgery)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                app.UseExceptionHandler("/Error");
                // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
                app.UseHsts();
            }

            app.UseHttpsRedirection();

            app.UseCors("EnableCORS");

            app.UseStaticFiles();
            if (!env.IsDevelopment())
            {
                app.UseSpaStaticFiles();
            }

            app.UseRouting();

            // [Authorize]
            app.UseAuthorization();

            // [ValidateAntiForgeryToken]
            // [AutoValidateAntiforgeryToken]
            app.Use(nextDelegate => context =>
            {
                string path         = context.Request.Path.Value.ToLower();
                string[] directUrls =
                {
                    "/admin",
                    "/store",
                    "/cart",
                    "checkout",
                    "/login"
                };
                if (path.StartsWith("/swagger") ||
                    path.StartsWith("/api") ||
                    string.Equals("/", path) ||
                    directUrls.Any(url => path.StartsWith(url)))
                {
                    AntiforgeryTokenSet tokens = antiforgery.GetAndStoreTokens(context);
                    context.Response.Cookies.Append(
                        "XSRF-TOKEN",
                        tokens.RequestToken,
                        new CookieOptions()
                    {
                        HttpOnly    = false,
                        Secure      = false,
                        IsEssential = true,
                        SameSite    = SameSiteMode.Strict
                    }
                        );
                }
                return(nextDelegate(context));
            });

            app.UseEndpoints(endpoints =>
            {
                // * Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation 3.1.5
                endpoints.MapControllerRoute(
                    name: "areas",
                    pattern: "{area:exists}/{controller=Home}/{action=Index}/{id?}");

                endpoints.MapControllerRoute(
                    name: "default",
                    pattern: "{controller}/{action=Index}/{id?}");
            });

            app.UseSpa(spa =>
            {
                // To learn more about options for serving an Angular SPA from ASP.NET Core,
                // see https://go.microsoft.com/fwlink/?linkid=864501

                spa.Options.SourcePath = "ClientApp";

                if (env.IsDevelopment())
                {
                    spa.UseAngularCliServer(npmScript: "start");
                }
            });
        }