让代码同时支持两种方式,登陆访问和带着请求头的token访问也可以。

首先做代码的重构

这里改成getSession() 改成这样以后会有一个问题,我用httpBasic登陆成功以后,我的用户信息放在session里面,后续的请求不用带Authorization的请求头也能访问。
我希望实现的效果是,如果你没登陆,那么你用HttpBasic这种方式来访问,每次你的头里面都要带着这个。然后除非你登陆了,访问的时候才可以不带这个头。那么要达到这个效果的话,我们需要来分辨下,哪些session是通过httpBasic这种方式建立的session。
像下面的这个getSesison就是通过httpBasic这种方式建立的。

还有一种是调用登陆方法,在登陆方法里面创建的session

想到达的效果就是,在httpBasic这种方式创建出来的session,在他方法调用结束以后,返回的时候把这个session销毁掉。
那么下次他再上来的时候session就没了。他就必须手里带着一个token,才能再啦访问这个请求。
那么要达到这个效果,就是在这里写个try finally

把过滤器的调用放在try里面。把过滤器的调用放在try里面。然后在finally里面让他失效掉。

这么写还有个问题就是登陆的那块的session也会失效掉。所以我需要做一个判断。在httpBasic的session中多加一个temp的session。判断它不为空, 就让session失效掉。

这样我们现在即支持登陆来访问也支持httpBasic访问

用UserInfo去接收

这里获取session里面的user改用UserInfo去接收了。那么存session的地方也要存成UserInfo这个类。、存的时候调用user.buildInfo()方法,转换成UserInfo对象即可。

原来在user写的方法要挪一下

把这段代码剪切到UserInfo里面

把这个属性也复制过去,注意是复制,不是剪切。

SecurityConfig

之前这里是写死的,现在我明确知道我要从session里面拿用户信息

那么Spring有一种静态的方法,可以让我们拿到session

强制转换。

从serveltRequestAttribute我们就可以拿到当前的request,再从request里拿到session

现在这个AuditorWare就可以根据真正的用户是谁,就可以拿到它的用户名来并返回。最终审计日志的时候,是当前登陆的用户名了。。


@Bean
public AuditorAware<String> auditorAware(){
return new AuditorAware<String>() {
@Override
public Optional<String> getCurrentAuditor() {
ServletRequestAttributes servletRequestAttributes=(ServletRequestAttributes)RequestContextHolder.getRequestAttributes();
UserInfo info=(UserInfo)servletRequestAttributes.getRequest().getSession().getAttribute("user");
String username=null;
if(info!=null){
username=info.getUsername();
}
//return Optional.of("jojo");
return Optional.ofNullable(username);
}
};
}
 

以上就重构完成了。

做退出操作

让session失效。UserController里面增加一个logout的方法

@GetMapping("/logout")
public void logout(HttpServletRequest request){
request.getSession().invalidate();//让sessin失效
}

然后这里也改成UserInfo


@GetMapping("/{id}")
public UserInfo get(@PathVariable Long id, HttpServletRequest request) throws Exception {
UserInfo user=(UserInfo) request.getAttribute("user"); if(user == null || !user.getId().equals(id)) {
throw new RuntimeException("身份认证信息异常,获取用户信息失败");
}
return userService.get(id);
}
 

修正自己代码的两处问题

一是在登陆的时候,UserController里面 往session存UserInfo对象的时候,写错了。这里之前是取的user对象,然后存的时候也是存user。 后面存的时候我自己忘了改了。 后来跟了下代码 发现是这里的问题。

二是在退出登陆的时候,要把退出的请求路径加入到排除列表里面。这样可以直接访问到logout,然后清空session。

运行系统


filter里面没有明显的是哪些代码是请求进来的时候调用,哪些代码是响应回去的时候调用,这样看起来不直观,不如拦截器的方法


拦截器的preHandler和afterCompletion看起来直观。 

现在是没带请求头也没登陆过。直接访问users/13 所以返回的是401

http://localhost:8080/users/13

带上我们的请求头

带上请求头就拿到用户信息了。

把请求头删掉依然不能访问,说明httpBasic每次请求响应回去session都被清除了。

测试登陆

登陆成功后,不带请求头访问我们的方法,因为我们是登陆过的,服务器端存了session

调用一下退出的方法

退出后,再调用getUser方法

以上就实现了我们想要的效果,我们这个方法支持两种认证方式。方法过程中有流控、身份认证、有审计、有授权等等
所有的安全机制应该都已经具备了。、

结束

