【问题标题】:Failing claim gives 500 instead of 403失败的索赔给 500 而不是 403
【发布时间】:2015-03-19 19:16:48
【问题描述】:

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

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

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

【问题讨论】:

  • 500 通常表示服务器出现错误。那是什么错误?请给我们看一些代码。我怀疑你使用 ClaimsPrincipal.Current - 这不是 MVC 应用程序中的最佳方式,因为这个值并不总是你想要的,尤其是对于未经身份验证的用户。
  • 我们在我们的 MVCcontroller 方法上使用 ClaimsPrincipalPermissionAttribute,如果用户没有被授权,它会抛出一个 SecurityException,它最终会变成 500 而不是 403,这对用户不是很友好。用户不明白他需要获得额外的权限才能访问系统的上述功能
  • 更新了一个例子

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


【解决方案1】:

我明白你在做什么。 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 个大规模生产项目中成功使用了这种方法,所以一定要正确使用 -)

【讨论】:

  • 愚蠢的我,在另一个项目中为企业库规则授权做了同样的事情。您使用 OnAuthorization 并处理 Attribute 中的错误重定向的任何原因?如果您改为覆盖 AutorizeCore 并返回 true/false,MVC 将使用内置的自定义错误管道
  • 现在不记得了,但这是有原因的。可能是因为我可以控制我重定向用户的位置 - 很高兴告诉他们他们没有权限,而不是在没有消息的情况下将他们重定向到登录页面。
  • 这是我们目前正在为 Asp.Net 5/MVC 积极迭代的内容,如果您有任何意见,请随时查看/评论...github.com/aspnet/Security/pull/141(我们正在政策驱动的方向,政策可以支持索赔要求)
【解决方案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/

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-09-11
    • 1970-01-01
    • 2012-09-26
    • 2021-08-29
    • 2018-10-31
    • 2015-07-01
    • 1970-01-01
    相关资源
    最近更新 更多