MVC6中未授权的结果会被重定向

9

我一直在尝试防止在控制器返回NotAuthorized IActionResult时重定向,但是无论我如何尝试,NotAuthorized 都会被转换为重定向。

我尝试了这里提到的方法(相同问题,使用旧版beta框架,我使用的是1.0.0-rc1-final)。我没有Notifications名称空间(已在rc1-final中删除)。

这是我的登录控制器:

    [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();
    }

在 Startup.cs 文件中,我尝试过以下变化:
        services.Configure<CookieAuthenticationOptions>(o =>
        {
            o.LoginPath = PathString.Empty;
            o.ReturnUrlParameter = PathString.Empty;
            o.AutomaticChallenge = false;
        });

每当登录失败(请忽略返回的密码),应该会出现一个空的401页面,但我却被重定向到/Account/Login。这里有什么诀窍吗?

你是在尝试在登录页面上实现这个功能吗?还是用于REST API身份验证?如果是用于API,你可以看一下这个链接:http://wildermuth.com/2015/9/10/ASP_NET_5_Identity_and_REST_APIs - David Rinck
REST API,您的链接假定Notifications命名空间存在,但已被删除。链接的解决方案不再起作用。 - galmok
4个回答

9
解决方案不是直接配置CookieAuthenticationOptions,而是通过IdentityOptions进行配置,如下所示:
        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);
                }
            };
        });

5
对我来说,仅仅使用 o.Cookies.ApplicationCookie.AutomaticChallenge = false; 就足够了(我从未想过要重定向)。 - Peppe L-G
@PeppeL-G 这是我能让它工作的唯一方法。非常感谢你。 - Sloth Armstrong

8

这段内容来源于此处(Shawn Wildermuth --> ASP.NET 5身份验证和REST API -->“Mehdi Hanafi”的评论),我使用Postman测试了API。

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);
        }
    }
};

你首先要如何进行重定向?我真希望我的能够进行重定向,但它就是做不到。 - Sam

4
从身份2.0开始,您需要添加以下内容:
using Microsoft.AspNetCore.Authentication.Cookies;

并且在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;
        })
    };
});

当然,分段检查应该根据您的路线进行调整。


2
如果您希望对某些页面进行重定向,而其他URL则不需要重定向,请查看此问题的解决方案。该解决方案仅针对非API URL使用默认的重定向逻辑:Suppress redirect on API URLs in ASP.NET Core。请注意保留HTML标签。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接