Asp.net mvc 基于某些标准(而不是用户身份验证)限制对控制器的访问
限制访问控制器的正确方法是什么 例如,我可能有“ProductReviewController”,我希望能够检查此控制器在当前存储中是否可访问并已启用。我不是在寻找代码来实现这一点,但我对在不满足此标准的情况下阻止用户访问控制器的方法感兴趣。我希望请求继续进行,就好像控制器从未出现过一样(因此可能会抛出404) 到目前为止,我的想法是:Asp.net mvc 基于某些标准(而不是用户身份验证)限制对控制器的访问,asp.net-mvc,controller,data-annotations,asp.net-mvc-5,Asp.net Mvc,Controller,Data Annotations,Asp.net Mvc 5,限制访问控制器的正确方法是什么 例如,我可能有“ProductReviewController”,我希望能够检查此控制器在当前存储中是否可访问并已启用。我不是在寻找代码来实现这一点,但我对在不满足此标准的情况下阻止用户访问控制器的方法感兴趣。我希望请求继续进行,就好像控制器从未出现过一样(因此可能会抛出404) 到目前为止,我的想法是: 数据注释,即[IsValidController]。我从哪个属性类派生-Authorize似乎不太合适,我会将其与用户身份验证联系起来。此外,如果不满足标准,我
[IsValidController]
。我从哪个属性
类派生-Authorize似乎不太合适,我会将其与用户身份验证联系起来。此外,如果不满足标准,我不确定正确的响应是什么(但我想这取决于它派生的属性)。我可以把这个数据注释放在我的基本控制器上
AuthorizeAttribute
。但是我觉得我误用了authorized属性
public class IsControllerAccessible : AuthorizeAttribute
{
protected override bool AuthorizeCore(HttpContextBase httpContext)
{
if (!CriteriaMet())
return false;
return true;
}
protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
{
filterContext.Result = new RedirectToRouteResult(
new RouteValueDictionary(
new
{
controller = "Generic",
action = "404"
})
);
}
}
我想你对属性感到困惑。它是一个动作过滤器,而不是数据注释。数据注释修饰validatioj的模型属性,动作过滤器修饰控制器动作,以检查控制器的上下文,并在动作执行之前执行某些操作
因此,限制对控制器操作的访问是authorized属性
存在的理由,所以让我们使用它吧
在SO好心人的帮助下,我创建了一个客户操作过滤器,该过滤器基于访问目录组的一部分来限制对操作(甚至控制器)的访问:
public class AuthorizeADAttribute : AuthorizeAttribute
{
public string Groups { get; set; }
protected override bool AuthorizeCore(HttpContextBase httpContext)
{
if (base.AuthorizeCore(httpContext))
{
/* Return true immediately if the authorization is not
locked down to any particular AD group */
if (String.IsNullOrEmpty(Groups))
return true;
// Get the AD groups
var groups = Groups.Split(',').ToList<string>();
// Verify that the user is in the given AD group (if any)
var context = new PrincipalContext(ContextType.Domain, "YOURADCONTROLLER");
var userPrincipal = UserPrincipal.FindByIdentity(context,
IdentityType.SamAccountName,
httpContext.User.Identity.Name);
foreach (var group in groups)
{
try
{
if (userPrincipal.IsMemberOf(context, IdentityType.Name, group))
return true;
}
catch (NoMatchingPrincipalException exc)
{
var msg = String.Format("While authenticating a user, the operation failed due to the group {0} could not be found in Active Directory.", group);
System.ApplicationException e = new System.ApplicationException(msg, exc);
ErrorSignal.FromCurrentContext().Raise(e);
return false;
}
catch (Exception exc)
{
var msg = "While authenticating a user, the operation failed.";
System.ApplicationException e = new System.ApplicationException(msg, exc);
ErrorSignal.FromCurrentContext().Raise(e);
return false;
}
}
}
return false;
}
}
或在控制器级别:
[AuthorizeAD(Groups = "Admin")]
public class AdminController : Controller
甚至可以通过在`/App\u Start'中编辑FilterConfig.cs
进行全局编辑:
public class FilterConfig
{
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
filters.Add(new HandleErrorAttribute());
filters.Add(new Code.Filters.MVC.AuthorizeADAttribute() { Groups = "User, Editor, Contributor, Admin" });
}
太棒了
另外,您在第二点中提到了页面生命周期。MVC中没有这样的东西,至少在Web表单的意义上你可能不会这么想。这对我来说是一件好事,因为事情已经大大简化了,我不需要记住十几个不同的生命周期事件,也不需要记住每一个事件都是为了什么 好的,感谢您对数据注释的澄清-我的术语有误。我刚刚使用authorized属性编写了自己的版本,它运行良好。我只是想确定这是正确的方法。当我提到生命周期时,我指的是这类事情:。我特别考虑覆盖第7点并创建自定义控制器工厂。在我的情况下,p.s404 not found
将是正确的响应。不是用户未经授权,而是网站不应该显示内容(这意味着用户遵循缓存链接或其他内容)。那么代码可能应该驻留在控制器本身,因为它负责根据用户交互提供正确的视图。如果用户提供产品id,则让控制器检查其在商店中是否存在,如果没有,则重定向到指示该id的特定视图。
public class FilterConfig
{
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
filters.Add(new HandleErrorAttribute());
filters.Add(new Code.Filters.MVC.AuthorizeADAttribute() { Groups = "User, Editor, Contributor, Admin" });
}