让代码同时支持两种方式,登陆访问和带着请求头的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. toapi模块简单使用

    toapi是一个api与爬虫结合的一个库,使用简单,可以自定义api展示,简单的mockserver,但只限制于get请求 toapi会在同级目录下建立缓存机制,再次访问就会读缓存了 安装: pip ...

  2. 《CoderXiaoban》第八次团队作业:Alpha冲刺1

    项目 内容 这个作业属于哪个课程 任课教师博客主页链接 这个作业的要求在哪里 实验十二 团队作业8:软件测试与ALPHA冲刺 团队名称 Coderxiaoban团队 作业学习目标 (1)掌握软件测试基 ...

  3. [PKUSC2018]主斗地

    暴搜 非常暴力的搜索,以至于我都不相信我能过. 方法是:暴力枚举所有牌型,然后暴力判断是否可行. 暴力枚举部分: 非常暴力: void dfs(int x,int l){ if(l==0){ flag ...

  4. [Angular] How to show global loading spinner for application between page navigation

    app.component.ts: import { Component, OnInit } from "@angular/core"; import { select, Stor ...

  5. xml文件整理

    xml 97-2003 格式 \s*\n\s*\n\s*\n\s*\n\n(^个人补充信息.*)\n(.*)\n(^总成绩.*)$1$2\n$3(^个人补充信息.*)\n(.*)\n(.*)\n(^总 ...

  6. [俺们学校的题]伪.GCD

    GCD 题面: 给定整数N,求1<=x,y<=N且Gcd(x,y)为素数的数对(x,y)有多少对. 思路: 首先两个数gcd(x,y)=p为质数,那么令x=k1*p,y=k2*p,由于是最 ...

  7. cube.js 学习(四)cube.js cube 说明

      cube 是cube.js data schema 的核心,里面定义了生成sql 的说明 一个比较全的schema 例子 cube(`Users`, { sql: `select * from u ...

  8. ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/usr/local/mysql/mysql.sock' (2)

    这种情况一般是mysql被杀掉了. 要重新启动. ps -A | grep -i mysql kill 列出来的进程 service mysql start 我的问题就解决了    

  9. AtCoder Grand Contest 006 题解

    传送门 \(A\) 咕咕 const int N=105; char s[N],t[N];int n; inline bool eq(R int k){fp(i,1,k)if(s[n-k+i]!=t[ ...

  10. 数据结构实验之排序三:bucket sort (SDUT 3400)

    桶排序: #include <stdio.h> #include <string.h> int a[5555555]; int main() { int n,m; scanf( ...