Spring Security 的TokenStore三种实现方式
博主介绍:✌专注于前后端领域开发的优质创作者、秉着互联网精神开源贡献精神,答疑解惑、坚持优质作品共享。本人是掘金/腾讯云/阿里云等平台优质作者、擅长前后端项目开发和毕业项目实战,深受全网粉丝喜爱与支持✌有需要可以联系作者我哦!
🍅文末三连哦🍅
什么是Token Store
在Web开发中,Token Store 通常用于存储用户身份验证令牌(Tokens),例如 JSON Web Tokens (JWT) 或其他形式的令牌。这些令牌可以用于验证用户身份,实现用户会话管理以及访问控制。
一种简单的Token Store示例,使用Node.js和Express框架以及一个基于内存的Token存储方式:
const express = require('express');
const jwt = require('jsonwebtoken');const app = express();
app.use(express.json());// In-memory Token Store
const tokenStore = {};// Secret key for JWT (replace with a strong, secret key in production)
const secretKey = 'your_secret_key';// Middleware to verify JWT
function verifyToken(req, res, next) {const token = req.headers.authorization;if (!token) {return res.status(403).json({ message: 'No token provided' });}jwt.verify(token, secretKey, (err, decoded) => {if (err) {return res.status(401).json({ message: 'Failed to authenticate token' });}req.user = decoded;next();});
}// Endpoint to generate and return a JWT
app.post('/login', (req, res) => {const { username, password } = req.body;// Authenticate user (replace with your actual authentication logic)// For simplicity, assume any username and password combination is validconst user = { username, role: 'user' };// Generate a JWTconst token = jwt.sign(user, secretKey, { expiresIn: '1h' });// Store the token in memorytokenStore[token] = user;res.json({ token });
});// Protected endpoint that requires a valid JWT for access
app.get('/protected', verifyToken, (req, res) => {res.json({ message: 'This is a protected endpoint', user: req.user });
});// Start the server
const port = 3000;
app.listen(port, () => {console.log(`Server is running on http://localhost:${port}`);
});
Spring Security 提供了几个常见的
TokenStore实现,包括内存中存储、JDBC 数据库存储和基于 JWT(JSON Web Token)的存储。下面将分别介绍这三种实现方式,并提供基本的代码示例。
1. 内存中存储(In-Memory)
@Configuration
@EnableAuthorizationServer
public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {@Autowiredprivate AuthenticationManager authenticationManager;@Beanpublic TokenStore inMemoryTokenStore() {return new InMemoryTokenStore();}@Overridepublic void configure(ClientDetailsServiceConfigurer clients) throws Exception {clients.inMemory().withClient("client").secret("{noop}secret") // 使用 "{noop}" 表示不加密.authorizedGrantTypes("password", "authorization_code", "refresh_token").scopes("read", "write").accessTokenValiditySeconds(3600).refreshTokenValiditySeconds(86400);}@Overridepublic void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {endpoints.tokenStore(inMemoryTokenStore()).authenticationManager(authenticationManager);}
}
2. JDBC 数据库存储
@Configuration
@EnableAuthorizationServer
public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {@Autowiredprivate AuthenticationManager authenticationManager;@Autowiredprivate DataSource dataSource;@Beanpublic TokenStore jdbcTokenStore() {return new JdbcTokenStore(dataSource);}@Overridepublic void configure(ClientDetailsServiceConfigurer clients) throws Exception {clients.jdbc(dataSource);}@Overridepublic void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {endpoints.tokenStore(jdbcTokenStore()).authenticationManager(authenticationManager);}
}
3. 基于 JWT 的存储
@Configuration
@EnableAuthorizationServer
public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {@Autowiredprivate AuthenticationManager authenticationManager;@Value("${security.jwt.client-id}")private String clientId;@Value("${security.jwt.client-secret}")private String clientSecret;@Value("${security.jwt.grant-type}")private String grantType;@Value("${security.jwt.scope-read}")private String scopeRead;@Value("${security.jwt.scope-write}")private String scopeWrite;@Value("${security.jwt.resource-ids}")private String resourceIds;@Beanpublic TokenStore jwtTokenStore() {return new JwtTokenStore(jwtAccessTokenConverter());}@Beanpublic JwtAccessTokenConverter jwtAccessTokenConverter() {JwtAccessTokenConverter converter = new JwtAccessTokenConverter();converter.setSigningKey("secret");return converter;}@Overridepublic void configure(ClientDetailsServiceConfigurer clients) throws Exception {clients.inMemory().withClient(clientId).secret("{noop}" + clientSecret).authorizedGrantTypes(grantType).scopes(scopeRead, scopeWrite).resourceIds(resourceIds);}@Overridepublic void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {endpoints.tokenStore(jwtTokenStore()).accessTokenConverter(jwtAccessTokenConverter()).authenticationManager(authenticationManager);}
}
小结
我们介绍了Spring Security中三种不同的Token Store实现方式。具体包括内存中存储、JDBC数据库存储和基于JWT的存储。每个实现方式都涉及到授权服务器的配置,用于管理和验证令牌,以及客户端详情的配置。
大家点赞、收藏、关注、评论啦!谢谢三连哦!
相关文章:
Spring Security 的TokenStore三种实现方式
博主介绍:✌专注于前后端领域开发的优质创作者、秉着互联网精神开源贡献精神,答疑解惑、坚持优质作品共享。本人是掘金/腾讯云/阿里云等平台优质作者、擅长前后端项目开发和毕业项目实战,深受全网粉丝喜爱与支持✌有需要可以联系作者我哦&…...
微信小程序 图片自适应高度 宽度 完美适配原生或者uniapp
-- - - - 查了一下百度看到网上图片高度自适应的解决方案 基本是靠JS获取图片的宽度进行按比例计算得出图片高度。 不是很符合我的需求/ 于是我脑瓜子一转 想到一种新的解决方案 不用JS计算也能完美解决。 我写了一个组件,直接导入可以使用。 - - - 1.新…...
Go语言基础之反射
1.变量的内在机制 Go语言中的变量是分为两部分的: 类型信息:预先定义好的元信息。值信息:程序运行过程中可动态变化的。 2.反射介绍 反射是指在程序运行期间对程序本身进行访问和修改的能力。程序在编译时,变量被转换为内存地址ÿ…...
MySQL十部曲之六:数据操作语句(DML)
文章目录 前言语法约定DELETEINSERTSELECT查询列表SELECT 选项子句FROMWHEREORDER BYGROUP BYHAVINGWINDOWLIMITFOR SELECT ... INTO连接查询CROSS JOIN和INNER JOINON和USINGOUTER JOINNATURE JOIN 子查询标量子查询使用子查询进行比较带有ANY、IN或SOME的子查询带有ALL的子查…...
Quartus生成烧录到FPGA板载Flash的jic文件
简要说明: Altera的FPGA芯片有两种基本分类,一类是纯FPGA,另一类是FPGASoc(System on chip),也就是FPGAHPS(Hard Processor System,硬核处理器),对应两种Flash烧录方式&a…...
CSS 多色正方形上升
<template><view class="loop cubes"><view class="item cubes"></view> <!-- 方块1 --><view class="item cubes"></view> <!-- 方块2 --><view class="item cubes"></vie…...
《HelloGitHub》第 94 期
兴趣是最好的老师,HelloGitHub 让你对编程感兴趣! 简介 HelloGitHub 分享 GitHub 上有趣、入门级的开源项目。 https://github.com/521xueweihan/HelloGitHub 这里有实战项目、入门教程、黑科技、开源书籍、大厂开源项目等,涵盖多种编程语言 …...
uniapp 实现路由拦截,权限或者登录控制
背景: 项目需要判断token,即是否登录,登录之后权限 参考uni-app官方: 为了兼容其他端的跳转权限控制,uni-app并没有用vue router路由,而是内部实现一个类似此功能的钩子:拦截器,由…...
[GXYCTF2019]BabySQli1
单引号闭合,列数为三列,但是没有期待的1 2 3回显,而是显示wrong pass。 尝试报错注入时发现过滤了圆括号,网上搜索似乎也没找到能绕过使用圆括号的方法,那么按以往爆库爆表爆字段的方法似乎无法使用了 在响应报文找到一…...
【架构】Docker实现集群主从缩容【案例4/4】
实现集群主从缩容【4/4】 接上一节,在当前机器为4主4从的架构上,减缩容量为3主3从架构。即实现删除6387和6388. 示意图如下: 第一步:查看集群情况(第一次) redis-cli --cluster check 127.0.0.1:6387roo…...
【ArcGIS微课1000例】0097:栅格重采样(以数字高程模型dem为例)
Contents 1. 最邻近法(Nearest Neighbor)2. 双线性内插法(Bilinear Interpolation)3. 三次卷积法(Cubic Convolution)4. ArcGIS重采样工具(Resample)5. 注意事项栅格/影像数据进行配准或纠正、投影等几何变换后,像元中心位置通常会发生变化,其在输入栅格中的位置不一…...
【技术分享】Ubuntu 20.04如何更改用户名
产品简介 本文适用于所有RK3568/RK3588平台产品在Ubuntu 20.04系统上如何更改用户名,本文以IDO-EVB3588开发板为例,在ubuntu20.04系统上修改用户名industio为usernew。 IDO-EVB3588开发板是一款基于RK3588平台的产品。该开发板集成了四核Cortex-A76和四…...
LabVIEW振动信号分析
LabVIEW振动信号分析 介绍如何使用LabVIEW软件实现希尔伯特-黄变换(Hilbert-Huang Transform, HHT),并将其应用于振动信号分析。HHT是一种用于分析非线性、非平稳信号的强大工具,特别适用于旋转机械等复杂系统的振动分析。开发了…...
清理Docker环境
清理Docker环境:有时,Docker环境可能会出现一些问题,导致网络连接故障。您可以尝试清理Docker环境并重新启动。可以尝试运行以下命令: 复制 docker-compose down docker system prune -a docker-compose up docker-compose up 和…...
oracle等保测评
实战|等保2.0 Oracle数据库测评过程 一、身份鉴别 a) 应对登录的用户进行身份标识和鉴别,身份标识具有唯一性,身份鉴别信息具有复杂度要求并定期更换; sysdba是Oracle数据库的最高权限管理员。通常使用sqlplus或PL/SQL 管理软件进行管理,PL/SQL 为第三方管理软件,但S…...
x-cmd pkg | go - Google 开发的开源编程语言
目录 简介首次用户技术特点竞品分析编译型语言解释型语言JavaWebAssebmly 进一步阅读 简介 Go 语言(或 Golang)是 Google 开发的开源编程语言,诞生于 2006 年。其设计目标是“兼具 Python 等动态语言的开发速度和 C/C 等编译型语言的性能与安…...
32个Java面试必考点-09(下)MySQL调优与最佳实践
详解 MySQL 下面来学习互联网行业使用最为广泛的关系型数据库 MySQL,它的知识点结构图如下所示。 常用 SQL 语句 对于手写常用 SQL 语句,没有什么特殊的技巧,根据所列的语句类型多做一些练习就好。 数据类型 要知道 MySQL 都提供哪些基本的…...
优思学院|精益管理如何判定哪些活动是增值或非增值?
“时间就是金钱”——这句老话我们都耳熟能详。但在工作中,我们真正从事的、对组织增加价值的活动有多少呢?我们常常认为自己的每一项任务都是维持运营的关键。然而,当我们从精益管理的视角进行分析,可能会惊讶地发现,…...
详解操作系统各章大题汇总(死锁资源分配+银行家+进程的PV操作+实时调度+逻辑地址->物理地址+页面置换算法+磁盘调度算法)
文章目录 第三章:死锁资源分配图例一例二 第三章:银行家算法第四章:进程的同步与互斥做题步骤PV操作的代码小心容易和读者写者混 1.交通问题(类似读者写者)分析代码 2.缓冲区问题(第二个缓冲区是复制缓冲区…...
用ASM HEMT模型提取GaN器件的参数
标题:Physics-Based Multi-Bias RF Large-Signal GaNHEMT Modeling and Parameter Extraction Flow (JEDS 17年) 模型描述 该模型的核心是对表面势(ψ)及其随施加的栅极电压(Vg)和漏极电压(Vd)…...
接口测试中缓存处理策略
在接口测试中,缓存处理策略是一个关键环节,直接影响测试结果的准确性和可靠性。合理的缓存处理策略能够确保测试环境的一致性,避免因缓存数据导致的测试偏差。以下是接口测试中常见的缓存处理策略及其详细说明: 一、缓存处理的核…...
CTF show Web 红包题第六弹
提示 1.不是SQL注入 2.需要找关键源码 思路 进入页面发现是一个登录框,很难让人不联想到SQL注入,但提示都说了不是SQL注入,所以就不往这方面想了 先查看一下网页源码,发现一段JavaScript代码,有一个关键类ctfs…...
【WiFi帧结构】
文章目录 帧结构MAC头部管理帧 帧结构 Wi-Fi的帧分为三部分组成:MAC头部frame bodyFCS,其中MAC是固定格式的,frame body是可变长度。 MAC头部有frame control,duration,address1,address2,addre…...
以下是对华为 HarmonyOS NETX 5属性动画(ArkTS)文档的结构化整理,通过层级标题、表格和代码块提升可读性:
一、属性动画概述NETX 作用:实现组件通用属性的渐变过渡效果,提升用户体验。支持属性:width、height、backgroundColor、opacity、scale、rotate、translate等。注意事项: 布局类属性(如宽高)变化时&#…...
YSYX学习记录(八)
C语言,练习0: 先创建一个文件夹,我用的是物理机: 安装build-essential 练习1: 我注释掉了 #include <stdio.h> 出现下面错误 在你的文本编辑器中打开ex1文件,随机修改或删除一部分,之后…...
JVM垃圾回收机制全解析
Java虚拟机(JVM)中的垃圾收集器(Garbage Collector,简称GC)是用于自动管理内存的机制。它负责识别和清除不再被程序使用的对象,从而释放内存空间,避免内存泄漏和内存溢出等问题。垃圾收集器在Ja…...
华为OD机试-食堂供餐-二分法
import java.util.Arrays; import java.util.Scanner;public class DemoTest3 {public static void main(String[] args) {Scanner in new Scanner(System.in);// 注意 hasNext 和 hasNextLine 的区别while (in.hasNextLine()) { // 注意 while 处理多个 caseint a in.nextIn…...
数据链路层的主要功能是什么
数据链路层(OSI模型第2层)的核心功能是在相邻网络节点(如交换机、主机)间提供可靠的数据帧传输服务,主要职责包括: 🔑 核心功能详解: 帧封装与解封装 封装: 将网络层下发…...
Python爬虫(一):爬虫伪装
一、网站防爬机制概述 在当今互联网环境中,具有一定规模或盈利性质的网站几乎都实施了各种防爬措施。这些措施主要分为两大类: 身份验证机制:直接将未经授权的爬虫阻挡在外反爬技术体系:通过各种技术手段增加爬虫获取数据的难度…...
【数据分析】R版IntelliGenes用于生物标志物发现的可解释机器学习
禁止商业或二改转载,仅供自学使用,侵权必究,如需截取部分内容请后台联系作者! 文章目录 介绍流程步骤1. 输入数据2. 特征选择3. 模型训练4. I-Genes 评分计算5. 输出结果 IntelliGenesR 安装包1. 特征选择2. 模型训练和评估3. I-Genes 评分计…...
