【问题标题】:Dynamic role based authorization on method基于方法的动态角色授权
【发布时间】:2015-09-30 23:33:13
【问题描述】:

我有一个俱乐部表,当创建一个新角色时,会创建一个新角色 Club(俱乐部的 id)Admin。

我希望能够在方法的授权属性中引用这个角色。

这是我在控制器方法上尝试过的:

        [Authorize(Roles = "Club" + clubId + "Admin")]
    public ActionResult ClubDetails(int clubId)
    {
        var viewModel = db.Clubs
          .Where(t => t.ClubId == clubId)
          .Select(t => new ClubDetailsViewModel
          {
              ClubId = t.ClubId,
              Name = t.Name,
              ShortName = t.ShortName,
              Founded = t.Founded,
              ContactName = t.FirstName + " " + t.LastName,
              Address1 = t.Address1,
              Address2 = t.Address2,
              City = t.City,
              County = t.County,
              Postcode = t.Postcode,
              Telephone = t.Telephone,
              Email = t.Email,
              Website = t.Website,
              Bio = t.Bio,
              ClubTypeId = t.ClubTypeId,
              MembershipStatusId = t.MembershipStatusId,
              ChequesPayable = t.ChequesPayable,
              BACSAcc = t.BACSAcc,
              BACSSort = t.BACSSort,
              PaypalAdd = t.PaypalAddress,
          })
          .FirstOrDefault();
        return View(viewModel);
    }

但这会导致授权属性中的 clubId 出现错误。当前上下文中不存在名称 clubId

有没有一种方法可以引用在授权属性中传递给方法的参数?

【问题讨论】:

  • 好吧,授权属性在绑定发生之前在 MVC 管道中执行。你我猜,你应该创建自己的授权过滤器。 This answer 会帮助你。

标签: c# asp.net-mvc


【解决方案1】:

您不能将动态数据传递给属性。 要解决您的问题,您可以继承 Authorize 属性并在 AuthorizeCore 方法中检查 clubId(您必须手动获取 clubId)或检查操作代码中的访问权限,即

if(User.IsInRole("Club" + clubId + "Admin"))

您可能应该考虑拆分“Admin”角色和 clubId,这样您的所有俱乐部管理员都具有相同的“Admin”角色并且他们都绑定到 clubId(即在数据库中具有列)

【讨论】:

  • 这看起来仍然是错误的。他显然不想检查clubId 是否是某个固定值,而是想验证绑定到方法参数的clubId 是否与角色名称中的clubId 完全相同。跨度>
【解决方案2】:

没有。你必须重写 AuthorizeAttribute 类来创建你自己的自定义属性。

[AttributeUsageAttribute( AttributeTargets.Class | 
                          AttributeTargets.Method, 
                          Inherited = true, AllowMultiple = true )]
public class CustomAuthorizeAttribute : AuthorizeAttribute {

   public override bool AuthorizeCore( HttpContextBase context ) {

       // this is where you can inspect the principal in context.User
       // and check if he/she is in role

       // you can get the clubId from context.Request.Params

       var clubId = int.Parse( context.Request.Params["clubId"] );

       return context.User.IsInRole( string.Format( "Club{0}Admin", clubId ) );  
   }

}

然后

[CustomAuthorizeAttribute]
public ActionResult ClubDetails(int clubId)

您甚至可以将Club{0}Admin 作为参数移动到属性的构造函数中。

【讨论】:

  • 非常感谢,有没有办法在属性中添加其他角色,以便可以授权多个角色?
  • 我还需要在哪里放置自定义属性定义?
  • 将代码放置在您想要的位置,以便可以从控制器访问该类。这应该是基本的。此外,根据需要修改核心代码,必要时传递其他参数。我的示例只是为了让您入门。
  • 我认为它会是,但我将它放在控制器中,它可用于我的方法,但它给出以下错误:'GRCWebApp.Controllers.ClubController.CustomAuthorizeAttribute.AuthorizeCore(System.Web.HttpContextBase )':覆盖'protected'继承成员'System.Web.Mvc.AuthorizeAttribute.AuthorizeCore(System.Web.HttpContextBase)'时无法更改访问修饰符
  • 这真是个简单的问题,把public改成protected。
猜你喜欢
  • 1970-01-01
  • 2022-01-01
  • 1970-01-01
  • 2017-12-14
  • 2017-04-12
  • 2018-07-21
  • 1970-01-01
  • 2020-06-22
相关资源
最近更新 更多