让代码同时支持两种方式,登陆访问和带着请求头的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. java设计模式解析(11) Chain责任链模式

    设计模式系列文章 java设计模式解析(1) Observer观察者模式 java设计模式解析(2) Proxy代理模式 java设计模式解析(3) Factory工厂模式 java设计模式解析(4) ...

  2. JS基础篇之作用域、执行上下文、this、闭包

    前言:JS 的作用域.执行上下文.this.闭包是老生常谈的话题,也是新手比较懵懂的知识点.当然即便你作为老手,也未必真的能理解透彻这些概念. 一.作用域和执行上下文 作用域: js中的作用域是词法作 ...

  3. IDEA的安装和使用

    IDEA的特色功能 IDEA所提倡的是智能编码,是减少程序员的工作,IDEA的特色功能有以下22点 [1]  : ● 智能的选取 在很多时候我们要选取某个方法,或某个循环或想一步一步从一个变量到整个类 ...

  4. call,apply,bind的用法及区别

    <script> function test(){ console.log(this) } // new test(); //函数调用call方法的时候,就会执行. //call的参数:第 ...

  5. HDU6072 Logical Chain

    题意:动态修改图 \(G\) 的边集,求每次修改后的 \(\sum c\times (c−1) / 2\) (记每个强连通分量中的点数量为 \(c\) ).其中修改操作共 \(m\) 次,每次最多改 ...

  6. 五.划分LVM逻辑卷

    作用:    1.整合分散的空间    2.空间可以进行扩大   零散空闲存储 ---- 整合的虚拟磁盘 ---- 虚拟的分区   由众多的物理卷(PV)组合成卷组(VG),从卷组中划分多个逻辑卷(L ...

  7. IKVM

    $ ikvmc -target:library E:\jt400.jar    $ ikvmc -target:library -reference:E:\jt400.dll E:\FTU.jar   ...

  8. PHP实现系统编程(一) --- 网络Socket及IO多路复用【网摘】

    一直以来,PHP很少用于socket编程,毕竟是一门脚本语言,效率会成为很大的瓶颈,但是不能说PHP就无法用于socket编程,也不能说PHP的socket编程性能就有多么的低,例如知名的一款PHP ...

  9. VIJOS PID221 / 烦人的幻灯片

     暴力出奇迹,学长诚不欺我. PID221 / 烦人的幻灯片 2017-04-14 19:47:08 运行耗时:30 ms 运行内存:12292 KB 查看最后一次评测记录 题目描述 李教授于今天下午 ...

  10. 洛谷 P1966 火柴排队 题解

    归并排序 很玄学的一道题目,用另类的方法求出逆序对的数量就可以AC 我的思路是这样的: 按照题目,输入数据用两个数组a,b储存, 同时,用另外两个数组c,d分别对应前面两个a,b储存, 就是前面两个的 ...