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

时间:2017-01-17 21:10:29

标签: asp.net-core authorization asp.net-core-mvc asp.net-core-middleware

我正在使用向第三方服务发出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,所以我也不能使用它......

思考? 感谢。

2 个答案:

答案 0 :(得分:2)

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

因此完整的解决方案如下:

  1. 创建自定义要求:

    public class SomeCustomRequirement : IAuthorizationRequirement
    {}
    
  2. 创建自定义处理程序:

    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);
            }
        }
    }
    
  3. 注册处理程序:

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

即使我的回答来得太晚,我希望它可以对将来的访问者有所帮助。

答案 1 :(得分:0)

如果您想要在API的中间件中尝试唯一的事情是执行LogIn行为,,因为您的代码似乎在解释,在我看来,这些可能的情况是发人深省的:< / p>

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

    • 您应该使用HttpContext.Response.Redirect重定向到LogIn网页。 As the documentation says,这将发送任何Web浏览器可以解释的301代码。 HttpContext在Invoke方法中可用。
  2. 如果/login/home重定向到执行验证用户身份的逻辑的控制器:

  3. 还可以查看Nate's postthis question