Redis反序列化的一次问题

news2024/11/15 21:03:03

redis反序列化的一次问题

1. 问题描述

springboot+redis不少用,但是一直没遇到什么问题,直接代码拷贝上去就用了。这次结合spring-security,将自定义的spring-security的UserDetails接口的实现类SecurityUser,反序列化取出时报错。

在这里插入图片描述

org.springframework.data.redis.serializer.SerializationException: Could not read JSON: Cannot construct instance of `com.jankin.inoteadmin.security.entity.SecurityUser` (no Creators, like default constructor, exist): cannot deserialize from Object value (no delegate- or property-based Creator)
	......
org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer.deserialize(GenericJackson2JsonRedisSerializer.java:165)

2. 问题解读

我猜肯定有人骂我了,上面问题描述不是很清晰了吗 no Creators, like default constructor, exist 。我的回答是,该骂,大骂特骂~

作为一名不称职的代码搬砖工,我遇到问题时,第一是间是查看是否实现了Serializable接口。确认父接口UserDetails实现了该接口还不死心,然后在本类中添加该接口,保存运行,报错依旧。慌了,按道理没道理啊,之前项目也是直接这样引依赖,建个RedisConfig类就行了啊,然后就打开百度……

结果还百度不出……(估计是没有人连这种问题需要百度,所以搜不到)

好,言归正传,问题就如上述所说,没有默认够构造器,也就是无参构造器。

我依稀记得大学教我java的老师,说到构造器时,反复强调,无论你建多少个有参构造器,都必须带上无参构造器,毕业后其实一直遵守老师所说的,每次建造构造方法时,都会建无参构造方法,lombok的 @AllArgsConstructor@NoArgsConstructor我一直都是连着用的。这次没用不是因为忘记了,而是SpringSecurity中自带的UserDetails实现类org.springframework.security.core.userdetails.User 本身就没带无参构造器,并且,其中的类属性还带上了final关键字,意思是在声明时或者构造方法中必须定义初始值。

好嘛,SpringSecurity默认的User都没问题,我自定义的SecurityUser仿照应该问题也不大。

然后就出这档子事儿了。

扯远了,总而言之啊,就是spring中redis的反序列化需要依赖无参构造器

3. 问题解决

那就加上无参构造器呗,SpringSecurity的自定义的SecurityUser还需要将对象属性的final关键字去掉。

public class SecurityUser implements UserDetails{

    private static final long serialVersionUID = 1L;

    private String userId;
    private String password;
    private String username;
    private Set<GrantedAuthority> authorities;
    private boolean accountNonExpired;
    private boolean accountNonLocked;
    private boolean credentialsNonExpired;
    private boolean enabled;
    
    /**
     * 无参构造器
     */
    public SecurityUser(){}

    /**
     * Simple Param Constructor
     * @param userId 用户id
     * @param password  用户密码
     * @param username  用户名
     * @param authorities   权限列表
     */
    public SecurityUser(String userId, String username, String password, Set<GrantedAuthority> authorities) {
        this(userId,username,password,authorities,
                true,true,true,true);
    }

    /**
     * AllParamConstructor
     * @param userId 用户id
     * @param password  用户密码
     * @param username  用户名
     * @param authorities   权限列表
     * @param accountNonExpired 账号没过期
     * @param accountNonLocked  账号没被锁
     * @param credentialsNonExpired 凭证没过期
     * @param enabled   正常
     */
    public SecurityUser(String userId, String username, String password, Set<GrantedAuthority> authorities,
                        boolean accountNonExpired, boolean accountNonLocked,
                        boolean credentialsNonExpired, boolean enabled) {
        this.userId = userId;
        this.username = username;
        this.password = password;
        this.authorities = Collections.unmodifiableSet(authorities);
        this.accountNonExpired = accountNonExpired;
        this.accountNonLocked = accountNonLocked;
        this.credentialsNonExpired = credentialsNonExpired;
        this.enabled = enabled;
    }
    // other todo
}

一点点题外话

作者还没做过什么大型项目,单体应用上看,前后端分离的情况下SpringSecurity的认证和授权根本上就是两个Filter和AOP做注解鉴权就行,感觉没有必要用SpringSecurity,之前用的shiro,也用过sa-token,相比之下,SpringSecurity是真的复杂,前后端分离情况下,SpringSecurity的UserDetailsService也拉,不好做缓存认证。

