首页 > 解决方案 > 动态cookie认证LoginPath asp.net core 2

问题描述

我需要动态更改 LaginPath。我的项目中有一种自定义文化。如果语言是英语,LoginPath="/Login" 如果语言是土耳其语,LoginPath="/Oturum-Ac"

如何动态更改 LoginPath

你能给我代码示例如何在 CustomCulture 中覆盖/更改 CookieAuthenticationOptions

using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Localization;
using Microsoft.EntityFrameworkCore;
using ECommerce.Entity;
using ECommerce.Repository.Abstract;
using System;
using System.Globalization;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using ECommerce.WebUI.Infrastructure;
using System.IO;
using System.Text;
using ECommerce.WebUI.Areas.Admin.Infrastructure;
using System.Net;
using System.Collections.Generic;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Configuration;
using Microsoft.AspNetCore.Identity;

namespace ECommerce.WebUI.Infrastructure
{
    public class CustomCulture
    {
        private readonly RequestDelegate _next;
        private readonly ILogger<CustomCulture> _logger;

        public CustomCulture(RequestDelegate next, ILogger<CustomCulture> logger)
        {
            _next = next;
            _logger = logger;

        }

        public async Task InvokeAsync(HttpContext context)
        {
            int languageId = context.Session.GetJSon<int>("LanguageId");
            var unitOfWork = (IUnitOfWork)context.RequestServices.GetService(typeof(IUnitOfWork));
            var test = (CookieAuthenticationOptions)context.RequestServices.GetService(typeof(CookieAuthenticationOptions));
            //test.LoginPath = "/NewLoginPath";
            var requestPath = context.Request.Path.Value;
            if (!string.IsNullOrEmpty(requestPath) && requestPath[0] == '/')
            {
                requestPath = requestPath.Substring(1);
            }
            var segments = requestPath.Split('/');

            string firstSegment = segments[0] ?? "";
            var set = false;
            Language Language = null;

            //check cookie 
            var locOptions = (IOptions<RequestLocalizationOptions>)context.RequestServices.GetService(typeof(IOptions<RequestLocalizationOptions>));
            if (string.IsNullOrEmpty(locOptions.Value.DefaultRequestCulture.Culture.Name))
            {
                languageId = 0;
            }

            if (firstSegment != "" && firstSegment.ToLower() != "admin" && firstSegment != "GetJsonList")
            {
                var getReturnUrlSegments = WebUtility.UrlDecode(WebUtility.UrlDecode(context.Request.QueryString.ToUriComponent().ToLower())).Split('/');
                var pageUrl = WebUtility.UrlDecode(getReturnUrlSegments[getReturnUrlSegments.Length - 1]);//last part of returnUrl 

                _logger.LogTrace($"CustomCulture - set FromUrl : {pageUrl}");

                Language = unitOfWork.Pages.GetAll().Include(i => i.Language)
                                                    .Where(i => i.PageRoot.RootName.ToLower() == segments[0].ToLower() ||
                                                                i.Url.ToLower() == segments[0].ToLower() ||
                                                                i.Url.ToLower() == pageUrl).FirstOrDefault().Language;
                if (Language != null)
                {
                    if (Language.LanguageId != languageId)
                    {
                        languageId = Language.LanguageId;
                        set = true; //set cookie and sesion
                    }
                }

                #region SET GetLogin GetLogout GetAccessDenied

                if (segments[0] == "GetLogin" || segments[0] == "GetLogout" || segments[0] == "GetAccessDenied")
                {
                    var returnUrlSegments = WebUtility.UrlDecode(WebUtility.UrlDecode(context.Request.QueryString.ToUriComponent().ToLower()))
                                                                .Split("returnurl=");
                    //find how many returnUrl with returnUrlSegments.Length - 1
                    var setReturnUrl = returnUrlSegments[returnUrlSegments.Length - 1];
                    returnUrlSegments = setReturnUrl.Substring(1).Split('/');
                    ///////////
                    var page = unitOfWork.Pages.GetAll().Include(i => i.PageRoot).ThenInclude(i => i.Language)
                                                    .Where(i => i.IsApproved && i.Language.IsApproved &&
                                                                i.LanguageId == languageId &&
                                                                i.PageRoot.ControllerName == "Account" &&
                                                                i.PageRoot.ActionName == segments[0].Replace("Get", "")).FirstOrDefault();

                    var redirectUrl = "/" + page.PageRoot.RootName + "/" + page.Url + "?ReturnUrl=" + setReturnUrl;

                    context.Response.Redirect(redirectUrl);
                    return;
                }

                #endregion
            }

            #region SET DEFAULT CULTURE

            if (languageId == 0)
            {
                var cultureFromBrowser = Thread.CurrentThread.CurrentCulture.ToString();
                if (Language == null)
                {
                    Language = unitOfWork.Languages.GetAll().Where(i => i.Culture == cultureFromBrowser &&
                                                                        i.IsApproved)
                                                            .FirstOrDefault();
                    if (Language == null)
                    {
                        Language = unitOfWork.Languages.GetAll()
                                            .Where(i => i.ShortLang == cultureFromBrowser.Substring(0, 2) &&
                                                        i.IsApproved)
                                            .FirstOrDefault();
                        if (Language == null)
                        {
                            Language = unitOfWork.Languages.GetAll()
                                           .Where(i => i.IsApproved).OrderBy(i => i.SortOrder)
                                           .FirstOrDefault();
                        }
                    }
                    set = true; //set cookie and sesion
                }
            }

            #endregion

            #region SET COOKIE AND SESSION

            if (set)
            {
                _logger.LogTrace($"CustomCulture - set CULTURE/SESSION/CULTURE COOKIE/CURRENCY COOKIE");

                //SET CULTURE
                var culture = new CultureInfo(Language.Culture);
                CultureInfo.CurrentCulture = culture;
                CultureInfo.CurrentUICulture = culture;

                //SET SESSION
                context.Session.SetJson("LanguageId", Language.LanguageId);
                context.Session.SetJson("Culture", Language.Culture);
                context.Session.SetJson("SettingLanguageId", Language.LanguageId);
                //SET CULTURE COOKIE
                context.Response.Cookies.Append(CookieRequestCultureProvider.DefaultCookieName,
                            CookieRequestCultureProvider.MakeCookieValue(new RequestCulture(Language.Culture)),
                            new CookieOptions { Expires = DateTimeOffset.UtcNow.AddYears(1) });

                //SET CURRENCY COOKİE
                context.Response.Cookies.Append("CurrencyId", Language.CurrencyId.ToString(),
                                                    new CookieOptions { Expires = DateTimeOffset.UtcNow.AddYears(1) });
            }

            #endregion

            _logger.LogInformation($"CustomCulture -  languageId : {languageId}");

            await this._next(context);

        }
    }
}

标签: asp.net-core

解决方案


一种解决方法是您可以CookieAuthenticationEvents使用上面的代码实现自定义并更改 RedirectUri:

public class MyCookieAuthenticationEvents : CookieAuthenticationEvents
{
    public override Task RedirectToLogin(RedirectContext<CookieAuthenticationOptions> redirectContext)
    {
        //get HttpContext
        var context = redirectContext.HttpContext;
        //your above logic omitted
        //...
        redirectContext.RedirectUri = "Your new url";
        return base.RedirectToLogin(redirectContext);
    }
}

在 startup.cs 中注册

services.ConfigureApplicationCookie(options =>
        {
           //...
            options.LoginPath = "/GetLogin";
            options.LogoutPath = "/GetLogout";
            options.AccessDeniedPath = "/GetAccessDenied";
            options.SlidingExpiration = true;
            options.EventsType = typeof(MyCookieAuthenticationEvents);
        });
services.AddScoped<MyCookieAuthenticationEvents>();

推荐阅读