捕获失败的授权策略

时间:2018-04-04 20:03:38

标签: c# asp.net-core asp.net-core-mvc asp.net-core-2.0

在.Net Core 2中,假设存在一个授权策略,用于检查用户是否存在特定声明:

public class CompletedProfileRequirement : AuthorizationHandler<CompletedProfileRequirement>, IAuthorizationRequirement
{
    protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, CompletedProfileRequirement requirement)
    {
        // Check that all required claims exist
        if (/* invalid user claims */) {
            context.Fail();
        }

        context.Succeed(requirement);
        return Task.FromResult(0);
    }
}

我们将策略检查放在MVC控制器之上:

[Authorize(Policy = "CompletedProfile")]
public class HomeController : Controller
{
     // Controller stuff
}

如何编写IAuthorizationFilter以便我们可以在此特定CompletedProfileRequirement政策中发现失败,以便我们可以将用户重定向到可以完成其个人资料的页面?

2 个答案:

答案 0 :(得分:1)

根据authorization documentation,您可以从AuthorizationHandler访问MVC上下文:

  

诸如MVC或Jabbr之类的框架可以自由地将任何对象添加到Resource上的AuthorizationHandlerContext属性以传递额外信息。

     

例如,MVC在AuthorizationFilterContext属性中传递Resource的实例。此属性提供对HttpContextRouteData以及MVC和Razor Pages提供的所有其他内容的访问权限。

因此,您可以这样做:

public class CompletedProfileRequirement : AuthorizationHandler<CompletedProfileRequirement>, IAuthorizationRequirement
{
    protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, CompletedProfileRequirement requirement)
    {
        // Check that all required claims exist
        if (/* invalid user claims */) {

            // retrieve MVC context
            if (context.Resource is AuthorizationFilterContext mvcContext)
            {
                // we still need to mark the requirement as succeeded, 
                // otherwise responde code is 401 unauthorized
                context.Succeed(requirement);

                // HTTP 302 temporary redirect to your page
                mvcContext.HttpContext.Response.Redirect("/Home/Wherever", false);
                return Task.FromResult(0);
            }

        }

        context.Succeed(requirement);
        return Task.FromResult(0);
    }
}

答案 1 :(得分:0)

您应该在应用程序启动时将您的策略​​添加到授权请求中,例如:

services.AddAuthorization(options =>
        {
            options.AddPolicy("CompletedProfile", builder =>
            {
                builder.AddRequirements(new CompletedProfileRequirement());
            });
        });

注册处理程序,例如:

 services.AddScoped<IAuthorizationHandler, CompletedProfileRequirementHandler>();

UPD:

对于重定向,您应该在控制器中注入和使用:

IAuthorizationService authorizationService

并调用:

var result = _authorizationService.AuthorizeAsync(User, someObject, "CompletedProfile");
if (!result.Succeeded)
    return RedirectToAction("CompleteProfileAction");