是否可以绕过控制器上的授权角色检查,但是对操作强制执行角色检查?我花了一些时间研究这个,我发现的一切都展示了如何实现AllowAnonymousAttribute。我目前正在使用AllowAnonymousAttribute,它非常适合完全绕过操作的授权。那不是我想要的。我有一个需要某些角色的控制器。当请求特定操作时,我想跳过控制器级别的角色,只是验证用户是否在操作上指定了角色。
以下是一些代码:
[Authorize(Roles="Administrator")]
public class MembersController : ViewApiController<MemberView>
{
// a list of actions....
[Authorize(Roles="ApiUser")]
[HttpPost]
public void AutoPayPost([FromBody] List<AutoPayModel> autoPayList)
{
//....
}
}
问题是我希望只有“ApiUser”角色的用户才能访问“AutoPayPost”操作。我意识到我可以删除类级别authorize属性,然后将其添加到我的控制器上的每个操作方法,减去'AutoPayPost'操作。我想避免这种情况,因为我的几个控制器都从一个基类继承,该基类提供了一长串需要“管理”角色的操作。因此我必须覆盖每个基本操作,将Authorize属性添加到重写方法,然后将调用委托给基类。这将有效但如果我后来决定向基类添加功能,我将不得不记得回到MembersController并覆盖新方法,添加属性等...
如果最终结果如下所示会很棒:
[Authorize(Roles="Administrator")]
public class MembersController : ViewApiController<MemberView>
{
// a list of actions....
[Authorize(Roles="ApiUser", IgnoreControllerRoles=true)]
[HttpPost]
public void AutoPayPost([FromBody] List<AutoPayModel> autoPayList)
{
//....
}
}
答案 0 :(得分:1)
执行类似的操作,您将检查角色/用户是否在角色中,然后拒绝其中的任何角色。
的
的public class ByPassAuthorizeAttribute : AuthorizeAttribute
{
protected override bool AuthorizeCore(HttpContextBase httpContext)
{
string[] roles = this.Roles.Split(',');
string[] users = this.Users.Split(',');
foreach (var r in roles)
{
if (httpContext.User.IsInRole(r.Trim()))
return false;
}
foreach (var u in users)
{
if (httpContext.User.Identity.Name.Equals(u))
return false;
}
return base.AuthorizeCore(httpContext);
}
}
的
然后像这样解析你的控制器/动作:
的
的 [ByPassAuthorize(Roles = "Admin,test,testint", Users = "Tester")]
public ActionResult Edit(int id = 0)
{
FooModel foomodel = db.FooModels.Find(id);
if (foomodel == null)
{
return HttpNotFound();
}
return View(foomodel);
}
的
希望对你有所帮助!
答案 1 :(得分:0)
如果我理解正确,您可以实现自定义ByPassControllerChecksAttribute(它用于装饰您希望允许“直通”访问的方法),然后在您的LogonAuthorizeAttribute中检索此请求调用的操作方法并检查其是否自定义属性集合具有ByPassControllerChecksAttribute的实例。如果是,请运行代码以检查是否允许用户访问该方法,否则运行代码以检查是否允许用户访问控制器。当然,如果您只有一个方法并且知道名称不会更改,您可以绕过额外属性并检查名称,但当然第一种方法要好得多。
修改强>
如果您的LogonAuthorizeAttribute继承自AuthorizeAttribute,那么您可以覆盖返回布尔值的AuthorizeCore方法(true表示用户已获得授权,否则为false)。在这种方法中,您可以使用以下伪代码:
if(CheckIfMethodHasByPassAttribute()){
return CheckIfUserIsAllowedToRunThisMethod();
}
return CheckIfUserIsAllowedToRunThisController();
方法CheckIfUserIsAllowedToRunThisMethod将需要做任何检查以确定是否允许用户运行此方法,而CheckIfUserIsAllowedToRunThisController将具有检查用户是否被允许访问控制器的代码(我假设已经在你的LogonAuthorizeAttribute中)