c# – 检测是否手动调用AuthorizationAttribute

我在遗留MVC5项目中有一个自定义AuthorizeAttribute:
public class AuthorizeWithLoggingAttribute : AuthorizeAttribute
{
     public override void OnAuthorization(AuthorizationContext filterContext)
     {
         if (!base.AuthorizeCore(httpContext)) {Log(FilterContext);}
     }
 }

我们在查看日志时注意到,除了要使用[AuthorizeWithLogging]应用于控制器之外,还在代码中的其他地方显式调用它,生成虚假日志:

var filters = new FilterInfo(FilterProviders.Providers.GetFilters(controllerContext,actionDescriptor));
foreach (var authFilter in filters.AuthorizationFilters)
{
    authFilter.OnAuthorization(authContext);
    if (authContext.Result != null) {return false;}
}

有没有办法告诉(通过StackTrace或其他东西)OnAuthorization方法是显式调用,还是从属性调用?我目前最好的是
Environment.StackTrace.Contains(“在System.Web.Mvc.ControllerActionInvoker.InvokeAuthorizationFilters”).

解决方法

AuthorizeAttribute只承担一项责任:确定用户是否获得授权.由于各种不同的原因,这可以在应用程序的多个位置使用.

由于未被授权而采取的任何操作(例如返回HTTP 401响应)都被委托给ActionResult类型的处理程序,该处理程序设置为AuthorizationContext.Result属性.例如,以下是AuthorizeAttribute.HandleUnauthorizedRequest的认实现:

protected virtual void HandleUnauthorizedRequest(AuthorizationContext filterContext)
{
    // Returns HTTP 401 - see comment in HttpUnauthorizedResult.cs.
    filterContext.Result = new HttpUnauthorizedResult();
}

如果您在未授权用户时尝试进行审核,则应将审核放入ActionResult处理程序,而不是自定义AuthorizeAttribute.这确保仅在执行ActionResult时(即,当前页面未被授权时)执行审计,而不是在每种情况下都检查授权.

public class AuthorizeWithLoggingAttribute : AuthorizeAttribute
{
    protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
    {
        filterContext.Result = new LoggingActionResult(new HttpUnauthorizedResult(),filterContext);
    }
}

public class LoggingActionResult : ActionResult
{
    private readonly ActionResult innerActionResult;
    private readonly AuthorizationContext filterContext;

    public LoggingActionResult(ActionResult innerActionResult,AuthorizationContext filterContext)
    {
        if (innerActionResult == null)
            throw new ArgumentNullException("innerActionResult");
        if (filterContext == null)
            throw new ArgumentNullException("filterContext");

        this.innerActionResult = innerActionResult;
        this.filterContext = filterContext;
    }

    public override void ExecuteResult(ControllerContext context)
    {
        // Do logging (or apparently you want auditing) here
        Log(this.filterContext);

        innerActionResult.ExecuteResult(context);
    }
}

NOTE: I would name them AuthorizeWithAuditingAttribute and AuditingActionResult since you clearly want auditing,not logging in this case.

相关文章

在要实现单例模式的类当中添加如下代码:实例化的时候:frmC...
1、如果制作圆角窗体,窗体先继承DOTNETBAR的:public parti...
根据网上资料,自己很粗略的实现了一个winform搜索提示,但是...
近期在做DSOFramer这个控件,打算自己弄一个自定义控件来封装...
今天玩了一把WMI,查询了一下电脑的硬件信息,感觉很多代码都...
最近在研究WinWordControl这个控件,因为上级要求在系统里,...