Suppress redirect on API URLs in ASP.NET Core

前端 未结 3 1089
名媛妹妹
名媛妹妹 2020-12-09 17:08

I have an ASP.NET Core site that uses cookie authentication for most pages. For those pages, the default server response of providing a 302 redirect for an unauthorized clie

相关标签:
3条回答
  • 2020-12-09 17:39

    Replace the redirect event handler with one that uses the default behavior only if the path is not an API. In Startup.ConfigureServices, add this:

    services.ConfigureApplicationCookie(options => {
        options.Events.OnRedirectToAccessDenied = ReplaceRedirector(HttpStatusCode.Forbidden, options.Events.OnRedirectToAccessDenied);
        options.Events.OnRedirectToLogin = ReplaceRedirector(HttpStatusCode.Unauthorized, options.Events.OnRedirectToLogin);
    });
    

    Use this helper method to replace the redirect methods:

    static Func<RedirectContext<CookieAuthenticationOptions>, Task> ReplaceRedirector(HttpStatusCode statusCode, Func<RedirectContext<CookieAuthenticationOptions>, Task> existingRedirector) =>
        context => {
            if (context.Request.Path.StartsWithSegments("/api")) {
                context.Response.StatusCode = (int)statusCode;
                return Task.CompletedTask;
            }
            return existingRedirector(context);
        };
    

    With this in place, the API controller methods can call Unauthorized() and Forbid() without causing redirects.

    Update: The above is for ASP.NET Core 2. The code for ASP.NET Core 1 is different.

    0 讨论(0)
  • 2020-12-09 17:40

    For .net core 2.x here's a fix (based on Edward's answer) :

    services.ConfigureApplicationCookie(options =>
            {
                options.Events = new CookieAuthenticationEvents
                {
                    OnRedirectToAccessDenied = ReplaceRedirector(HttpStatusCode.Forbidden, context => options.Events.RedirectToAccessDenied(context)),
                    OnRedirectToLogin = ReplaceRedirector(HttpStatusCode.Unauthorized, context => options.Events.RedirectToLogin(context))
                };
            });
    

    where ReplaceRedirector:

    Func<RedirectContext<CookieAuthenticationOptions>, Task> ReplaceRedirector(HttpStatusCode statusCode, Func<RedirectContext<CookieAuthenticationOptions>, Task> existingRedirector) =>
    context =>
    {
        if (context.Request.Path.StartsWithSegments("/api"))
        {
            context.Response.StatusCode = (int)statusCode;
            return Task.CompletedTask;
        }
        return existingRedirector(context);
    };
    
    0 讨论(0)
  • 2020-12-09 17:41

    Other simple way

     .AddCookie(options =>
                {
                    options.AccessDeniedPath = "/Home/401";
                    options.Events = new CookieAuthenticationEvents
                    {
                        OnRedirectToAccessDenied = context => 
                        {
                            if (context.Request.Path.StartsWithSegments("/api"))
                            {
                                context.Response.StatusCode = (int)(HttpStatusCode.Unauthorized);
                            }
                            return Task.CompletedTask;
                        },
                    };
                })
    
    0 讨论(0)
提交回复
热议问题