---Spring Security是配置在具有登录功能的前后端交互项目中
配置要点:
首先一个项目想要有Spring Security支持,需要先在
org.springframework.boot
spring-boot-starter-security
io.jsonwebtoken
jjwt
0.9.1
com.alibaba
fastjson
1.2.75
继承WebSecurityConfigurerAdapter
还有两个重要的Bean要加上,PasswordEncoder以及AuthenticationManager
1约定密码编码格式,2用于后续认证操作的操作器
Security过滤器里边要声明白名单路径,然后制定访问控制策略,比如常用的是将OPTION请求放行
因为OPTION请求是请求中有复杂数据时会出现的一种请求,这种请求并没有实际数据,是由浏览器发起的,只是询问是否可以接收处理复杂请求,算是一个预检,我们可以直接放行,即告诉浏览器OK,
对于其他的请求我们都要求其具有认证.最后在这个配置Security的配置类中我们还要在最后将Jwt的过滤器加进来,因为对于密码等的验证Security框架是自动进行的,我们需要将Jwt的验证优先级提一下,让他在Security自动处理数据之前运行.
Jwt过滤器
Jwt过滤器即是处理那些没有被Security配置通过的请求,当接收到一个请求,本类会先将当前Security上下文中的认证信息清空,然后将请求头里的数据根据约定的消息头Authorization提取出来(未提取到直接放行,未将认证信息写入上下文就等着被拦截),这个对应的就是Jwt,然后对Jwt进行反解析(用到Jwt工具类),这句反解析的代码是可能抛出异常的,Jwt过期以及错误异常,当没有异常抛出时,就认为这个认证信息是有效的,由于往Jwt里边封装数据只能是以Map的形式,这里我们也是用get("
Jwt工具类:
封装将Map
封装解析Jwt数据回到Map
用户名:
AdminDetails[注1]是就是个用户名属性,到往jwt转换的时候也是用户名,直到被提取出来往Security上下文里边装的时候才与id封装成为个人主体信息AdminPrincipal
权限:
权限起初都是放在数据库中的字符串,当查询时我们将这一条条权限(String)放到了List集合中,因此我们根据用户名 查询得到的AdminLoginVO中permission是一个List
JSON.toJSONString(List<>) ,jwt解析出来后又可以
JSON.parseArray(
, <集合中数据类型>.class)恢复为List<集合中数据类型>,他会以这个形式写入Security上下文.
[注1]
AdminDetail数据类型是我们因为其原本UserDetails类型没有id属性,UserDetails是User类型的一个实现,因此我们继承了User类再声明一个id属性,然后写了一个具有id属性的构造方法,在方法体中super父类实现 方法,然后将this.id=id;AdminDetails,这样使用AdminDetails创建的数据对象就具有id属性了,后续可get调用.
在Security配置类上加此注解,开启全局授权访问检查
@EnableGlobalMethodSecurity(prePostEnabled = true)
在Controller方法上加注解,配置访问权限
@PreAuthorize("hasAnyAuthority('/ams/admin/update')")
用户输入的用户名,密码被封装着传入Controller,然后被解开放到AdminDetails里边根据名字查找对应的对象,没查到就直接返回null,在外边null就直接抛出异常了,不是null就将找到的数据封装起来成为一个AdminDetails对象送到外边进行认证,认证通过就继续往下走,提取(用户名,id,权限) 注意这个信息是放在验证用户登录信息返回的对象的principal中,可以get后直接强转成AdminDetails,注意权限List集合要转为String类型然后往map里边放,最后将map传给Jwt工具类转换成jwt码,以
JsonResult.ok(jwt)
返回,方便前端调用
前端在发送登陆请求,登陆成功后通过response.data.data获取jwt,setItem到localStorage,让其他请求可以直接getItem,然后发请求放上这个请求头
this.axios.create({
headers: {
Authorization: jwtItem
}
}).post/get…