记录SpringSecurity jwt问题
认证、授权、鉴权和权限控制
0.jwt 加签->验签 加签参数中包含:头部()负载(用户名,创建时间)验签:客户端传值与服务端算一致,别人篡改什么?用户名? 验签成功标识?失败提示什么?@篡改 用户名。1.token 错误,根据token 解析荷载是会报错,其实这里应该把异常抛出,token错误!
(业务:实际报异常:暂未登录或token已经过期,因为取了用户信息,取不到报错。不取用户不会报错,即便token错误)
验签:就是根据token 反解jwt,无token或token被篡改,回报异常,说明验签失败!
/**
* 从token中获取JWT中的负载
*/
private Claims getClaimsFromToken(String token) {
Claims claims = null;
try {
claims = Jwts.parser()
.setSigningKey(secret)
.parseClaimsJws(token)
.getBody();
} catch (Exception e) {
LOGGER.info("JWT格式验证失败:{}", token, e);
}
return claims;
}
1.注册后,用户信息怎么进入security的? @注册后没有存用户信息,是登录时,根据用户名查询数据库,然后存security。
2.权限怎么进去的 SecurityConfig configure 在这里从数据库查询权限,还有用户信息保存了,保存到哪里了?->AdminUserDetails 包含用户信息,权限信息,并提供对外接口
2.1 用户权限信息包含两部分 1.角色权限表 2.用户权限表,用户权限表数据怎么进去的(暂时业务没有用到)? @登录时,查数据库表,取权限赋值??不是登录时还是直接取UserDetailsService!!!。总结:登录赋值,调接口取值
3.sysUser 用户类 联系 @同一个
4.jwt 生成token原理
普通token只有过期时间与用户信息,而且会被伪造,jwt包含签名,不会被伪造。更像是一个签名
5.用户登录成功后,除了token,还有菜单权限数据,还有一个权限列表,这是个啥,权限值吗,有什么?鉴权吗? @前者只有菜单,后者包含所有,不只是权限,完整权限数据。应该不是控制权限,是控制数据是否展示。控制权限通过security注解
Map<String, Object> tokenMap = new HashMap<>();
tokenMap.put("token", token);
tokenMap.put("tokenHead", tokenHead);
tokenMap.put("authorities", SecurityUtils.getAuthentication().getAuthorities()); @包含所有权限
tokenMap.put("menuList", sysUserService.getMenuPermissionList(SecurityUtils.getUser().getId())); @只有菜单,没有按钮
tokenMap.put("uid", SecurityUtils.getUser().getId());
6.根据用户名,获取用户信息密码,权限原理,@ 是登录成功后,缓存了!!! 用户名哪里来:根据token获取,jwt中获取,因为登录生产jwt时,存入了用户名。
7.jwt 自定义鉴权过滤器 做什么 1.用户名是否正确 security中获取与token中是否一直,token中是当前登录人,为什么? @防止A登录成功,拿B的token取调接口,扩大权限,显然只判断有效期不行,2.token是否过期
8.UserDetailsService 根据用户名取用户信息,调用场景 登录时 1.登录取密码校验 2.jwt过滤器 验证用户名,token,最终从缓存中获取。但是入口在AdminUserDetails,说明在某时候数据进入了缓存 EhCache,进程内缓存,不支持分布式 @关于用户信息登录时,查库存security,其他接口直接取。
9.ums_admin_permission_relation 用户权限表中type=1含义 数据入口在->给用户分配+-权限,含义? @ 应该是增加删除权限,每次都是权限全量,与用户角色权限中权限比较,多:标记为+,少:标记为-,记的意义应该是保存记录
10.SecurityContext 取权限 赋值权限,但是权限值也是从UserDetails中获取,??此处哪里给?何时给?看上面:第8条
11.解决用户登录查库问题
首先,登录时是要查库,取用户与权限,只不过后面调接口时不必再查询数据库。
方式1.实现接口:UserDetailsService,重写方法,查询库把用户及权限信息写入,UserDetail接口。
方式2.重写配置类SecurityConfig 中 抽象类WebSecurityConfigurerAdapter userDetailsService方法
12.用户登录流程
虽然jwt配置了过滤登录请求,但是还是会走jwt过滤器(没有token 不会走jwt 认证及鉴权),然后到登录接口,根据用户名无法获得用户信息,说明用户名错误,抛出用户名密码错误。
如果密码错误,取到用户信息后,再比较密码,不正确抛出。那问题来了,为什么能获取用户信息???注册时缓存吗?@@@@查询数据库的!!每次都查询吗?应该是,之前有人说,不要每次查看?? @@@登录时,要查,调接口不再需要
13.权限来源于哪?UsernamePasswordAuthenticationToken 赋值过两次权限,都是从数据库查询用户权限,然后给到token。场景:1.登录 2.jwt过滤器(调用非登录接口时)。应该没有缓存,都是实时取表 @ 查库只有登录时,jwt过滤器也是取登录时赋值。jwt过滤器赋值权限,应该是注解鉴权时,跟这里比较。登录时,给了权限,为什么这里还要给??
if (jwtTokenUtil.validateToken(authToken, userDetails)) {
UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
LOGGER.info("authenticated user:{}", username);
SecurityContextHolder.getContext().setAuthentication(authentication);
}
登录成功后,把信息赋值UserDetail接口(重写),后面调用其他接口,可以直接获取用户名。
正常的应该只需要登录时查询数据库,取出权限,后面调接口从缓存中获取,这里就涉及一个缓存刷新问题??? @@@应该是这样。
14.当未登录或者token失效,(无token或错误,无法根据token反解jwt,报异常,到下一个过滤链,进入自定义异常)访问接口时,自定义的返回结果 RestAuthenticationEntryPoint 调用接口未带token,来这里,{
"code": 401,
"data": "Full authentication is required to access this resource",
"msg": "暂未登录或token已经过期"
}
15.访问接口时,可获取当前用户所有权限,具体怎么校验有没有权限,登录后,会返回菜单和权限,这时候前端会处理,没有就看不到菜单或者按钮。但是通过接口怎么拦截?@通过security注解,@PreAuthorize 在每一个接口上加权限。
@PreAuthorize("hasAuthority('product')")
@GetMapping("myRoom")
@ApiOperation("我的直播间")
public BaseResult<ResTextLiveProgramVo> myChatRoom() {
return textLiveProgrammeService.myChatRoom();
}
16.自定义:登录失败处理器,两种方式
@Component
//public class RestAuthenticationEntryPoint implements AuthenticationEntryPoint {
public class RestAuthenticationEntryPoint implements AuthenticationFailureHandler {
@Override
public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException, ServletException {
response.setCharacterEncoding("UTF-8");
response.setContentType("application/json");
response.getWriter().println(JSON.toJSONString(BaseResult.unauthorized(authException.getMessage())));
response.getWriter().flush();
}
@Override
public void onAuthenticationFailure(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse,
AuthenticationException e) throws IOException, ServletException {
}
}
实际代码中并没有采用以上任意一种,而是在登录时,捕获了用户或密码错误异常,统一返回报错。
16.验证权限
无权限报错: 不允许访问
在接口添加权限限制 @PreAuthorize("hasAuthority('product')
问题
1.没走自定义无权限,直接报:不允许访问
2.原理是什么,异常从哪抛出的
3.不手动添加权限限制,直接调接口,怎么实现鉴权 @ 每一个接口都是手动给权限
17.登出
jwt 在有效期一直可用,无失效逻辑。
token:之前都是存在redis有失效机制。
需要做两件事
1.前端删除token
2.自定义登录处理器,并在security中配置,把请求头token设置为空。
登出过滤器
@Component
public class JwtLogoutSuccessHandler implements LogoutSuccessHandler {
@Override
public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication)
throws IOException, ServletException {
if (Objects.nonNull(authentication)) {
new SecurityContextLogoutHandler().logout(request, response, authentication);
}
response.setContentType("application/json;charset=UTF-8");
ServletOutputStream outputStream = response.getOutputStream();
response.setHeader("Authorization", "");
BaseResult result = BaseResult.success("");
outputStream.write(JSON.toJSONString(result).getBytes("UTF-8"));
outputStream.flush();
outputStream.close();
}
}
18 SecurityConfig jwt直接关联
在security配置类中加 入jwt过滤器
1.创建实例
@Bean
public JwtAuthenticationTokenFilter jwtAuthenticationTokenFilter(){
return new JwtAuthenticationTokenFilter();
}
2.添加JWT filter
httpSecurity.addFilterBefore(jwtAuthenticationTokenFilter(), UsernamePasswordAuthenticationFilter.class);
19.jwt 存在问题
https://blog.csdn.net/hanxiaotongtong/article/details/103347063
20.token刷新
1.接口请求请求头带 token, Authorization:token
2.刷新token,只是在jwt生产token中,更新了创建时间
21.jwt作用
1.认证 根据判断用户名,密码 jwt加签存了用户信息,验签验证身份
2.鉴权,权限不足 @主要由security完成,只是利用了jwt过滤器
22.spring Security 如何保存权限信息
UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(userDetails,
null, userDetails.getAuthorities());
SecurityContextHolder.getContext().setAuthentication(authentication);
涉及到上下文
public interface SecurityContext extends Serializable {
Authentication getAuthentication();
void setAuthentication(Authentication var1);
}
SecurityContextHolder.getContext().setAuthentication(authentication);
把权限信息给到给到上下问Context,两个地方,登录时,jwt验证后。登录后,已经把用户权限给context,为什么调接口还要赋值
if (username != null && SecurityContextHolder.getContext().getAuthentication() == null),因为jwt判断为null才赋值,为什么为空
23.每次登录成功后,把用户及权限信息,保存到上下文,怎么实现用户隔离
参考文档:
http://www.cocoachina.com/articles/42621
https://zhengkai.blog.csdn.net/article/details/96290686
赋值权限
AdminUserDetails(自定义认证主体,包含用户信息及权限信息类。认证:及校验密码,成功后,设置创建一个实现了 Authentication接口的对象,给上下文)-> UserDetails -> UsernamePasswordAuthenticationToken ->Authentication->SecurityContext->-ThreadLocal(又保存到httpSession,取的时候从这里)-@> SecurityContextHolder
SecurityContextHolder 是如何存储 SecurityContext 的。 ThreadLocalSecurityContextHolderStrategy 怎么存储到ThreadLocal
https://www.it610.com/article/1281109153997144064.htm
https://www.bbsmax.com/A/gVdnpGr1JW/
https://blog.csdn.net/liuyanglglg/article/details/104742799
https://blog.csdn.net/weixin_34366546/article/details/87994814?utm_medium=distribute.pc_relevant.none-task-blog-2~default~baidujs_title~default-0.no_search_link&spm=1001.2101.3001.4242
【FilterChain】【HttpSession】【SecurityContextPersistenceFilter】
SecurityContextPersistenceFilter:
该Filter的作用主要是创建一个空的SecurityContext(如果session中没有SecurityContext实例),然后持久化到session中
HttpSessionSecurityContextRepository
context 与httpsessin 绑定,为什么存在httpSession ,为什么也要保存到ThreadLocal
https://cloud.tencent.com/developer/article/1361030
https://blog.didispace.com/xjf-spring-security-4/ 比较全的源码分析
https://blog.didispace.com/xjf-spring-security-3/
SecurityContextPersistenceFilter 两个主要职责:请求来临时,创建SecurityContext安全上下文信息,请求结束时清空
请求来临时 指调用接口吗,请求结束接口执行完成吗?创建context是不是应该登录时创建。
https://www.bbsmax.com/A/gVdnpGr1JW/
https://www.it610.com/article/1281109153997144064.htm
https://zhengkai.blog.csdn.net/article/details/96290686
http://www.cocoachina.com/articles/42621
https://www.shuzhiduo.com/A/QW5YV87Gdm/
https://www.cnblogs.com/felordcn/p/12142491.html
https://blog.csdn.net/andy_zhang2007/article/details/91955225
https://my.oschina.net/u/2518341/blog/1982933
https://blog.csdn.net/qq_35067322/article/details/103209951
https://www.cnblogs.com/longfurcat/p/10293819.html
https://cloud.tencent.com/developer/article/1361030
https://blog.csdn.net/liuyanglglg/article/details/104742799
https://blog.csdn.net/weixin_34366546/article/details/87994814?utm_medium=distribute.pc_relevant.none-task-blog-2~default~baidujs_title~default-0.no_search_link&spm=1001.2101.3001.4242
https://blog.csdn.net/fengyilin_henu/article/details/84916822
https://www.cnblogs.com/longfurcat/p/10574734.html
1.使用security 依赖,配置(方法级别)
jwt:
tokenHeader: Authorization
secret: mySecret
# 60*60*24
expiration: 604800 s /60/60 168 7天有效期
tokenHead: Bearer
UserDetails:构建Authentication对象必须的信息,可以自定义,可能需要访问DB得到
SpringSecurity JWT
认证、授权、鉴权和权限控制
1.JWT作用:身份认证(token生成与校验)
生成与校验场景:生成:用户登录;校验:用户进行操作时,走JWT过滤器,从请求头中获取token,根据token反解JWT中的负载。
成功失败标志:从token中反解JWT中的负载时,如果异常,说明认证失败,无异常则认证成功
2.SpringSecurity:授权,鉴权
授权:创建用户选择权限及管理员分配权限,需要权限控制的方法上加注解:@PreAuthorize("hasAuthority('sys:role:update')")
SpringSecurity如何管理权限:接口请求走JWT过滤器,实时查数据库取用户基本信息与权限信息。
存在哪里:
怎么获取:
https://blog.csdn.net/u012702547/article/details/89629415
https://blog.csdn.net/weixin_39915815/article/details/111038973?utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7Edefault-6.nolandingword2&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7Edefault-6.nolandingword2
记录SpringSecurity jwt问题相关推荐
- Java项目:在线淘房系统(租房、购房)(java+SpringBoot+Redis+MySQL+Vue+SpringSecurity+JWT+ElasticSearch+WebSocket)
源码获取:博客首页 "资源" 里下载! 该系统有三个角色,分别是:普通用户.房屋中介.管理员.普通用户的功能:浏览房屋信息.预约看房.和中介聊天.申请成为中介等等.房屋中介的功能: ...
- SpringtBoot+SpringSecurity+Jwt+MyBatis整合实现用户认证以及权限控制
文章目录 前言 数据库表结构 项目结构图 核心配置类SecurityConfig 实体类 工具类 用户登录认证 Token令牌验证 获取用户权限 用户权限验证 Service层实现类 统一响应类 Co ...
- SpringSecurity + JWT,从入门到精通!
点击上方"朱小厮的博客",选择"设为星标" 后台回复"书",获取 链接:22j.co/bBbq 权限系统躲不开的概念,在Shiro和Spri ...
- SpringSecurity + JWT实现单点登录
前面说了很多的理论知识,本文使用SpringSecurity + JWT来实现单点登录. 文章目录 什么是单点登陆 简单的运行机制 SpringSecurity整合JWT 认证思路分析 什么是单点登陆 ...
- Springboot+Spring-Security+JWT 实现用户登录和权限认证
如今,互联网项目对于安全的要求越来越严格,这就是对后端开发提出了更多的要求,目前比较成熟的几种大家比较熟悉的模式,像RBAC 基于角色权限的验证,shiro框架专门用于处理权限方面的,另一个比较流行的 ...
- html jwt权限控制,SpringBoot+SpringSecurity+JWT实RESTfulAPI权限控制
在整合jwt之前,我们首先要在SpringBoot中整合security的模块,来实现基于security的授权控制.用过security的人都知道,它的功能无比的强大比shiro还要强大,但是今天我 ...
- Java权限管理|基于springBoot+springSecurity+jwt实现前后端分离用户权限认证
基于springBoot+springSecurity+jwt实现前后端分离用户权限认证 1. 项目说明 主要基于前后端分离情况下用户权限认证, 当用户登录认证成功后,每个用户会获取到自己的tok ...
- 厉害,我带的实习生仅用四步就整合好SpringSecurity+JWT实现登录认证
小二是新来的实习生,作为技术 leader,我还是很负责任的,有什么锅都想甩给他,啊,不,一不小心怎么把心里话全说出来了呢?重来! 小二是新来的实习生,作为技术 leader,我还是很负责任的,有什么 ...
- SpringSecurity+JWT实现登陆验证的思路(有一点点源码分析)
看了几个SpringSecurity+JWT的登陆demo,两个demo在一些细节实现上有一些不同,然后对于各个类和接口的关系比较模糊,就决定整理一下思路. 先简单的借用一下一位UP 三更草堂的图了解 ...
- SpringSecurity+JWT+OAuth2
一个简洁的博客网站:http://lss-coding.top,欢迎大家来访 学习娱乐导航页:http://miss123.top/ 1. Spring Security 简介 1.1 概述 什么是安 ...
最新文章
- 全球顶级设计师云集天猫双11 超1000款时尚大牌新品首发
- 通过xrdp远程访问ubuntu出现输入d最小化问题的处理
- 一句话简单总结李航统计学习法各算法
- Visual Studio2017 远程调试 Remote Debugger
- 了解使用JavaScript进行面向对象编程的基础(并增强您的编码…
- springMVC 源码级别总结原理,DispatcherServlet核心方法
- linux 非阻塞 socket - Google 搜索
- 明年起网剧可参评白玉兰奖 你期待哪部网剧上榜?
- AI 芯片崛起!FPGA 工程师的核心竞争力在哪里?
- sql 2000简体中文企业版下载(含SP3 SP4 下载地址)
- spring三级缓存
- 嵌入式和单片机的区别在哪?
- Hive——多行转一行及一行转多行
- VOT Toolkit环境配置与使用
- SPADE 代码略解 ade20k数据集
- 软件测试基础 按照测试对象划分 界面测试(UI测试.响应式页面 可靠性测试 容错性测试 文档测试 平台测试 易用性测试等
- 单片机驱动蜂鸣器(有源和无源)
- java wrap()_Java中的CharBuffer wrap()方法
- 志强预测中国房价到2020年以后才可能会下降
- 内网直播(局域网直播)系统的搭建