说到SpringSecurity的认证,网上很多方案都是使用jwt做token认证标识,对于jwt做下线功能该怎么做呢,jwt一旦颁发就只能到期失效。这样token被盗用的话一点办法都没有。有人说在缓存或数据库中添加signature的加密串,或者用账户密码做加密串,这样下线时或者更改密码时修改加密串就行……这样做确实能解决jwt的失效问题,但是jwt的主要特点(优点)就是无状态,每次认证只需要依赖jwt本体就行,这样数据库或者缓存添加jwt的加密串,岂不是违背了原本jwt的初衷?这样和使用普通token,用token做key缓存用户登录状态信息有什么区别。

虽然言语略带偏激,但是确实是心中疑问,有朋友看到且有见解的话,还请指教一下。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1364556.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Packet Tracer - Configure Cisco Routers for Syslog, NTP, and SSH Operations

Packet Tracer - 配置Cisco路由器以实现Syslog、NTP和SSH功能 地址表 目标&#xff1a; 配置OSPF MD5身份验证。配置NTP服务。设置路由器将消息记录到syslog服务器。配置R3路由器以支持SSH连接。 背景/场景&#xff1a; 在本练习中&#xff0c;您将配置OSPF MD5身份验证以实…

一文快速搞懂Nginx —— Nginx 详解

一文快速搞懂Nginx 一、niginx 简介二、正向 / 反向代理2.1 正向代理2.2 反向代理 三、负载均衡四、动静分离五、web 缓存六、Niginx 安装6.1 windows版本下的安装6.2 Linux版本下的安装 七、常用命令八、为什么选择Nginx 一、niginx 简介 Nginx 同 Apache 一样都是一种 Web 服…

C语言光速入门笔记

C语言是一门面向过程的编译型语言&#xff0c;它的运行速度极快&#xff0c;仅次于汇编语言。C语言是计算机产业的核心语言&#xff0c;操作系统、硬件驱动、关键组件、数据库等都离不开C语言&#xff1b;不学习C语言&#xff0c;就不能了解计算机底层。 目录 C语言介绍C语言特…

PAT 乙级 1056 组合数的和

给定 N 个非 0 的个位数字&#xff0c;用其中任意 2 个数字都可以组合成 1 个 2 位的数字。要求所有可能组合出来的 2 位数字的和。例如给定 2、5、8&#xff0c;则可以组合出&#xff1a;25、28、52、58、82、85&#xff0c;它们的和为330。 输入格式&#xff1a; 输入在一行…

水母目标检测数据集VOC格式500张

水母&#xff0c;一种美丽而神秘的海洋生物&#xff0c;以其独特的形态和生态习性而备受瞩目。 水母的体型呈伞状&#xff0c;身体透明&#xff0c;有各种颜色和花纹。它们没有骨骼&#xff0c;身体由胶状物质组成&#xff0c;非常柔软和脆弱。水母通过触手上的刺细胞释放毒素…

Unity 一文掌握使用AddListener方法为组件事件添加监听器的方法

在Unity中&#xff0c;很多组件都带有事件&#xff0c;比如: Button组件&#xff1a;onClick() Toggle组件&#xff1a;On Value Changed(Boolean) Dropdown组件&#xff1a;On Value Changed(Int32) InputField组件&#xff1a;On Value Changed(String)、On End Edit(Stri…

【leetcode】力扣算法之有效的数独【中等难度】

题目描述 请你判断一个 9 x 9 的数独是否有效。只需要 根据以下规则 &#xff0c;验证已经填入的数字是否有效即可。 数字 1-9 在每一行只能出现一次。数字 1-9 在每一列只能出现一次。数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。&#xff08;请参考示例图&…

CodeWave智能开发平台--03--目标:应用创建--07供应商数据表格

摘要 本文是网易数帆CodeWave智能开发平台系列的第09篇&#xff0c;主要介绍了基于CodeWave平台文档的新手入门进行学习&#xff0c;实现一个完整的应用&#xff0c;本文主要完成07供应商数据表格 CodeWave智能开发平台的09次接触 CodeWave参考资源 网易数帆CodeWave开发者…

Micro-app 微前端框架demo介绍

Micro-app 框架 1、框架安装 npm i micro-zoe/micro-app --save2、子应用对应的view页面 <template><div><!-- name(必传)&#xff1a;应用名称url(必传)&#xff1a;应用地址&#xff0c;会被自动补全为http://localhost:3000/index.htmlbaseroute(可选)&…

