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

时间:2015-01-21 10:04:14

标签: asp.net-mvc asp.net-mvc-4 asp.net-identity wif claims-based-identity

我们使用MVC控制器的Claims主体属性。问题是,如果未经授权的用户访问该网站,他获得500而不是403,这对用户不友好(如果他得到403,他知道他需要致电服务台订购正确的用户权限)。

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

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

2 个答案:

答案 0 :(得分:2)

我明白你要做什么。 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个大规模的生产项目中成功使用了这种方法,因此必须做得对 - )

答案 1 :(得分:1)

使用自己的Claims属性(如trailmax建议),但仅适用于Web层中的代码,但下面的业务逻辑仍然可以使用claim属性。我的问题的更好解决方案是使用自定义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/