【问题标题】:Authorization not working on custom authorizeattribute授权不适用于自定义授权属性
【发布时间】:2014-10-28 10:37:02
【问题描述】:

我为我的 MVC 控制器创建了一个非常简单的授权属性,旨在重定向到允许显示“未授权”消息的控制器:

public class ReportAuthorizeAttribute : AuthorizeAttribute
{
    protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
    {
        filterContext.Result = new RedirectToRouteResult(new RouteValueDictionary
        {
            { "action", "ReportDenied" }
            , { "controller", "Authorization"}
        });
    }
}

我将它应用到我的主站点控制器:

[ReportAuthorize(Roles=@"Domain\GroupName")]
public class ReportController : Controller
{
     //etc
}

即使我在 @"Domain\GroupName" 中,我也会被踢出局。实际上,如果我将其更改为 Users=@"Domain\MyUserName" 它仍然失败!

我已将其追溯到为该站点启用的 IIS 设置匿名身份验证。不幸的是,我不能在我们的生产系统上禁用匿名访问,因为这个项目是一个更大的 MVC 项目的一部分,其中有许多其他控制器没有正确的属性。但是,当我在IIS中本地更改它时,我可以正常进入。

现在,如果我更改为正常的授权属性:

[Authorize(Roles = @"Domain\GroupName")]
public class ReportController : Controller
{
    //etc
}

我进入(我假设是因为我没有为未经授权的用户尝试连接时定义任何特殊行为)。

我有哪些选项可以解决此属性问题?我只需要获取 ReportsAuthorize 属性以正确验证用户身份,然后再将用户踢出匿名。

【问题讨论】:

    标签: asp.net-mvc iis asp.net-mvc-5 authorization custom-attributes


    【解决方案1】:

    我原以为您会想要检查当前用户是否经过身份验证 (filterContext.HttpContext.User.Identity.IsAuthenticated)。

    如果没有,请致电 base.HandleUnauthorizedRequest,这可能最终会发送 Windows 凭据质询。

    如果用户通过了身份验证,则实现您的重定向逻辑。

    话虽如此,使用标准的AuthorizeAttribute 并使用自定义错误显示“未授权”页面不是更简单吗?

    【讨论】:

    • 标准 authorizeattribute 的问题是,如果我输入一个组名,我不是其中的一部分,我会向我挑战我的凭据,但无法正确验证我并反复询问直到我取消。跨度>
    • @CBauer - 如果提示对您来说是个问题,那么是的,选择自定义属性。以我的经验,这不是问题,因为我会使用启用安全修剪的 MvcSiteMapProvider 之类的东西,这样用户就看不到指向他们未经授权的 URL 的链接。因此,用户很少遇到提示。
    • 不幸的是,我要保护的页面是通过直接链接传播的网站,如果我可以定位一个角色并将没有该角色的人转发给“您无权访问此资源”页面。
    【解决方案2】:

    好的,所以在经历了一些痛苦和痛苦之后,我终于解决了这个问题。请记住,部分问题在于该控制器位于一个较大的项目中,无法在 IIS 中禁用匿名身份验证。

    这是控制器:

    [ReportAuthorize(Users = @"domain\me,domain\etc", Roles = @"domain\groupname")]
    [Authorize]
    public class ReportController : Controller
    {
        //etc
    }
    

    这是授权属性:

    public class ReportAuthorizeAttribute : AuthorizeAttribute
    {
        protected override bool AuthorizeCore(HttpContextBase httpContext)
        {
            if (Users.Contains(httpContext.User.Identity.Name) || Roles.Split(',').Any(s => httpContext.User.IsInRole(s))) //this if checks users and roles using OR logic
            {
                return true;
            }
            return false;
        }
    
        protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
        {
            filterContext.Result = new RedirectToRouteResult(new RouteValueDictionary
            {
                {"action", "ReportDenied"}
                ,
                {"controller", "Authorization"}
            }); //this redirect sends you to a "not permitted" page
        }
    }
    

    我需要授权属性来使站点检查域并加载帐户信息。然后,覆盖授权核心的自定义属性使用 OR 逻辑验证值(而不是默认的 AND 逻辑,通过使用两个授权属性来演示,其中一个包含您需要的用户/角色)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-07-01
      • 1970-01-01
      • 1970-01-01
      • 2020-04-11
      • 2015-03-03
      • 1970-01-01
      相关资源
      最近更新 更多