mysql进阶-重构表

目录 1. 原因 2. 如何重构表呢&#xff1f; 2.1 命令1&#xff1a; 2.2 命令2&#xff1a; 2.3 命令3&#xff1a; 1. 原因 正常的业务开发&#xff0c;为什么需要重构表呢&#xff1f; 原因1&#xff1a;某张表存在大量的新增和删除操作&#xff0c;导致表经历过大量的…

Kali Linux——设置中文

【问题现象】 从下图可以看到&#xff0c;菜单全是英文的。对于英文不好的同学&#xff0c;使用起来很难受。 【解决方法】 1、获取root权限 su root 2、进入语言设置 dpkg-reconfigure locales 3、选择zh_CN.UTF-8 UTF-8 4、设置默认 5、安装完成 6、重启虚拟机 reboot…

多租户看这一篇就够了

什么是多租户&#xff1f;举个例子&#xff1a;马云、马化腾和刘强东三个人去租房子&#xff0c;他们因为家里经济困难所以勤工俭学&#xff0c;三个人决定合租一套三室一厅的房子&#xff0c;虽然每个人有自己的房间&#xff0c;但是家里的水电、厨房、卫生间和热水器都是大家…

强化学习的数学原理学习笔记 - 蒙特卡洛方法(Monte Carlo)

文章目录 概览&#xff1a;RL方法分类蒙特卡洛方法&#xff08;Monte Carlo&#xff0c;MC&#xff09;MC BasicMC Exploring Starts&#x1f7e6;MC ε-Greedy 本系列文章介绍强化学习基础知识与经典算法原理&#xff0c;大部分内容来自西湖大学赵世钰老师的强化学习的数学原理…

欧拉函数算法总结

知识概览 欧拉函数为1~n中与n互质的数的个数。假设一个数N分解质因数后的结果为 则欧拉函数 这可以用容斥原理来证明。 欧拉函数的应用 欧拉定理&#xff1a;若a与n互质&#xff0c;则。 费马小定理&#xff1a;欧拉定理中的n为质数p时&#xff0c;可以得到若a与p互质&#xff…

Java:结束本机端口被占用进程

前言 在实际开发当中我们&#xff0c;往往在idea中将某个服务的启动给关闭了&#xff0c;但是在nacos的某个服务上&#xff0c;我们却可以看到本地别名服务还是在上面挂载着本地再次启动的时候就提示【端口被占用】&#xff0c;今天就说一下如何解决这个问题 操作 点击即可预…

我的创作纪念日——redis的历史纪录

机缘 最开始只想存留点Redis的操作信息&#xff0c;后来写着写着也就写多了&#xff0c;虽然后面很长时间由于忙就没继续写&#xff0c;但是还是偶尔登录看一下&#xff0c;有好几篇文章的浏览量还是很多的呢。 收获 收获不多&#xff0c;粉丝也才三十多个&#xff0c;浏览量感…

mac版viso软件 流程图软件omnigraffile

OmniGraffle 是一款由 The Omni Group 开发的绘图工具&#xff0c;主要用于创建各种类型的图表、流程图、组织结构图、网站地图等。它提供了丰富的绘图工具和功能&#xff0c;包括形状、线条、文本、颜色、样式等&#xff0c;可以帮助用户轻松地创建出精美的图表和图形。 OmniG…

优化器(一)torch.optim.SGD-随机梯度下降法

torch.optim.SGD-随机梯度下降法 import torch import torchvision.datasets from torch import nn from torch.utils.data import DataLoaderdataset torchvision.datasets.CIFAR10(root./data, trainFalse, downloadTrue,transformtorchvision.transforms.ToTensor()) data…

【51单片机】独立按键控制LED灯

不同于上篇文章只用代码控制&#xff0c;这次我们要再加上独立按键一同控制LED灯 目录 独立按键控制LED亮灭&#xff1a;代码实现&#xff1a; 独立按键控制LED状态&#xff1a;代码实现&#xff1a; 独立按键实现二进制LED显示&#xff1a;代码实现&#xff1a; 独立按键控制…

【C++】几种常用的类型转换

类型转换 c语言中的类型转换C的类型转换static_castreinterpret_castconst_castdynamic_cast c语言中的类型转换 在C语言中我们经常会遇到类型转化的问题&#xff0c;主要分为两种&#xff1a;显式类型转换和隐式类型转换。 显式类型转换&#xff1a;就是程序员使用强制类型转…