从 .net core 2.1 中间件重定向到控制器操作/视图的正确方法

Fli*_*242 2 c# asp.net-core-mvc angular

我有一个 .NET Core 2.1/Angular 6 应用程序,如果他们不是安全组的一部分,我试图将用户重定向到静态视图。运行应用程序时,我只是不断收到“错误太多重定向”。

我有一个securityMiddleWareStartup.cs

public class ADAuthMiddleware
{

    RequestDelegate next;

    public ADAuthMiddleware(RequestDelegate next)
    {

        this.next = next;
    }

    public async Task Invoke(HttpContext httpContext)
    {
        //check if user belongs to AD group or not
        var isAuthorized = httpContext.User.IsInRole("app.users.foo");


        // Return error if the current user is not authorized
        if (!isAuthorized)
        {
            httpContext.Response.StatusCode = 403;
            return;
        }

        // Jump to the next middleware if the user is authorized
        await next(httpContext);
    }

}
Run Code Online (Sandbox Code Playgroud)

现在我已将其设置为返回 403 的响应,这只会生成标准的丑陋“未经授权的页面”,因此我想要一种更简洁的方式将用户发送到新视图,在那里他们可以获得有关获取访问权限的说明... 拒绝访问

我试过httpContext.Response.Redirect(/controller/action)没有运气。这适用于带有 MVC 的完整 .NET 框架。到目前为止,我已经发现 .NET Core 存在问题......也可能是因为它在一个Task而不是IActionResult?

Wid*_*dor 5

您需要在中间件中添加一些逻辑,以确保在重定向用户后不会再次尝试对其进行身份验证。

否则,您将陷入重定向、身份验证和重定向的循环,因为它们未经身份验证。

在您可以有条件地应用您的身份验证的Configure()方法中Startup.cs,例如

app.UseWhen(ShouldAuthenticate, appBuilder =>
    {
        appBuilder.UseMiddleware<ADAuthMiddleware>();
    });
Run Code Online (Sandbox Code Playgroud)

并定义ShouldAuthenticate为:

private static bool ShouldAuthenticate(HttpContext context)
{
    var path = context.Request.Path;
    return !context.Request.Path.StartsWithSegments("/staticpage");
}
Run Code Online (Sandbox Code Playgroud)

对于重定向,您可以使用相同的Configure()方法执行此操作,例如

app.Use(async (context, next) =>
{
    await next.Invoke();
    if (context.Response.StatusCode == 401)
    {
        context.Response.Redirect("/redirectpage/"); 
    }
});
Run Code Online (Sandbox Code Playgroud)

请注意,这是实现它的一种简单方法,还有更多使用身份服务等实现此目的的“核心”方法