BladeX单点登录与若依框架集成实现

在这里插入图片描述

1. 概述

本文档详细介绍了将BladeX认证系统与若依(RuoYi)框架集成的完整实现过程。集成采用OAuth2.0授权码流程,使用户能够通过BladeX账号直接登录若依系统,实现无缝单点登录体验。

2. 系统架构

2.1 总体架构

1. 点击BladeX登录
2. 重定向到BladeX授权页
3. 用户授权
4. 返回授权码
5. 发送授权码
6. 请求令牌
7. 返回用户信息和令牌
8. 查找用户并生成令牌
9. 返回若依JWT令牌
10. 保存令牌并跳转
用户
若依前端
BladeX认证服务
若依回调页面
若依后端
若依Redis缓存
若依系统首页

2.2 关键组件

  • BladeAuthUtil: 工具类,处理与BladeX认证服务的通信
  • BladeAuthController: 后端控制器,处理授权码并生成若依JWT令牌
  • BladeCallback.vue: 前端页面,接收授权回调并处理认证结果

3. 后端实现

3.1 BladeAuthUtil工具类

public class BladeAuthUtil {public static Map<String, Object> getTokenByCode(String authUrl, String clientId, String clientSecret, String code, String redirectUri, String tenantId) {// 构建请求参数MultiValueMap<String, String> params = new LinkedMultiValueMap<>();params.add("grant_type", "authorization_code");params.add("code", code);params.add("client_id", clientId);params.add("client_secret", clientSecret);params.add("redirect_uri", redirectUri);if (tenantId != null && !tenantId.isEmpty()) {params.add("tenant_id", tenantId);}// 发送请求获取令牌try {RestTemplate restTemplate = new RestTemplate();HttpHeaders headers = new HttpHeaders();headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);HttpEntity<MultiValueMap<String, String>> requestEntity = new HttpEntity<>(params, headers);ResponseEntity<Map> response = restTemplate.exchange(authUrl, HttpMethod.POST, requestEntity, Map.class);return response.getBody();} catch (Exception e) {// 处理异常return null;}}
}

3.2 BladeAuthController控制器

@RestController
@RequestMapping("/blade/auth")
public class BladeAuthController {@Value("${blade.auth.url:}")private String authUrl;@Value("${blade.auth.client-id:}")private String clientId;@Value("${blade.auth.client-secret:}")private String clientSecret;@Value("${blade.auth.redirect-uri:}")private String redirectUri;@Autowiredprivate ISysUserService userService;@Autowiredprivate TokenService tokenService;@Autowiredprivate UserDetailsServiceImpl userDetailsService;@GetMapping("/getTokenInfo")public AjaxResult getTokenInfo(@RequestParam("code") String code, @RequestParam(value = "tenant_id", required = false) String tenantId) {// 获取BladeX令牌Map<String, Object> tokenInfo = BladeAuthUtil.getTokenByCode(authUrl, clientId, clientSecret, code, redirectUri, tenantId);// 提取用户名并查找若依系统用户if (tokenInfo != null && tokenInfo.containsKey("account")) {String userName = (String) tokenInfo.get("account");SysUser user = userService.selectUserByUserName(userName);if (user != null) {// 使用UserDetailsServiceImpl创建LoginUser对象LoginUser loginUser = (LoginUser) userDetailsService.createLoginUser(user);// 记录登录信息recordLoginInfo(user.getUserId());// 使用TokenService生成JWT令牌String token = tokenService.createToken(loginUser);// 返回令牌AjaxResult ajax = AjaxResult.success();ajax.put(Constants.TOKEN, token);return ajax;}}return AjaxResult.error("认证失败");}
}

4. 前端实现

4.1 登录页面增加BladeX登录按钮

<template><div class="login"><!-- 现有登录表单 --><!-- 添加BladeX登录按钮 --><el-button type="primary" class="blade-login-btn" @click="handleBladeLogin">使用BladeX登录</el-button></div>
</template><script>
export default {methods: {handleBladeLogin() {// BladeX授权页面URLconst bladeAuthUrl = process.env.VUE_APP_BLADE_AUTH_URL;const clientId = process.env.VUE_APP_BLADE_CLIENT_ID;const redirectUri = encodeURIComponent(process.env.VUE_APP_BLADE_REDIRECT_URI);// 跳转到BladeX授权页面window.location.href = `${bladeAuthUrl}?client_id=${clientId}&response_type=code&redirect_uri=${redirectUri}`;}}
}
</script>

4.2 BladeCallback.vue回调处理页面

<template><div class="blade-callback-container"><div class="callback-card"><div v-if="loading"><h2>正在处理BladeX授权...</h2><el-progress :percentage="progress"></el-progress></div><div v-else-if="error"><h2>授权处理失败</h2><p>{{ errorMessage }}</p><el-button type="primary" @click="returnToLogin">返回登录页</el-button></div></div></div>
</template><script>
import { Message } from 'element-ui';
import { setToken } from '@/utils/auth';export default {data() {return {loading: true,error: false,errorMessage: '',code: '',tenantId: ''};},created() {// 获取URL参数中的授权码this.code = this.$route.query.code;this.tenantId = this.$route.query.state || '';// 处理授权码this.handleAuthorizationCode();},methods: {// 处理授权码handleAuthorizationCode() {request({url: '/blade/auth/getTokenInfo',method: 'get',params: {code: this.code,tenant_id: this.tenantId}}).then(response => {if (response.code === 200 && response.data && response.data.token) {// 使用若依token登录this.handleLoginSuccess(response.data.token);} else {// 显示错误信息this.handleError(response.msg || '获取令牌失败');}}).catch(error => {this.handleError('获取令牌失败: ' + error.message);});},// 处理登录成功handleLoginSuccess(token) {// 保存tokensetToken(token);// 获取用户信息并生成路由this.$store.dispatch('GetInfo').then(() => {this.$store.dispatch('GenerateRoutes').then(accessRoutes => {// 动态添加可访问路由表this.$router.addRoutes(accessRoutes);// 跳转到首页this.$router.push({ path: '/' });});});}}
};
</script>

5. 配置说明

5.1 后端配置 (application.yml)

# BladeX认证配置
blade:auth:# BladeX认证服务地址url: https://auth.example.com/oauth/token# 客户端IDclient-id: your_client_id# 客户端密钥client-secret: your_client_secret# 重定向URIredirect-uri: http://your-app-url/auth/blade-callback

5.2 前端配置 (.env.development)

# BladeX配置
VUE_APP_BLADE_AUTH_URL=https://auth.example.com/oauth/authorize
VUE_APP_BLADE_CLIENT_ID=your_client_id
VUE_APP_BLADE_REDIRECT_URI=http://your-app-url/auth/blade-callback

5.3 安全配置

SecurityConfig.java中添加允许匿名访问的路径:

@Override
protected void configure(HttpSecurity httpSecurity) throws Exception {httpSecurity// 其他配置.antMatchers("/blade/auth/getTokenInfo",// 其他允许匿名访问的路径).permitAll()
}

6. 实现步骤

6.1 前置准备

  1. 向BladeX系统管理员申请OAuth2.0客户端ID和密钥
  2. 确认并配置授权回调URL
  3. 确保若依系统中存在与BladeX用户名相匹配的账号

6.2 后端实现步骤

  1. 创建BladeAuthUtil工具类
  2. 实现BladeAuthController控制器
  3. 在application.yml中添加BladeX配置
  4. 更新SecurityConfig安全配置

6.3 前端实现步骤

  1. 在登录页添加BladeX登录按钮
  2. 创建回调处理页面BladeCallback.vue
  3. 配置前端环境变量
  4. 更新路由配置,添加回调页面路由

6.4 路由配置

在前端路由配置中添加BladeX回调页面:

// router/index.js
export const constantRoutes = [// 其他路由{path: '/auth/blade-callback',component: () => import('@/views/auth/BladeCallback'),hidden: true}
]

7. 集成测试

7.1 测试流程

  1. 点击BladeX登录按钮,验证是否正确重定向到BladeX授权页面
  2. 在BladeX系统完成登录授权
  3. 验证是否正确重定向回若依系统
  4. 检查是否成功获取若依JWT令牌
  5. 验证是否成功进入若依系统首页
  6. 测试若依系统的各项功能是否正常

7.2 故障排查

  1. 检查浏览器控制台日志
  2. 查看后端日志输出
  3. 使用开发者工具检查网络请求
  4. 验证Redis中是否成功缓存了登录用户信息

8. 安全与性能考虑

8.1 安全

  • 确保client_secret不被暴露在前端代码中
  • 实现CSRF防护
  • 设置合理的token过期时间
  • 考虑实现单点登出功能

8.2 性能

  • 缓存用户权限信息
  • 考虑多Redis节点的情况下的token共享
  • 优化前端资源加载

9. 常见问题与解决方案

9.1 回调地址配置问题

问题:BladeX系统报错"重定向URI不匹配"

解决方案:确保在BladeX系统注册的重定向URI与application.yml和前端环境变量中配置的完全一致,包括协议、域名、端口和路径。

9.2 无法获取用户信息

问题:获取到BladeX令牌但无法获取用户信息

解决方案:检查请求参数是否正确,特别是client_id和client_secret,并确认BladeX用户账号是否有效。

9.3 若依系统找不到对应用户

问题:BladeX认证成功但若依系统找不到对应用户

解决方案:确保在若依系统中创建与BladeX用户名相匹配的账号,或实现自动创建用户的功能。

10. 结论

通过本文档介绍的方法,成功实现了BladeX单点登录与若依框架的无缝集成,用户可以使用BladeX账号直接登录若依系统,享受到统一认证的便利性。集成过程充分利用了若依现有的登录机制,最小化了代码修改,确保了系统的稳定性和安全性。

本集成方案具有以下优势:

  • 完全复用若依原生登录流程的后半部分,确保与系统其他部分的一致性
  • 令牌格式、存储、过期机制与原生系统保持一致
  • 最小化修改,降低集成风险
  • BladeX用户享有与普通登录用户相同的体验

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

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

相关文章

初识Redis · set和zset

目录 前言&#xff1a; set 基本命令 交集并集差集 内部编码和应用场景 zset 基本命令 交集并集差集 内部编码和应用场景 应用场景&#xff08;AI生成&#xff09; 排行榜系统 应用背景 设计思路 热榜系统 应用背景 设计思路 热度计算方式 总结对比表 前言&a…

playwright 教程高级篇:掌握网页自动化与验证码处理等关键技术详解

Playwright 教程高级篇:掌握网页自动化与验证码处理等关键技术详解 本教程将带您一步步学习如何使用 Playwright——一个强大的浏览器自动化工具,来完成网页任务,例如提交链接并处理旋转验证码。我们将按照典型的自动化流程顺序,从启动浏览器到关闭浏览器,详细讲解每个步骤…

数据结构(完)

树 二叉树 构建二叉树 int value;Node left;Node right;public Node(int val) {valueval;} 节点的添加 Node rootnull;public void insert(int num) {Node nodenew Node(num);if(rootnull) {rootnode;return;}Node index root;while(true) {//插入的节点值小if(index.value&g…

FastAPI与SQLAlchemy数据库集成与CRUD操作

title: FastAPI与SQLAlchemy数据库集成与CRUD操作 date: 2025/04/16 09:50:57 updated: 2025/04/16 09:50:57 author: cmdragon excerpt: FastAPI与SQLAlchemy集成基础包括环境准备、数据库连接配置和模型定义。CRUD操作通过数据访问层封装和路由层实现,确保线程安全和事务…

一个基于Django的写字楼管理系统实现方案

一个基于Django的写字楼管理系统实现方案 用户现在需要我用Django来编写一个写字楼管理系统的Web版本&#xff0c;要求包括增删改查写字楼的HTML页面&#xff0c;视频管理功能&#xff0c;本地化部署&#xff0c;以及人员权限管理&#xff0c;包含完整的代码结构和功能实现&am…

mongodb在window10中创建副本集的方法,以及node.js连接副本集的方法

创建Mongodb的副本集最好是新建一个文件夹&#xff0c;如D:/data&#xff0c;不要在mongodb安装文件夹里面创建副本集&#xff0c;虽然这样也可以&#xff0c;但是容易造成误操作或路径混乱&#xff1b;在新建文件夹里与现有 MongoDB 数据隔离&#xff0c;避免误操作影响原有数…

Maven 多仓库与镜像配置全攻略:从原理到企业级实践

Maven 多仓库与镜像配置全攻略&#xff1a;从原理到企业级实践 一、核心概念&#xff1a;Repository 与 Mirror 的本质差异 在 Maven 依赖管理体系中&#xff0c;repository与mirror是构建可靠依赖解析链的两大核心组件&#xff0c;其核心区别如下&#xff1a; 1. Repositor…

STM32 四足机器人常见问题汇总

文章不介绍具体参数&#xff0c;有需求可去网上搜索。 特别声明&#xff1a;不论年龄&#xff0c;不看学历。既然你对这个领域的东西感兴趣&#xff0c;就应该不断培养自己提出问题、思考问题、探索答案的能力。 提出问题&#xff1a;提出问题时&#xff0c;应说明是哪款产品&a…

MySQL 中 `${}` 和 `#{}` 占位符详解及面试高频考点

文章目录 一、概述二、#{} 和 ${} 的核心区别1. 底层机制代码示例 2. 核心区别总结 三、为什么表名只能用 ${}&#xff1f;1. 预编译机制的限制2. 动态表名的实现 四、安全性注意事项1. ${} 的风险场景2. 安全实践 五、面试高频考点1. 基础原理类问题**问题 1**&#xff1a;**问…

C语言编译预处理2

#include <XXXX.h>和#include <XXXX.c> #include "XXXX.h" 是 C 语言中一条预处理指令 #include <XXXX.h>&#xff1a;这种形式用于包含系统标准库的头文件。预处理器会在系统默认的头文件搜索路径中查找XXXX.h 文件。例如在 Linux 系统中&#…

Elasticvue-轻量级Elasticsearch可视化管理工具

Elasticvue一个免费且开源的 Elasticsearch 在线可视化客户端&#xff0c;用于管理 Elasticsearch 集群中的数据&#xff0c;完全支持 Elasticsearch 版本 8.x 和 7.x. 功能特色&#xff1a; 集群概览索引和别名管理分片管理搜索和编辑文档REST 查询快照和存储库管理支持国际…

Git提交规范及最佳实践

Git 提交规范通常是为了提高代码提交的可读性、可维护性和自动化效率&#xff08;如生成 ChangeLog&#xff09;。以下是常见的 Conventional Commits 规范&#xff0c;结合社区最佳实践总结而成&#xff1a; 1. 提交格式 每次提交的 commit message 应包含三部分&#xff1a;…

Ubuntu中snap

通过Snap可以安装众多的软件包。需要注意的是&#xff0c;snap是一种全新的软件包管理方式&#xff0c;它类似一个容器拥有一个应用程序所有的文件和库&#xff0c;各个应用程序之间完全独立。所以使用snap包的好处就是它解决了应用程序之间的依赖问题&#xff0c;使应用程序之…

android studio 运行java main报错

运行某个带main函数的java文件报错 Could not create task :app:Test.main(). > SourceSet with name main not found. 解决办法&#xff1a;在工程的.idea/gradle.xml 文件下添加&#xff1a; <option name"delegatedBuild" value"false" /&g…

openssh离线一键升级脚本分享(含安装包)

查看当前的版本 [rootmyoracle ~]#ssh -V相关安装包下载地址 openssh下载地址&#xff1a;http://ftp.openbsd.org/pub/OpenBSD/OpenSSH/portable/openssl下载地址&#xff1a;https://www.openssl.org/source/zlib下载地址&#xff1a;http://www.zlib.net/今天演示从7.4升级…

Mac M1管理多个Node.js版本

目录 1. 使用 nvm (Node Version Manager) 1.1.安装 nvm 1.2.安装Node.js版本 1.3.查看已安装的node版本列表 1.4.使用特定版本的Node.js 1.5.查看当前使用的版本 2. 使用 fnm (Fast Node Manager) 2.1.安装 fnm 2.2.安装Node.js版本 2.3.查看已安装的版本 2.4.使用…

Unity中国战略调整简讯:Unity6下架 团结引擎接棒

Unity中国战略调整简讯&#xff1a;Unity6下架 团结引擎接棒 免费版 2025年4月9日 —— Unity中国宣布自即日起&#xff0c;中国大陆及港澳地区停止提供Unity 6及后续版本下载与服务&#xff0c;相关功能由国产引擎“团结引擎”承接。国际版2022 LTS及更早版本仍由Unity中国维护…

TestNG 单元测试详解

1、测试环境 jdk1.8.0 121 myeclipse-10.0-offline-installer-windows.exe TestNG 插件 org.testng.eclipse 6.8.6.20130607 0745 2、介绍 套件(suite):由一个 XML 文件表示,通过<suite>标签定义,包含一个或更多测试(test)。测试(test):由<test>定义&#xf…

C复习(主要复习)

指针和数组 指针数组是一个数组&#xff0c;数组的每个元素都是指针。它适用于需要存储多个指针的场景&#xff0c;如字符串数组。数组指针是一个指针&#xff0c;指向一个数组。它适用于需要传递整个数组给函数或处理多维数组的场景。 函数指针&#xff1a;函数指针的定义需要…

探索大语言模型(LLM):定义、发展、构建与应用

文章目录 引言大规模语言模型的基本概念大规模语言模型的发展历程1. 基础模型阶段&#xff08;2018年至2021年&#xff09;2. 能力探索阶段&#xff08;2019年至2022年&#xff09;3. 突破发展阶段&#xff08;以2022年11月ChatGPT的发布为起点&#xff09; 大规模语言模型的构…