失败的索赔给予 500 而不是 403

Failing claim gives 500 instead of 403

我们使用 MVC 控制器中的声明主体属性。问题是,如果未经授权的用户访问该站点,他会收到 500 而不是 403,这对用户来说不是很友好(如果他收到 403,他知道他需要致电服务台以订购正确的用户权限)。

确保安全异常导致 403 的正确方法是什么?我在谷歌搜索时看到了很多创造性的方法,但没有一个可靠的解决方案。

[ClaimsPrincipalPermission(SecurityAction.Demand, Resource = "Foo", Operation = "Post")]

我明白你想做什么了。 ClaimsPrincipalPermissionAttribute 不适用于 MVC 应用。但是,MVC 没有以类似方式工作的类似属性,因此您需要自己实现一个。

您可以将我的简单实现作为您代码的基础:

public class ClaimsAuthorizeAttribute : AuthorizeAttribute
{
    public string ClaimType { get; private set; }
    public string ClaimValue { get; private set; }

    public ClaimsAuthorizeAttribute(string claimType, string claimValue)
    {
        ClaimType = claimType;
        ClaimValue = claimValue;
    }

    public override void OnAuthorization(AuthorizationContext filterContext)
    {
        var user = HttpContext.Current.User as ClaimsPrincipal;
        if (user.HasClaim(ClaimType, ClaimValue))
        {
            base.OnAuthorization(filterContext);
        }
        else
        {
            filterContext.Result = new RedirectToRouteResult(new RouteValueDictionary()
            {
                // need to have controller Errors with action Unauthorised
                {"controller", "Errors"},
                {"action", "Unauthorised"}
            });
        }
    }
}

我已经玩了一段时间的索赔认证并将其加载到 GitHub(有 2 个分支,主要的更高级)。欢迎您四处探索,看看它是如何工作的。我已经在 2 个成功的大规模生产项目中使用了这种方法,所以一定是正确的 -)

建议使用自己的 Claims 属性,如 trailmax,但仅适用于 Web 层中的代码,但下面的业务逻辑仍然可以使用 claims 属性。解决我的问题的更好方法是使用自定义 HandleErrorAttribute

public class HandleClaimsErrorAttribute : HandleErrorAttribute
{
    public override void OnException(ExceptionContext filterContext)
    {
        base.OnException(filterContext);
        if (filterContext.Exception is SecurityException)            
            filterContext.HttpContext.Response.StatusCode = 403;            

    }
}

http://andersmalmgren.com/2015/01/23/mvc-custom-errors-http-status-codes-and-securityexception/