Spring cloud微服务安全实战-3-13重构代码的更多相关文章

  1. 《Spring Cloud微服务 入门 实战与进阶》

    很少在周末发文,还是由于昨晚刚收到实体书,还是耐不住性子马上发文了. 一年前,耗时半年多的时间,写出了我的第一本书<Spring Cloud微服务-全栈技术与案例解析>. 时至今日,一年的 ...

  2. Spring Cloud微服务安全实战_00_前言

    一.前言: 一直以来对服务安全都很感兴趣,所以就学习.这是学习immoc的 jojo老师的 <Spring Cloud微服务安全实战课程>的笔记,讲的很好. 课程简介:  二.最终形成的架 ...

  3. Spring cloud微服务安全实战_汇总

    Spring cloud微服务安全实战 https://coding.imooc.com/class/chapter/379.html#Anchor Spring Cloud微服务安全实战-1-1 课 ...

  4. Spring Cloud微服务安全实战_4-5_搭建OAuth2资源服务器

    上一篇搭建了一个OAuth2认证服务器,可以生成token,这篇来改造下之前的订单微服务,使其能够认这个token令牌. 本篇针对订单服务要做三件事: 1,要让他知道自己是资源服务器,他知道这件事后, ...

  5. Spring Cloud微服务安全实战_4-3_订单微服务&价格微服务

    实现一个场景: 订单微服务: POM: <?xml version="1.0" encoding="UTF-8"?> <project xml ...

  6. Spring cloud微服务安全实战 最新完整教程

    课程资料获取链接:点击这里 采用流行的微服务架构开发,应用程序访问安全将会面临更多更复杂的挑战,尤其是开发者最关心的三大问题:认证授权.可用性.可视化.本课程从简单的API安全入手,过渡到复杂的微服务 ...

  7. Spring cloud微服务安全实战-6-8sentinel限流实战

    阿里2018年开源的. 简单来说就是干三件事,最终的结果就是保证你的服务可用,不会崩掉.保证服务高可用. 流控 先从最简单的场景来入手. 1.引用一个依赖, 2,声明一个资源. 3.声明一个规则 注意 ...

  8. Spring cloud微服务安全实战-6-4权限控制改造

    授权,权限的控制 令牌里的scope包含fly就有权限访问.根据Oauth的scope来做权限控制, 要让@PreAuthorize生效,就要在启动类里面写一个注解. 里面有一个属性叫做,就是在方法的 ...

  9. Spring cloud微服务安全实战-6-2JWT认证之认证服务改造

    首先来解决认证的问题. 1.效率低,每次认证都要去认证服务器调一次服务. 2.传递用户身份,在请求头里面, 3.服务之间传递请求头比较麻烦. jwt令牌. spring提供了工具,帮你在微服务之间传递 ...

  10. Spring cloud微服务安全实战-5-7实现基于session的SSO(客户端应用的Session有效期)

    授权模式改造成了Authorization code完成了改造的同时也实现了SSO.微服务环境下的前后端分离的单点登陆. 把admin的服务重启.刷新页面 并没有让我去登陆,直接就进入了首页. ord ...

随机推荐

  1. machine learning (3)---Linear Algebra Review

    Matrix Vector Multiplication 左边的矩阵向量相乘法比右边的更简洁而且计算高效 Matrix Matrix Multiplication 可以同时计算12个结果(4个房子面积 ...

  2. to_excel

    Signature: df.to_excel( ['excel_writer', "sheet_name='Sheet1'", "na_rep=''", 'fl ...

  3. Python之sort()函数详解

    #从小到大排列 print(sorted([36, 5, -12, 9, -21])) #将待排序的值放入到key中的函数中,在进行比较排序 print(sorted([36, 5, -12, 9, ...

  4. Kubernetes 学习22 kubernetes容器资源需求资源限制及HeapSter(翻车章节)

    一.概述 1.接下来介绍在k8s上运行pod对象时我们如何去监控我们系统级的资源指标以及业务级别的资源指标.数据如何获取和监控.在此之前先介绍一下Pod对象的资源请求和资源限制.即容器的资源需求和资源 ...

  5. 汇编知识之EIP寄存器

    eip寄存器存储着我们cpu要读取指令的地址,没有了它,cpu就无法读取下面的指令(通俗点讲cpu就无法执行.每次相应汇编指令执行完相应的eip值就会增加. 因为80386 cpu的寻址范围是4GB. ...

  6. 洛谷 P1147 连续自然数和 题解

    P1147 连续自然数和 题目描述 对一个给定的自然数MM,求出所有的连续的自然数段,这些连续的自然数段中的全部数之和为MM. 例子:1998+1999+2000+2001+2002 = 100001 ...

  7. 2019暑期金华集训 Day7 动态规划

    自闭集训 Day7 动态规划 LOJ6395 首先发现这个树的形态没啥用,只需要保证度数之和是\(2n-2\)且度数大于0即可. 然后设\(dp_{i,j}\)表示前\(i\)个点用了\(j\)个度数 ...

  8. GoCN每日新闻(2019-09-28)

     GoCN每日新闻(2019-09-28) 1. 可视化Go程序的调用图 https://truefurby.github.io/go-callvis/2. Go modules编写和发布官方教程 h ...

  9. sed 替换文件内容

    方法1:sed -i 's/被替换的内容/要替换成的内容/' file 方法2:sed 's/被替换的内容/要替换成的内容/g' file > file.out:mv file.out file ...

  10. CAS5.3服务环境搭建

    什么是Overlay overlay可以把多个项目war合并成为一个项目,并且如果项目存在同名文件,那么主项目中的文件将覆盖掉其他项目的同名文件.使用maven 的Overlay配置实现无侵入的改造c ...