zoukankan      html  css  js  c++  java
  • [C#].Net Core下全局自定义身份过滤器使用AllowAnonymous属性

    假设一种情况:项目中需要做认证和权限控制,而且需要权限才能访问的控制器要远多于可以匿名访问的(类似AO系统那样,登陆了才能用)。

    那在每个控制器上加一个 [Authorize] 是能解决问题,反正正我是觉得麻烦。

    而且Core自带的权限认证机制不满足于复杂的身份权限认证,打算像在Framework中一样注册一个全局过滤器,然后用 [AllowAnonymous] 来放行可以匿名的控制器或者方法。

    按照官方文档,自定义身份过滤器推荐实现 IAuthorizationFilter 或者 IAsyncAuthorizationFilter 接口,再顺便给他们定义为中间件更好。

    例如

     1     public class MyAuthorizeFilter : IAuthorizationFilter
     2     {
     3         public void OnAuthorization(AuthorizationFilterContext context)
     4         {
     5             //do something... 6         }
     7     }
     8 
     9     public class MyAsyncAuthorizeFilter : IAsyncAuthorizationFilter
    10     {
    11         public Task OnAuthorizationAsync(AuthorizationFilterContext context)
    12         {
    13             //do someting...14         }
    15     }
    MyAuthorizeFilter

    然后在Startup.cs中注册全局过滤器

    1         public void ConfigureServices(IServiceCollection services)
    2         {
    3             services.AddMvc(option => { option.Filters.Add(typeof(MyAuthorizeFilter)); });
    4         }

    可是运行时发现,自定义的过滤器无法阻止那些没有授权的请求!这是为什么?

    在控制器上加上  [Authorize] 调试

    发现实际上我的过滤器已经被加到了过滤器列队里,但是本身并没有执行任何动作。

    其实这里也是我自己犯傻了,人家就是一个接口而已,肯定没有任何操作,单纯继承接口以后指望人家能做什么呢。

    那我们既要实现原生的权限认证机制(毕竟像未登录跳转等功能不用自己实现了),还要增加自定义的认证机制。

    后来发现 [Authorize] 属性会被注册为AuthorizeFliter过滤器。那就妥了,继承然后重写其实现就好。

    我的过滤器就变成了这样。

     1 public class MyAuthorizeFilter : AuthorizeFilter
     2     {
     3 
     4         private static AuthorizationPolicy _policy_ = new AuthorizationPolicy(new[] { new DenyAnonymousAuthorizationRequirement() }, new string[] { });
     5 
     6         public MyAuthorizeFilter() : base(_policy_) { }
     7 
     8         public override async Task OnAuthorizationAsync(AuthorizationFilterContext context)
     9         {
    10             await base.OnAuthorizationAsync(context);
    11             Console.WriteLine("权限检测");
    12         }
    13     }

    说明一下实现AuthorizeFilter基类,必须有一个过滤策略,也就是,这里我采用的是最基础的DenyAnonymousAuthorizationRequirement(阻止匿名身份的请求)

    运行,过滤器可以正常过滤没有授权的请求了,但是无论授权与否,或者是否可匿名访问,均会执行“权限检测”那里。

    这是为啥?

    继续调试。

    发现 [AllowAnonymous] 也被注册成了过滤器。

    修改代码,最终成了这样

     1     public class MyAuthorizeFilter : AuthorizeFilter
     2     {
     3 
     4         private static AuthorizationPolicy _policy_ = new AuthorizationPolicy(new[] { new DenyAnonymousAuthorizationRequirement() }, new string[] { });
     5 
     6         public MyAuthorizeFilter() : base(_policy_) { }
     7 
     8         public override async Task OnAuthorizationAsync(AuthorizationFilterContext context)
     9         {
    10             await base.OnAuthorizationAsync(context);
    11             if (!context.HttpContext.User.Identity.IsAuthenticated ||
    12                 context.Filters.Any(item => item is IAllowAnonymousFilter)) return;
    13             //do something
    14         }
    15     }

    仅作为一个简单的学习笔记。如果有更好的方法欢迎指教。

    又及:

    在某篇博客中见过一个问题,大概就是说 context.HttpContext.User.Identity.IsAuthenticate 的值恒定false,后来采用了一大堆不啦不啦的方法自己实现了获取认证状态的方法。这篇博客我找不到了。

    我也遇到了类似的问题,后来发现是在startup的Configure中没有启用身份认证 app.UseAuthentication() ,根据自己的方法自行选择,例如我后来用IdentityServer4,就变成了 app.UseIdentityServer(); 

  • 相关阅读:
    视觉(9)争取快点看完基于图论的立体匹配算法
    STL笔记(2) STL之父访谈录
    视觉(7)Computer vision from Wikipedia
    *NIX工具使用(1) Vim notes
    STL笔记(1)map
    AI杂谈(1) 你喜欢ML里的哪些模型?希望ML未来向什么方向发展?
    AI杂谈(3): dodo:人脸识别方法个人见解(zz from prfans)
    AI杂谈(2)请教支持向量机用于图像分类
    视觉(3)blepo
    windows编程(2)深入探讨MFC消息循环和消息泵
  • 原文地址:https://www.cnblogs.com/kasimlz/p/7845574.html
Copyright © 2011-2022 走看看