.NET Core 2.0 Cookie事件OnRedirectToLogin [英] .NET Core 2.0 Cookie Events OnRedirectToLogin

查看:274
本文介绍了.NET Core 2.0 Cookie事件OnRedirectToLogin的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何在Cookie选项中将中间件应用于OnRedirectToLogin事件(以便可以使用依赖项注入),或者如何从RedirectContext检索actionContext?我曾尝试搜索文档或示例,但是很难找到,也没有看到任何示例解释或定义方法.这有可能吗?

How can I apply a middleware to the OnRedirectToLogin event in Cookie options (so i can use dependency injection), OR how can I retrieve actionContext from RedirectContext? I have tried searching for documentation or examples, but it is hard to find, and I have not seen any examples explaining or defining how. Is this even possible?

我的Startup.cs

my Startup.cs

services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
                .AddCookie(o =>
                {
                    o.AccessDeniedPath = new PathString("/Error/AccessDenied");
                    o.LoginPath = new PathString("/Account/Login/");
                    o.Cookie.Path = "/";
                    o.Cookie.SecurePolicy = CookieSecurePolicy.SameAsRequest;
                    o.Cookie.HttpOnly = true;
                    o.LogoutPath = new PathString("/Account/Logout/");
                    o.Events.OnRedirectToLogin = (context) =>
                    {
                        var routeData = context.HttpContext.GetRouteData();
                        RouteValueDictionary routeValues = new RouteValueDictionary();
                        if (routeData != null) routeValues.Add("lang", routeData.Values["lang"]);
                        Uri uri = new Uri(context.RedirectUri);
                        string returnUrl = HttpUtility.ParseQueryString(uri.Query)[context.Options.ReturnUrlParameter];
                        string focustab = "";
                        context.Request.Query.ToList().ForEach(x =>
                        {
                            if (x.Key == "id") routeValues.Add("id", x.Value.FirstOrDefault());
                            if (x.Key == "values") routeValues.Add("values", x.Value.FirstOrDefault());

                        });

                        routeValues.Add(context.Options.ReturnUrlParameter, returnUrl + focustab);

                        //context here is a redirect context, how can i get the action context to create a new Action as what UrlHelper is expecting
                        context.RedirectUri = new UrlHelper(context).Action("login", "account", routeValues);
                        return Task.CompletedTask;
                    };
                });

谢谢.

推荐答案

我能够按需运行它,因此,我发布了答案,以防其他人遇到此问题.借助此文档:在没有ASP.NET的情况下使用Cookie身份验证核心身份.我实现了CustomCookieAuthenticationEvents并将其强制转换为Cookie事件的类型.

I was able to get it working as I wanted, so I am posting my answer in case anyone else comes across this question. With the help of this documentation: Use cookie authentication without ASP.NET Core Identity. I implemented the CustomCookieAuthenticationEvents and casted that as the type for the Cookie events.

services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
    .AddCookie(o =>
    {
        o.AccessDeniedPath = new PathString("/Error/AccessDenied");
        o.LoginPath = new PathString("/Account/Login/");
        o.Cookie.Path = "/";
        o.Cookie.SecurePolicy = CookieSecurePolicy.SameAsRequest;
        o.Cookie.HttpOnly = true;
        o.LogoutPath = new PathString("/Account/Logout/");
        //This line here
        o.EventsType = typeof(CustomCookieAuthenticationEvents);
    });

//register the IActionContextAccessor so that I can inject into my CustomCookieAuthenticationEvents constructor
services.AddSingleton<IActionContextAccessor, ActionContextAccessor>();

然后在该Custom类中,我可以注入IUrlHelperFactoryIActionContextAccessor,这有助于我为当前操作创建新的UrlHelper.

Then inside that Custom class, I was able to inject IUrlHelperFactory and IActionContextAccessor which helps me create new UrlHelper for the current action.

public class CustomCookieAuthenticationEvents : CookieAuthenticationEvents
{
    private IUrlHelperFactory _helper;
    private IActionContextAccessor _accessor;
    public CustomCookieAuthenticationEvents(IUrlHelperFactory helper, IActionContextAccessor accessor)
    {
        _helper = helper;
        _accessor = accessor;
    }
    public override Task RedirectToLogin(RedirectContext<CookieAuthenticationOptions> context)
    {
        var routeData = context.Request.HttpContext.GetRouteData();
        RouteValueDictionary routeValues = new RouteValueDictionary();
        //Create new routeValues based on routeData above
        ... code removed for brevity
        Uri uri = new Uri(context.RedirectUri);
        string returnUrl = HttpUtility.ParseQueryString(uri.Query)[context.Options.ReturnUrlParameter];

        routeValues.Add(context.Options.ReturnUrlParameter, returnUrl + focustab);
        var urlHelper = _helper.GetUrlHelper(_accessor.ActionContext);
        context.RedirectUri = UrlHelperExtensions.Action(urlHelper, "login", "account", routeValues);
        return base.RedirectToLogin(context);
    }
}

这使我可以修改重定向到登录"请求上的查询字符串和returnUrl参数.我的要求是在首次登录时删除特定的查询字符串值,这可以满足我的需求.

This allows me to modify the query string and returnUrl parameter on Redirect to Login requests. My requirement was to remove a specific query string value on first request to Login, and this allows me to meet that need.

注释中指出在.net Core 3.1中ActionContext为空.我创建了一个新的.net core 3.1项目,这是确保ActionContext不为null的新代码.还没有完全测试,只需确保ActionContext对于注入IActionContextAccessor不为null.

It was pointed out in the comments that ActionContext is null in .net Core 3.1. I created a new .net core 3.1 project and this is the new code to make sure ActionContext is NOT null. Have not fully tested, just made sure the ActionContext was not null for inject IActionContextAccessor.

这里要记住的主要事情是IActionContextAccessor与MVC管道一起使用.这意味着我们必须更改.net core 3.1模板才能使用MVC. CustomCookieAuthenticationEvents不会更改.

The main thing to remember here is that IActionContextAccessor works with the MVC pipeline. This means we would have to change the .net core 3.1 template to use MVC. CustomCookieAuthenticationEvents does not change.

New Startup.cs

New Startup.cs

public void ConfigureServices(IServiceCollection services)
    {
        services.AddMvc(m =>
        {
            m.EnableEndpointRouting = false;
        });
        //register the IActionContextAccessor so that I can inject into my CustomCookieAuthenticationEvents constructor
        services.AddSingleton<IActionContextAccessor, ActionContextAccessor>();
        services.AddScoped<CustomCookieAuthenticationEvents>();
        services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
        .AddCookie(o =>
        {
            o.AccessDeniedPath = new PathString("/Error/AccessDenied");
            o.LoginPath = new PathString("/Account/Login/");
            o.Cookie.Path = "/";
            o.Cookie.SecurePolicy = CookieSecurePolicy.SameAsRequest;
            o.Cookie.HttpOnly = true;
            o.LogoutPath = new PathString("/Account/Logout/");
            //This line here
            o.EventsType = typeof(CustomCookieAuthenticationEvents);
        });

    }

    // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }
        else
        {
            app.UseExceptionHandler("/Home/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.UseStaticFiles();

        //app.UseRouting();

        app.UseAuthorization();

        app.UseMvcWithDefaultRoute();

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

这篇关于.NET Core 2.0 Cookie事件OnRedirectToLogin的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