来自 AuthorizationHandler (ASP.NET Core) 的自定义重定向

Posted

技术标签:

【中文标题】来自 AuthorizationHandler (ASP.NET Core) 的自定义重定向【英文标题】:Custom redirect from AuthorizationHandler (ASP.NET Core) 【发布时间】:2017-06-02 02:26:08 【问题描述】:

我正在使用向第三方服务发出 API 请求的身份验证中间件。然后,此中间件设置声明,稍后由 AuthorizationHandler 与 IAuthorizationRequirement 和自定义策略一起处理。

中间件有效,我可以构建声明:

context.User.AddIdentity(identity); // contains claims

我被卡住的地方是从处理程序或属性重定向到特定的 URL(我们需要重定向的地方有自定义规则)。从我尝试过的处理程序:

var mvcContext = context.Resource as Microsoft.AspNetCore.Mvc.Filters.AuthorizationFilterContext;
mvcContext.Result = new RedirectToActionResult("login", "home", null);

但它被忽略了;只返回 401。 AuthorizeAttribute 不再有 OnAuthorization 所以我也不能使用它...

想法? 谢谢。

【问题讨论】:

【参考方案1】:

您在处理程序中使用 AuthorizationFilterContext 的方法几乎是正确的。如this answer 中所述,您还需要输入context.Succeed(requirement); 才能使其正常工作。

所以完整的解决方案应该是这样的:

    创建自定义需求:

    public class SomeCustomRequirement : IAuthorizationRequirement
    
    

    创建自定义处理程序:

    public class SomeCustomRequirementHandler : AuthorizationHandler<SomeCustomRequirement>
    
        protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, UserInformationCompletedRequirement requirement)
        
            if (!fulfillsRequirement())
                if (context.Resource is AuthorizationFilterContext redirectContext)
                    redirectContext.Result = new RedirectResult("/Account/Unauthorized");
                // even though this is weird it is necessary
                context.Succeed(requirement);
            
        
    
    

    注册处理程序:

    services.AddAuthorization(options =>
    
        options.AddPolicy(IdentityConstants.UserInformationCompletePolicy, policy =>
        
            policy.RequireAuthenticatedUser();
            policy.Requirements.Add(new SomeCustomRequirement());
        );
    );
    
    services.AddSingelton<IAuthorizationHandler, SomeCustomRequirementHandler>();    
    // OR transient if the handler uses the Entity Framework
    services.AddTransient<IAuthorizationHandler, SomeCustomRequirementHandler>();
    

尽管我的回答迟了,但我希望它可以帮助未来的访客。

【讨论】:

【参考方案2】:

如果您只想在 API 的中间件中尝试执行登录行为,正如您的代码似乎解释的那样,在我看来,这些可能的情况是发人深省的:

    如果/login/home 重定向到网页:

    您应该使用HttpContext.Response.Redirect 重定向到登录网页。 As the documentation says,这将发送任何 Web 浏览器都可以解释的 301 代码。 HttpContext 在Invoke 方法中可用。

    如果/login/home 重定向到执行验证用户身份的逻辑的控制器:

    您可以改为在中间件中验证用户的身份,而不是在单独的路由中。 Just like the great Nate Barbettini does。

还请查看Nate's post 和this question。

【讨论】:

以上是关于来自 AuthorizationHandler (ASP.NET Core) 的自定义重定向的主要内容,如果未能解决你的问题,请参考以下文章

AuthorizationHandler异常不通过ExceptionFilter

自定义AuthorizationHandler HandleRequirementAsync未调用

AuthorizationHandler 和数据库依赖注入

有没有办法在 .Net 5 中的 AuthorizationHandler 中重定向?

[Asp.Net Core]NET5策略鉴权

[Asp.Net Core]NET5策略鉴权