zoukankan      html  css  js  c++  java
  • Spring cloud微服务安全实战-6-5jwt改造之日志及错误处理(1)

    在代码里,我们没有认证或者授权的filter。认证和授权的工作现在基本上完全由Spring Security的过滤器接管了。

    本节就来看下 如何在Spring Security的过滤器链上加入我们自己的逻辑,因为现在这个过滤器链上只处理了认证和授权。我们还有其他的一些安全机制,比如说限流、日志。我们看下怎么把这些机制加到Spring的默认实现里面去,最后总结一下,到底都做了哪些事情,然后整个它的处理流程是什么样子的

    日志

    首先来写处理日志的过滤器。和我们之前的处理是类似的。

    继承OncePerRequestFilter


    这里一定注意不要用@Component注解把这个Filter声明成Spring 的Bean原因下面再讲。

    日志的这个过滤器应该是在认证的过滤器前面,在授权的过滤器前面。所以在这个过滤器里面,我应该知道当前用户是谁了。如果你的认证成功的话。
    前面认证的过滤器会把jwt的令牌转换成一个Authentication,然后把它放到SpringSecurityContext安全的上下文里面。

    通过下面的代码就可以把它从安全上下文里面再拿出来。principal就是我们申请令牌的时候的用户名。



    调用后面的过滤器处理完之后,还要再加一句日志更新,日志的成功还是失败,更新到数据库里面。这里我简单的用一个sysout来处理。把日志更新成处理成功。

    过滤器加到SpringSecurity配置中

    http的安全配置这里加一行。第一个addFilter一般不会去用.
    addFilterAfter、addFilterAt、addFilterBefore 就是你自己写的过滤器加到SpringSecurity的过滤器链上,指定一个位置。SpringSecurity过滤器链的顺序是固定的。所以你只要把你的过滤器加到spring的某一个过滤器的前面before或 后面after,at就是直接加入到这个过滤器的位置上。替换掉原来的过滤器。

    我们加的是一个日志过滤器,要加载授权的前面。用addFilterBefore

    前面是自己定义的过滤器,后面那个过滤器ExceptionTranslationFilter是Spring 用来转换异常的一个过滤器。我们最后会在授权的过滤器里面抛出异常。要不然是401需要身份认证,要不然是403需要权限。就这两种异常。两个异常抛出来以后,都会由这个过滤器来处理。

    刚才我们说不要把自己定义的GatewayAuditLogFilter声明称一个spring的Bean。SprintBoot默认情况下(如果声明成了Spring的Bean) ,会把这个过滤器直接加到web程序的过滤器链上。因为这个类继承了OncePreRequestFilter
    后面这里还有一个addFilter的操作。也就是说SpringBoot加了一次,自己这里写代码又加了一次。这个过滤器加入到过滤器的链上,加了两次。所以我们这里不声明称Spring成的Bean。这里只用代码加到链上一次。 

    启动测试

    首先是 认证服务器

    网关

    订单。

    申请令牌

    复制令牌

    去调用创建订单的服务。



    看一下 网关上的日志。说明进入了日志的过滤器里面。jojo是jwt内解析的用户名, 这说明日志是在认证的过滤器后面的。所以才会解析出当前的用户。

    第二句是在验证权限的服务,这里打印出来的。这就说明了日志过滤器在认证的过滤器之后,权限的过滤器之前生效的。

    在权限的过滤器判断完成后,最终还会回到日志的过滤器里面,把它的处理结果更新成处理成功。这个是我们想要的执行的顺序。

    异常处理

    多发几次创建订单的请求,因为是50%的成功率

    403访问被拒绝。

    这里并没有体现出来,请求是被拒绝掉的、现在的处理代码并没有处理这种情况,仍然是回到了日志Filter里面,把我的日志更新成功了。




    这个就是访问被拒绝 ,它的处理器


    默认的处理器就是返回下面这样的json

    我们可以自己定义自己的访问拒绝的处理器。在这个处理器里面我们可以记录日志,也可以自定义返回去的这个错误。这里只是针对没有权限403这种情况的一个处理。
    还有另外一种情况401,一会再说。
    我们要写的就是AccessDeniedHandler这个接口的实现。

    自定义错误处理handler



    直接继承一个父类。


    OAuth2AccessDeniedHandler是个默认的实现,如果不在网关的这里配置accessDeniedHandler这个配置的话。

    默认用的就是这个 OAuth2AccessDeniedHandler。在这里处理器里面,它会把异常 转换成一个简单的json也就是我们看到页面返回的403的json

    声明称Spring的Bean。然后覆盖handler方法。

    在这里能拿到request、response、抛出的exception。

    可以通过操作response,写你想写的错误信息。

    这里我们就加一句输出




    注入我们自己写的错误处理器

    这样在抛出403的错误异常的时候,我的控制台就会输出。

    重启网关服务。测试





    日志的过滤器里面又update了一次。更新为成功了。我们想要的是 如果报错了 就不再更新日志为成功


    最简单的做法是在request里面设置一个attributes。value值随便定义。




    attribute的值为空 就走更新成功。也就是没有抛出403的错误。

    重启网关服务



    结束

  • 相关阅读:
    mysql 数据类型学习笔记(持续更新)
    datetime 和 timestamp 的区别
    Jupyter notebook 常用快捷键(持续更新)
    遍历SnoMed的multiHierarchy中给定概念的子概念
    Ramdom Walk with Restart
    矩阵和向量
    power-law
    一些SQL操作(收集)
    MySQL5.7.19-win64安装启动
    OO_UNIT1_SUMMARY
  • 原文地址:https://www.cnblogs.com/wangjunwei/p/11980280.html
Copyright © 2011-2022 走看看