我有一个这样的自定义动作过滤器:
public class MySecurityTest : ActionFilterAttribut{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
//Do some security tests
base.OnActionExecuting(filterContext);
}
}
我将此添加到FilterConfig
以执行所有操作。但是如果没有它,我需要一些操作。
现在我使用这样的东西:
public class MySecurityTest : ActionFilterAttribute
{
public bool CheckRules { get; set; }
public MySecurityTest(bool checkRules = true)
{
CheckRules = checkRules;
}
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
if (CheckRules)
{
//Do some security tests
}
base.OnActionExecuting(filterContext);
}
}
和用法:
[MySecurityTest(false)]
public ActionResult Index()
{
return View();
}
但是如何构建像[AllowAnonymous]
属性
最好的问候
答案 0 :(得分:3)
您只需要创建另一个属性并使用.NET反射来检查它的存在。
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
if (!HasMyIgnoreAttribute(filterContext))
{
//Do some security tests
}
base.OnActionExecuting(filterContext);
}
public bool HasMyIgnoreAttribute(ActionDescriptor actionDescriptor)
{
// Check if the attribute exists on the action method
bool existsOnMethod = actionDescriptor.IsDefined(typeof(MyIgnoreAttribute), false);
if (existsOnMethod)
{
return true;
}
// Check if the attribute exists on the controller
return actionDescriptor.ControllerDescriptor.IsDefined(typeof(MyIgnoreAttribute), false);
}
然后创建一个自定义属性来装饰你的动作/控制器。
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, AllowMultiple = false)]
public class MyIgnoreAttribute : Attribute
{
}
[MySecurity]
public class MyController
{
[MyIgnore]
public ActionResult Index()
{
return View();
}
public ActionResult About()
{
return View();
}
}
一般情况下,如果使用依赖注入,最好不要使用ActionFilterAttribute
,因为should contain no behavior中的属性this answer。您还应该考虑使用authorization filter(或AuthorizationAttribute继承的类)而不是动作过滤器来进行安全检查,因为它是在管道的早期完成的。
答案 1 :(得分:2)
但是如何构建像[AllowAnonymous]属性
这样的东西
实际上非常简单:
[AttributeUsage(AttributeTargets.Method)]
public class ExcludeMySecurityAttribute : Attribute
{
}
然后在您的过滤帐户中:
public class MySecurityTest : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
if (filterContext.ActionDescriptor.GetCustomAttributes(typeof(ExcludeMySecurityAttribute), true).Any())
{
// The controller action is decorated with the exclude attribute
// so you should probably do nothing here
}
else
{
// Do your security tests here
}
}
}
现在剩下的就是装饰:
[ExcludeMySecurity]
public ActionResult Index()
{
return View();
}
答案 2 :(得分:0)
要构建类似[AllowAnonymous]过滤器的内容,您可以继承IAllowAnonymousFilter或您选择的任何过滤器,然后您必须在其他过滤器中进行验证,例如,如果context.filter是IAllowAnonymousFilter
var filters = context.Filters;
for (var i = 0; i < filters.Count; i++)
{
if (filters[i] is IAllowAnonymousFilter)
{
return true;
}
}
示例
public class AuthorizeAllAccessActionFilter : IAuthorizationFilter // or whatever filter
you inherit
{
...... ....
public void OnAuthorization(AuthorizationFilterContext context)
{
var filters = context.Filters;
for (var i = 0; i < filters.Count; i++)
{
if (filters[i] is IAllowAnonymousFilter) // or AnonymousAccessActionFilter
{
return ;
}
}
.... ....
.....
....
}
public class AnonymousAccessActionFilter : IAllowAnonymousFilter,
IAuthorizationFilter, IOrderedFilter
{
....
....
// do what everver implement you want
}
我选择将IOrderedFilter保留在代码中,因为您可能希望更改过滤器上的执行顺序,因为您希望先执行
您现在可以像这样使用它
[AuthorizeAllAccess]
public class UsersController : ControllerBase
{
/// other action method
[AnonymousAccess(Order = int.MinValue)]
[HttpGet]
public async Task<IActionResult> GetUsers() {
}
}