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

前端之家收集整理的这篇文章主要介绍了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.

猜你在找的C#相关文章