mvc6 unauthorized results in redirect instead

非 Y 不嫁゛ 提交于 2019-12-09 05:27:56

问题


I have been trying to prevent the redirect when I return an NotAuthorized IActionResult from a Controller, but regardless of my attempts, NotAuthorized gets translated to a Redirect.

I have tried what is mentioned here (same issue, using older beta framework, I use 1.0.0-rc1-final). I do not have the Notifications namespace (has been removed in rc1-final).

This is my Login Controller:

    [HttpPost]
    [AllowAnonymous]
    public async Task<IActionResult> Login(LoginViewModel model, string returnUrl = null)
    {
        if (ModelState.IsValid)
        {
            var result = await _signInManager.PasswordSignInAsync(model.Email, model.Password, model.RememberMe, lockoutOnFailure: false);
            if (result.Succeeded)
            {
                return Ok(model);
            }
            if (result.IsLockedOut)
            {
                return new HttpStatusCodeResult((int)HttpStatusCode.Forbidden);
            }
            else
            {
                return HttpUnauthorized();
            }
        }
        return HttpUnauthorized();
    }

In Startup.cs I have tried variations over this:

        services.Configure<CookieAuthenticationOptions>(o =>
        {
            o.LoginPath = PathString.Empty;
            o.ReturnUrlParameter = PathString.Empty;
            o.AutomaticChallenge = false;
        });

Everytime a login fails (please ignore that the password is returned on Ok) and should result in an empty 401 page, I get a redirection to /Account/Login instead. What is the trick here?


回答1:


The solution is not to configure CookieAuthenticationOptions directly, but do it via IdentityOptions like this:

        services.Configure<IdentityOptions>(o =>
        {
            o.Cookies.ApplicationCookie.Events = new CookieAuthenticationEvents()
            {
                OnRedirectToLogin = ctx =>
                {
                    if (ctx.Response.StatusCode == (int)HttpStatusCode.Unauthorized)
                    {
                        return Task.FromResult<object>(null);
                    }
                    ctx.Response.Redirect(ctx.RedirectUri);
                    return Task.FromResult<object>(null);
                }
            };
        });



回答2:


Taken from here ( Shawn Wildermuth --> ASP.NET 5 Identity and REST APIs --> Comment of "Mehdi Hanafi") and tested the API with Postman

config.Cookies.ApplicationCookie.Events = new CookieAuthenticationEvents()
{
    OnRedirectToLogin = ctx =>
    {
        if (ctx.Request.Path.StartsWithSegments("/api") &&
        ctx.Response.StatusCode == 200)
        {
            ctx.Response.StatusCode = (int)HttpStatusCode.Unauthorized;
            return Task.FromResult<object>(null);
        }
        else
        {
            ctx.Response.Redirect(ctx.RedirectUri);
            return Task.FromResult<object>(null);
        }
    }
};



回答3:


from Identity 2.0, you'd need to add:

using Microsoft.AspNetCore.Authentication.Cookies;

and in ConfigureServices:

services.ConfigureApplicationCookie(options =>
{
    options.Events = new CookieAuthenticationEvents
    {
        OnRedirectToLogin = (x =>
        {
            if (x.Request.Path.StartsWithSegments("/api") && x.Response.StatusCode == 200)
                x.Response.StatusCode = 401;

            return Task.CompletedTask;
        }),
        OnRedirectToAccessDenied = (x =>
        {
            if (x.Request.Path.StartsWithSegments("/api") && x.Response.StatusCode == 200)
                x.Response.StatusCode = 403;

            return Task.CompletedTask;
        })
    };
});

the segments check should of course be adjusted to your routes.




回答4:


If you have some pages for which the redirect is desired and other URLs that should not have a redirect, see this question for a solution that uses the default redirect logic only for non-API URLs:

Suppress redirect on API URLs in ASP.NET Core



来源:https://stackoverflow.com/questions/34770886/mvc6-unauthorized-results-in-redirect-instead

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!