当前位置: 首页 > news >正文

根据用户名称实现单点登录

一、参数格式

二、后端实现

Controller层
public class IAccessTokenLoginController extends BaseController {@Autowiredprivate ISysUserService sysUserService;@Autowiredprivate ISingleTokenServiceImpl tokenService;/*** 登录方法** @return 结果*/@PostMapping("/login")public AjaxResult singleLogin(@RequestBody LoginBody loginBody) {String accessToken = loginBody.getAccessToken();if (StringUtils.isNotEmpty(accessToken)) {String tokenNew = tokenService.singleLogin(accessToken);AjaxResult ajax = AjaxResult.success();ajax.put(Constants.TOKEN, tokenNew);return ajax;} else {return AjaxResult.error();}}
}
注意:LoginBody新增变量accessToken
@Service
public class ISingleTokenServiceImpl implements ISingleTokenService {@Autowiredprivate TokenService tokenService;@Autowiredprivate AuthenticationManager authenticationManager;public String singleLogin(String accessToken) {// 用户验证Authentication authentication = null;String username =accessToken;try{
//            username=parseAccessToken(accessToken);
//不用进行处置 直接传参authentication = authenticationManager.authenticate(new IAuthenticationToken(username));}catch (Exception e){if (e instanceof BadCredentialsException){AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.password.not.match")));throw new UserPasswordNotMatchException();}else{AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, e.getMessage()));throw new ServiceException(e.getMessage());}}AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success")));LoginUser loginUser = (LoginUser) authentication.getPrincipal();// 生成tokenreturn tokenService.createToken(loginUser);}public String parseAccessToken(String accessToken) {try {// 从 access token 中提取 payloadClaims claims = Jwts.parser().parseClaimsJws(accessToken).getBody();// 获取 usernameString username = (String) claims.get("username");return username;} catch (Exception e) {System.out.println("无法解析 access token!" + e);return null;}}
  • 添加自定义IAuthenticationToken 
  • public class IAuthenticationToken extends AbstractAuthenticationToken {private final Object principal;public IAuthenticationToken(Object principal) {super(null);this.principal = principal;this.setAuthenticated(false);}public IAuthenticationToken(Object principal, Collection<? extends GrantedAuthority> authorities) {super(authorities);this.principal = principal;super.setAuthenticated(true);}@Overridepublic Object getCredentials() {return null;}@Overridepublic Object getPrincipal() {return this.principal;}@Overridepublic void setAuthenticated(boolean isAuthenticated) throws IllegalArgumentException {if (isAuthenticated) {throw new IllegalArgumentException("Cannot set this token to trusted - use constructor which takes a GrantedAuthority list instead");}super.setAuthenticated(false);}@Overridepublic void eraseCredentials() {super.eraseCredentials();}}
    

    添加IAuthenticationProvider

  • @Component
    public class IAuthenticationProvider implements AuthenticationProvider {@Autowiredprivate UserDetailsServiceImpl userDetailsService;@Overridepublic Authentication authenticate(Authentication authentication) throws AuthenticationException {IAuthenticationToken authenticationToken = (IAuthenticationToken) authentication;String username = (String) authenticationToken.getPrincipal();UserDetails user = userDetailsService.loadUserByUsername(username);IAuthenticationToken result = new IAuthenticationToken(user, Collections.emptyList());/*Details 中包含了 ip地址、 sessionId 等等属性 也可以存储一些自己想要放进去的内容*/result.setDetails(authenticationToken.getDetails());return result;}@Overridepublic boolean supports(Class<?> aClass) {return IAuthenticationToken.class.isAssignableFrom(aClass);}
    }
    

    修改SecurityConfig 放行我们的请求登录路径 并把自定义认证加进来
    .antMatchers("/hello","/single/login","/login", "/register", "/captchaImage").anonymous()
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception
    {
        

    auth.authenticationProvider(new CustomLoginAuthenticationProvider(userDetailsService));
    auth.userDetailsService(userDetailsService).passwordEncoder(bCryptPasswordEncoder());
    auth.authenticationProvider(iAuthenticationProvider);

    }

