加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

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

发布时间:2020-12-15 07:58:23 所属栏目:百科 来源:网络整理
导读:我在遗留MVC5项目中有一个自定义AuthorizeAttribute: public class AuthorizeWithLoggingAttribute : AuthorizeAttribute{ public override void OnAuthorization(AuthorizationContext filterContext) { if (!base.AuthorizeCore(httpContext)) {Log(Filte
我在遗留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.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读