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的错误。

重启网关服务



结束
Spring cloud微服务安全实战-6-5jwt改造之日志及错误处理(1)的更多相关文章
- 《Spring Cloud微服务 入门 实战与进阶》
很少在周末发文,还是由于昨晚刚收到实体书,还是耐不住性子马上发文了. 一年前,耗时半年多的时间,写出了我的第一本书<Spring Cloud微服务-全栈技术与案例解析>. 时至今日,一年的 ...
- Spring Cloud微服务安全实战_00_前言
一.前言: 一直以来对服务安全都很感兴趣,所以就学习.这是学习immoc的 jojo老师的 <Spring Cloud微服务安全实战课程>的笔记,讲的很好. 课程简介: 二.最终形成的架 ...
- Spring cloud微服务安全实战_汇总
Spring cloud微服务安全实战 https://coding.imooc.com/class/chapter/379.html#Anchor Spring Cloud微服务安全实战-1-1 课 ...
- Spring Cloud微服务安全实战_4-5_搭建OAuth2资源服务器
上一篇搭建了一个OAuth2认证服务器,可以生成token,这篇来改造下之前的订单微服务,使其能够认这个token令牌. 本篇针对订单服务要做三件事: 1,要让他知道自己是资源服务器,他知道这件事后, ...
- Spring Cloud微服务安全实战_4-3_订单微服务&价格微服务
实现一个场景: 订单微服务: POM: <?xml version="1.0" encoding="UTF-8"?> <project xml ...
- Spring cloud微服务安全实战 最新完整教程
课程资料获取链接:点击这里 采用流行的微服务架构开发,应用程序访问安全将会面临更多更复杂的挑战,尤其是开发者最关心的三大问题:认证授权.可用性.可视化.本课程从简单的API安全入手,过渡到复杂的微服务 ...
- Spring cloud微服务安全实战-6-8sentinel限流实战
阿里2018年开源的. 简单来说就是干三件事,最终的结果就是保证你的服务可用,不会崩掉.保证服务高可用. 流控 先从最简单的场景来入手. 1.引用一个依赖, 2,声明一个资源. 3.声明一个规则 注意 ...
- Spring cloud微服务安全实战-6-4权限控制改造
授权,权限的控制 令牌里的scope包含fly就有权限访问.根据Oauth的scope来做权限控制, 要让@PreAuthorize生效,就要在启动类里面写一个注解. 里面有一个属性叫做,就是在方法的 ...
- Spring cloud微服务安全实战-6-2JWT认证之认证服务改造
首先来解决认证的问题. 1.效率低,每次认证都要去认证服务器调一次服务. 2.传递用户身份,在请求头里面, 3.服务之间传递请求头比较麻烦. jwt令牌. spring提供了工具,帮你在微服务之间传递 ...
- Spring cloud微服务安全实战-5-7实现基于session的SSO(客户端应用的Session有效期)
授权模式改造成了Authorization code完成了改造的同时也实现了SSO.微服务环境下的前后端分离的单点登陆. 把admin的服务重启.刷新页面 并没有让我去登陆,直接就进入了首页. ord ...
随机推荐
- 二次封装Response类 | 视图类传递参数给序列化类context
二次封装Response类 源码: class Response(SimpleTemplateResponse): """ An HttpResponse that al ...
- The 2018 ACM-ICPC CCPC 宁夏 A-Maximum Element In A Stack
题意 对一个栈有入栈和出栈两种操作,求每次操作后栈的最大值的异或. 题目链接 分析 类似于单调栈,但是还没有那么复杂. 只需保持栈顶为最大值,如果入栈元素小于栈顶元素,则重复一次栈顶元素入栈:否则,直 ...
- 2019CCPC网络赛 HDU 6702——找规律
题意 给定 $A,B$(都是正整数),求使得 $(A\ xor\ C) \& (B \ xor \ C)$ 最小的正整数 $C$,如果有多个满足条件的 $C$,输出最小的 $C$. 分析 ...
- placeholder这个属性 input
input是一个很常见的标签,大家使用的也很常见,但是我在具体的工作中发现要想完美的使用这个标签还是任重而道远,下面是我碰到的几个问题. 1.我们在使用这个标签的时候会习惯的加上placeholder ...
- go协程的特点
go奉行通过通信来共享内存,不像c和c++通过共享内存来通信 协程是轻量级的线程,编译器做优化** 有独立的栈空间 共享程序堆空间 调度由用户控制 协程是轻量级的线程 并行:多个cpu共同执行 并发 ...
- 洛谷 P3372 【模板】线段树 1 题解
Analysis 新学了一种很骚气的线段树写法,就是把整个线段树放到一个struct里面,然后可以直接调用里面的函数 #include<iostream> #include<cstd ...
- Hive ACID和事务表支持详解
一.ACID介绍 ACID就是常见数据库事务的四大特性:Atomicity(原子性).Consistency(一致性).Isolation(隔离性).Durability(持久性). 在Hive 0. ...
- CODE FESTIVAL 2016 qual A题解
传送门 不知道为什么\(AGC\)系列的题里突然多了这些--那就做吧-- \(A\) 什么玩意儿-- upd:因为没看到最后要加换行居然没有\(1A\)好气哦-- const int N=15; ch ...
- 地区sql
/*Navicat MySQL Data Transfer Source Server : localhostSource Server Version : 50136Source Host : lo ...
- vue日常学习(2)
1.组件学习之内容分发 1.1 作用域插槽 父级 <div class="parent"> <child> <template scope=" ...