  • 前端根据后台返回的token进行访问

相关文章:

根据用户名称实现单点登录

一、参数格式 二、后端实现 Controller层 public class IAccessTokenLoginController extends BaseController {Autowiredprivate ISysUserService sysUserService;Autowiredprivate ISingleTokenServiceImpl tokenService;/*** 登录方法** return 结果*/PostMapping("/l…...

【设计】855. 考场就座

855. 考场就座 这段代码实现了一个考场安排座位的算法。在这个算法中&#xff0c;考场被模拟成一个从0到n-1的数轴&#xff0c;其中每个位置代表一个座位。目的是在每次学生入座时&#xff0c;找到一个使得所有学生之间距离最大化的座位&#xff0c;并在学生离开时更新座位信息…...

Android中的传感器类型和接口名称

本文将介绍传感器坐标轴、基础传感器和复合传感器&#xff08;动作传感器、姿势传感器、未校准传感器和互动传感器&#xff09;。 1. 传感器坐标轴 许多传感器的传感器事件值在相对于设备静止的特定坐标系中表示。 1.1 移动设备坐标轴 Sensor API 仅与屏幕的自然方向相关&a…...

解析进程 /proc/pid/maps 和 /proc/pid/smaps

目录 /proc//maps 背景 具体描述 代码实现 实践 /proc/pid/smaps smaps各子项详解 代码实现 代码调用的路径如下&#xff1a; 小结 /proc/<pid>/maps 背景 相对于/proc/meminfo和dumpsys meminfo可以看到系统整体的内存信息&#xff0c;我们还需要能够具体到…...

【MQ】消息队列概述

&#x1f4dd;个人主页&#xff1a;五敷有你 &#x1f525;系列专栏&#xff1a;MQ ⛺️稳中求进&#xff0c;晒太阳 定义 消息队列&#xff1a;一般我们简称为MQ(Message Queue) Message Queue :消息队列中间件&#xff0c;很多初学者认为&#xff0c;MQ通过消息的发送…...

交友盲盒系统PHP开源的盲盒源码

源码介绍&#xff1a; 交友盲盒系统是一款基于PHP开发的开源免费盲盒系统&#xff0c;旨在为用户提供一个充满乐趣和惊喜的社交体验。该系统具有丰富的功能和灵活的扩展性&#xff0c;可以轻松地满足各种线上交友、抽奖活动等场景的需求。 安装说明&#xff1a; PHP版本&…...

【Flutter 面试题】什么是异步编程 Flutter中如何处理异步操作?

【Flutter 面试题】什么是异步编程 Flutter中如何处理异步操作&#xff1f; 文章目录 写在前面解答补充说明从网络API异步获取数据并解析 写在前面 关于我 &#xff0c;小雨青年 &#x1f449; CSDN博客专家&#xff0c;GitChat专栏作者&#xff0c;阿里云社区专家博主&#x…...

处理error: remote origin already exists.及其Gitee文件上传保姆级教程

解决error: remote origin already exists.&#xff1a; 删除远程 Git 仓库 git remote rm origin 再添加远程 Git 仓库 git remote add origin &#xff08;HTTPS&#xff09; 比如这样&#xff1a; 然后再push过去就ok了 好多人可能还是不熟悉怎么将文件上传 Gitee:我…...

网络编程套接字(2)——Socket套接字

目录 一、概念 二、分类 1、流套接字&#xff08;使用传输层TCP协议&#xff09; TCP的特点 2、数据报套接字&#xff08;使用传输层UDP协议&#xff09; UDP的特点 3、原始套接字 一、概念 Socket套接字&#xff0c;是由系统提供用于网络通信的技术&#xff0c;是基于T…...

向量错题本

《1800》 1 看变换求和能不能成为0,为0,就是线性相关 2 矩阵等价 3 4<...

FPGA-VGA成像原理与时序

什么是VGA: VGA, Video Graphics Array。即视频图形阵列,具有分辨率高、显示速率快、颜色丰富等优点。VGA接口不但是CRT显示设备的标准接口,同样也是LCD液晶显示设备的标准接口,具有广泛的应用范围。在FGPA中,常广泛用于图像处理等领域。 VGA 显示器成像原理 在 VGA 标准刚兴…...

【VTKExamples::Points】第三期 ExtractClusters

很高兴在雪易的CSDN遇见你 VTK技术爱好者 QQ:870202403 公众号:VTK忠粉 前言 本文分享VTK样例ExtractClusters,并解析接口vtkEuclideanClusterExtraction,希望对各位小伙伴有所帮助! 感谢各位小伙伴的点赞+关注,小易会继续努力分享,一起进步! 你的点赞就是我…...

迅速上手:CentOS 系统下 SSH 服务配置指南

前言 掌握 SSH 服务&#xff0c;就像拥有了一把解锁网络世界的钥匙。本文深入浅出地介绍了如何使用 SSH&#xff08;Secure Shell&#xff09;服务&#xff0c;从连接远程服务器到安全文件传输&#xff0c;让你轻松驾驭远程管理与数据传输&#xff0c;提高工作效率&#xff0c…...

day38 动态规划part1

509. 斐波那契数 简单 斐波那契数 &#xff08;通常用 F(n) 表示&#xff09;形成的序列称为 斐波那契数列 。该数列由 0 和 1 开始&#xff0c;后面的每一项数字都是前面两项数字的和。也就是&#xff1a; F(0) 0&#xff0c;F(1) 1 F(n) F(n - 1) F(n - 2)&#xff0c;…...

01背包问题 刷题笔记

思路 dp 用f[i][j]来表示当体积为j时 考虑前i件物品可以获得的 最大值 记住f[i][j]本身是个价“价值” 考虑两种状态 是否将第i件物品放入背包里面 将背包的体积从小到大递增来进行考虑 首先 考虑条件 如果当前增加的体积放不下下一件物品 则该体积 可以获得的最大值可以直接…...

docker安装包(Linux和windows)

Linux——docker-20.10.9.tgz 网盘地址&#xff1a;链接&#xff1a;https://pan.baidu.com/s/1T3qfVZ-uT-vMAo8w6heTMw 提取码&#xff1a;qu85 windows——docker19.03.1 链接&#xff1a;https://pan.baidu.com/s/1mK6hqhkGCBs6tdBHJxrdPw 提取码&#xff1a;4dkj...

RabbitMQ 安装使用

文章目录 RabbitMQ 安装使用安装下载 Erlang下载 RabbitMQ 的服务安装好后看是否有 RabbitMQ 的服务开启管理 UIRabbitMQ 端口使用一览图 使用输出最简单的 Hello World&#xff01;生产者定义消费者消费消息小拓展 RabbitMQ 安装使用 安装 下载 Erlang RabbitMQ 是用这个语…...

echarts x轴名称过长tip显示全称

xAxis的axisLabel的内容如下&#xff1a; axisLabel: { rotate: -45, color: document.body.className.indexOf(custom-f4c46d) > -1 ? #fff : #343434, // 显示省略号操作&#xff08;第一步&#xff09; formatter: function (value) { var val if (value.length >…...

js和css阻塞问题

面试常见问题 css 加载会不会阻塞 js 的加载&#xff1f;&#xff08;不会&#xff09;css 加载会不会阻塞 js 的执行&#xff1f;&#xff08;会&#xff09;css 加载会不会阻塞 DOM 的解析&#xff1f;&#xff08;不会&#xff09;css 加载会不会阻塞 DOM 的渲染&#xff1…...

MySQL 的基础操作

数据库的基础操作 1. 库操作2. 表的操作3. 数据类型 数据库是现代应用程序中至关重要的组成部分&#xff0c;通过数据库管理系统&#xff08;DBMS&#xff09;存储和管理数据。 1. 库操作 创建数据库 创建数据库是开始使用数据库的第一步。下面是一些常见的创建数据库的示例&a…...

【大模型RAG】拍照搜题技术架构速览:三层管道、两级检索、兜底大模型

摘要 拍照搜题系统采用“三层管道&#xff08;多模态 OCR → 语义检索 → 答案渲染&#xff09;、两级检索&#xff08;倒排 BM25 向量 HNSW&#xff09;并以大语言模型兜底”的整体框架&#xff1a; 多模态 OCR 层 将题目图片经过超分、去噪、倾斜校正后&#xff0c;分别用…...

[2025CVPR]DeepVideo-R1:基于难度感知回归GRPO的视频强化微调框架详解

突破视频大语言模型推理瓶颈,在多个视频基准上实现SOTA性能 一、核心问题与创新亮点 1.1 GRPO在视频任务中的两大挑战 ​安全措施依赖问题​ GRPO使用min和clip函数限制策略更新幅度,导致: 梯度抑制:当新旧策略差异过大时梯度消失收敛困难:策略无法充分优化# 传统GRPO的梯…...

从WWDC看苹果产品发展的规律

WWDC 是苹果公司一年一度面向全球开发者的盛会&#xff0c;其主题演讲展现了苹果在产品设计、技术路线、用户体验和生态系统构建上的核心理念与演进脉络。我们借助 ChatGPT Deep Research 工具&#xff0c;对过去十年 WWDC 主题演讲内容进行了系统化分析&#xff0c;形成了这份…...

模型参数、模型存储精度、参数与显存

模型参数量衡量单位 M&#xff1a;百万&#xff08;Million&#xff09; B&#xff1a;十亿&#xff08;Billion&#xff09; 1 B 1000 M 1B 1000M 1B1000M 参数存储精度 模型参数是固定的&#xff0c;但是一个参数所表示多少字节不一定&#xff0c;需要看这个参数以什么…...

前端导出带有合并单元格的列表

// 导出async function exportExcel(fileName "共识调整.xlsx") {// 所有数据const exportData await getAllMainData();// 表头内容let fitstTitleList [];const secondTitleList [];allColumns.value.forEach(column > {if (!column.children) {fitstTitleL…...

GitHub 趋势日报 (2025年06月08日)

&#x1f4ca; 由 TrendForge 系统生成 | &#x1f310; https://trendforge.devlive.org/ &#x1f310; 本日报中的项目描述已自动翻译为中文 &#x1f4c8; 今日获星趋势图 今日获星趋势图 884 cognee 566 dify 414 HumanSystemOptimization 414 omni-tools 321 note-gen …...

爬虫基础学习day2

# 爬虫设计领域 工商&#xff1a;企查查、天眼查短视频&#xff1a;抖音、快手、西瓜 ---> 飞瓜电商&#xff1a;京东、淘宝、聚美优品、亚马逊 ---> 分析店铺经营决策标题、排名航空&#xff1a;抓取所有航空公司价格 ---> 去哪儿自媒体&#xff1a;采集自媒体数据进…...

力扣-35.搜索插入位置

题目描述 给定一个排序数组和一个目标值&#xff0c;在数组中找到目标值&#xff0c;并返回其索引。如果目标值不存在于数组中&#xff0c;返回它将会被按顺序插入的位置。 请必须使用时间复杂度为 O(log n) 的算法。 class Solution {public int searchInsert(int[] nums, …...

如何在网页里填写 PDF 表格?

有时候&#xff0c;你可能希望用户能在你的网站上填写 PDF 表单。然而&#xff0c;这件事并不简单&#xff0c;因为 PDF 并不是一种原生的网页格式。虽然浏览器可以显示 PDF 文件&#xff0c;但原生并不支持编辑或填写它们。更糟的是&#xff0c;如果你想收集表单数据&#xff…...

使用Spring AI和MCP协议构建图片搜索服务

目录 使用Spring AI和MCP协议构建图片搜索服务 引言 技术栈概览 项目架构设计 架构图 服务端开发 1. 创建Spring Boot项目 2. 实现图片搜索工具 3. 配置传输模式 Stdio模式&#xff08;本地调用&#xff09; SSE模式&#xff08;远程调用&#xff09; 4. 注册工具提…...