认证、授权、鉴权和权限控制

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问题相关推荐

  1. Java项目:在线淘房系统(租房、购房)(java+SpringBoot+Redis+MySQL+Vue+SpringSecurity+JWT+ElasticSearch+WebSocket)

    源码获取:博客首页 "资源" 里下载! 该系统有三个角色,分别是:普通用户.房屋中介.管理员.普通用户的功能:浏览房屋信息.预约看房.和中介聊天.申请成为中介等等.房屋中介的功能: ...

  2. SpringtBoot+SpringSecurity+Jwt+MyBatis整合实现用户认证以及权限控制

    文章目录 前言 数据库表结构 项目结构图 核心配置类SecurityConfig 实体类 工具类 用户登录认证 Token令牌验证 获取用户权限 用户权限验证 Service层实现类 统一响应类 Co ...

  3. SpringSecurity + JWT,从入门到精通!

    点击上方"朱小厮的博客",选择"设为星标" 后台回复"书",获取 链接:22j.co/bBbq 权限系统躲不开的概念,在Shiro和Spri ...

  4. SpringSecurity + JWT实现单点登录

    前面说了很多的理论知识,本文使用SpringSecurity + JWT来实现单点登录. 文章目录 什么是单点登陆 简单的运行机制 SpringSecurity整合JWT 认证思路分析 什么是单点登陆 ...

  5. Springboot+Spring-Security+JWT 实现用户登录和权限认证

    如今,互联网项目对于安全的要求越来越严格,这就是对后端开发提出了更多的要求,目前比较成熟的几种大家比较熟悉的模式,像RBAC 基于角色权限的验证,shiro框架专门用于处理权限方面的,另一个比较流行的 ...

  6. html jwt权限控制,SpringBoot+SpringSecurity+JWT实RESTfulAPI权限控制

    在整合jwt之前,我们首先要在SpringBoot中整合security的模块,来实现基于security的授权控制.用过security的人都知道,它的功能无比的强大比shiro还要强大,但是今天我 ...

  7. Java权限管理|基于springBoot+springSecurity+jwt实现前后端分离用户权限认证

    基于springBoot+springSecurity+jwt实现前后端分离用户权限认证 1. 项目说明   主要基于前后端分离情况下用户权限认证, 当用户登录认证成功后,每个用户会获取到自己的tok ...

  8. 厉害,我带的实习生仅用四步就整合好SpringSecurity+JWT实现登录认证

    小二是新来的实习生,作为技术 leader,我还是很负责任的,有什么锅都想甩给他,啊,不,一不小心怎么把心里话全说出来了呢?重来! 小二是新来的实习生,作为技术 leader,我还是很负责任的,有什么 ...

  9. SpringSecurity+JWT实现登陆验证的思路(有一点点源码分析)

    看了几个SpringSecurity+JWT的登陆demo,两个demo在一些细节实现上有一些不同,然后对于各个类和接口的关系比较模糊,就决定整理一下思路. 先简单的借用一下一位UP 三更草堂的图了解 ...

  10. SpringSecurity+JWT+OAuth2

    一个简洁的博客网站:http://lss-coding.top,欢迎大家来访 学习娱乐导航页:http://miss123.top/ 1. Spring Security 简介 1.1 概述 什么是安 ...

最新文章

  1. 全球顶级设计师云集天猫双11 超1000款时尚大牌新品首发
  2. 通过xrdp远程访问ubuntu出现输入d最小化问题的处理
  3. 一句话简单总结李航统计学习法各算法
  4. Visual Studio2017 远程调试 Remote Debugger
  5. 了解使用JavaScript进行面向对象编程的基础(并增强您的编码…
  6. springMVC 源码级别总结原理,DispatcherServlet核心方法
  7. linux 非阻塞 socket - Google 搜索
  8. 明年起网剧可参评白玉兰奖 你期待哪部网剧上榜?
  9. AI 芯片崛起!FPGA 工程师的核心竞争力在哪里?
  10. sql 2000简体中文企业版下载(含SP3 SP4 下载地址)
  11. spring三级缓存
  12. 嵌入式和单片机的区别在哪?
  13. Hive——多行转一行及一行转多行
  14. VOT Toolkit环境配置与使用
  15. SPADE 代码略解 ade20k数据集
  16. 软件测试基础 按照测试对象划分 界面测试(UI测试.响应式页面 可靠性测试 容错性测试 文档测试 平台测试 易用性测试等
  17. 单片机驱动蜂鸣器(有源和无源)
  18. java wrap()_Java中的CharBuffer wrap()方法
  19. 志强预测中国房价到2020年以后才可能会下降
  20. 内网直播(局域网直播)系统的搭建

热门文章

  1. Vue异步组件Demo 1
  2. linux基础总结1
  3. nodejs 密码加盐
  4. 采集的时候,列表的编码是gb2312,内容页的编码却是UTF-8,这种网站怎么采集?
  5. Fisher-Yates 乱序算法
  6. 精挑细选几个JavaScript库和工具
  7. 艾伟_转载:编写自文档化的代码
  8. 借助 Clay 编写 不可思议 的 c# 代码
  9. 【python入门到实践1】简介和环境搭建
  10. 实现透明防火墙的必备知识-Bridge Filter半景