9

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

想法?谢谢。

4

2 回答 2

6

您在处理程序中使用 AuthorizationFilterContext 的方法几乎是正确的。如本答案中所述,您还需要说明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>();
    

即使我的回答迟了,我希望它可以帮助未来的访客。

于 2018-11-25T15:57:32.030 回答
1

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

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

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

还可以看看Nate 的帖子这个问题

于 2017-02-16T10:44:25.353 回答