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

news2025/4/19 5:55:38

在这里插入图片描述

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;
    
    @Autowired
    private ISysUserService userService;
    
    @Autowired
    private TokenService tokenService;
    
    @Autowired
    private 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授权页面URL
      const 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) {
      // 保存token
      setToken(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
    # 客户端ID
    client-id: your_client_id
    # 客户端密钥
    client-secret: your_client_secret
    # 重定向URI
    redirect-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.coloradmin.cn/o/2336970.html

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

相关文章

JVM 内存调优

内存调优 内存泄漏&#xff08;Memory Leak&#xff09;和内存溢出&#xff08;Memory Overflow&#xff09;是两种常见的内存管理问题&#xff0c;它们都可能导致程序执行不正常或系统性能下降&#xff0c;但它们的原因和表现有所不同。 内存泄漏 内存泄漏&#xff08;Memo…

Shell脚本提交Spark任务简单案例

一、IDEA打包SparkETL模块&#xff0c;上传值HDFS的/tqdt/job目录 二、创建ods_ETL.sh脚本 mkdir -p /var/tq/sh/dwd vim /var/tq/sh/dwd/ods_ETL.sh chmod 754 /var/tq/sh/dwd/ods——ETL.sh #脚本内容如下 #!/bin/bash cur_date$(date %Y-%m-%d) /opt/bigdata/spark-3.3.2/b…

国标GB28181视频平台EasyCVR视频汇聚系统,打造别墅居民区智能监控体系

一、现状背景 随着国家经济的快速增长&#xff0c;生活水平逐渐提高&#xff0c;私人别墅在城市、乡镇和农村的普及率也在逐年增加。然而&#xff0c;由于别墅区业主经济条件较好&#xff0c;各类不法事件也日益增多&#xff0c;主要集中在以下几个方面&#xff1a; 1&#x…

BGP分解实验·23——BGP选路原则之路由器标识

在选路原则需要用到Router-ID做选路决策时&#xff0c;其对等体Router-ID较小的路由将被优选&#xff1b;其中&#xff0c;当路由被反射时&#xff0c;包含起源器ID属性时&#xff0c;该属性将代替router-id做比较。 实验拓扑如下&#xff1a; 实验通过调整路由器R1和R2的rout…

【玩泰山派】MISC(杂项)- 使用vscode远程连接泰山派进行开发

文章目录 前言流程1、安装、启动sshd2、配置一下允许root登录3、vscode中配置1、安装remote插件2、登录 **注意** 前言 有时候要在开发板中写一写代码&#xff0c;直接在终端中使用vim这种工具有时候也不是很方便。这里准备使用vscode去通过ssh远程连接泰山派去操作&#xff0…

同步/异步日志系统

同步/异步日志系统 项目演示基础测试性能测试测试环境&#xff1a;同步日志器单线程同步日志器多线程异步日志器单线程异步日志器多线程 工具类&#xff08;util.hpp&#xff09;日志等级level.hpp 日志消息message.hpp 日志消息格式化formatter.hpp 日志消息落地sink.hpp 日志…

typescript html input无法输入解决办法

input里加上这个&#xff1a; onkeydown:(e: KeyboardEvent) > {e.stopPropagation();

游戏引擎学习第224天

回顾游戏运行并指出一个明显的图像问题。 回顾一下之前那个算法 我们今天要做一点预加载的处理。上周刚完成了游戏序章部分的所有剪辑内容。在运行这一部分时&#xff0c;如果观察得足够仔细&#xff0c;就会注意到一个问题。虽然因为视频流压缩质量较低&#xff0c;很难清楚…

工厂能耗系统智能化解决方案 —— 安科瑞企业能源管控平台

安科瑞顾强 政策背景与“双碳”战略驱动 2025年《政府工作报告》明确提出“单位国内生产总值能耗降低3%左右”的目标&#xff0c;要求通过产业结构升级&#xff08;如高耗能行业技术革新或转型&#xff09;、能源结构优化&#xff08;提高非化石能源占比&#xff09;及数字化…

【pytorch图像视觉】lesson17深度视觉应用(上)构建自己的深度视觉项目

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、 数据1、认识经典数据1.1入门数据&#xff1a;MNIST、其他数字与字母识别&#xff08;1&#xff09;数据下载&#xff08;2&#xff09;查看数据的特征和标…

USB(TYPE-C)转串口(TTL)模块设计讲解

目录 一 、引言 二、方案设计 三、USB TYPE-C介绍 1、TYPE-C接口定义 1、24P全引脚描述 2、Type C 接口 VBUS/GND 作用 3、Type C 接口 D/D- 作用 1、数据传输&#xff1a; 2、设备识别&#xff1a; 3、充电协议协商&#xff1a; 4、Type C 接口 CC1/CC2 作用 1、主从设备区…

PyTorch张量操作指南:cat、stack、split与chunk的实战拆解

本文深入探讨PyTorch中用于调整张量结构的四个核心函数——torch.cat、torch.stack、torch.split和torch.chunk。通过实际应用场景分析和代码演示&#xff0c;帮助读者掌握它们的功能差异及适用条件&#xff0c;提升模型开发的灵活性与效率。 在深度学习实践中&#xff0c;张量…

YOLO涨点技巧之分层扩展路径聚合网络 (HEPAN)

一、应用场景与问题背景 1.1 无人机图像检测挑战 https://ai-studio-static-online.cdn.bcebos.com/3d4f7e8c4d8d4d2d8a4c8e4b4e8c4d8d ​场景特点:无人机航拍视角下的小目标检测(如行人、车辆、农作物病害等)​核心难点: 目标尺寸小(<3232像素)复杂背景干扰(如城市…

玩机进阶教程----MTK芯片设备刷机导致的死砖修复实例解析 连电脑毫无反应 非硬件问题

在高通芯片机型中,我们可以通过短接主板测试点来激活高通芯片特有的9008底层端口来刷写救砖固件。但通常MTK芯片类的设备联机电脑即可触发深刷模式。但有些例外的情况会导致链接电脑毫无反应。遇到类似故障的友友可以参阅此博文尝试解决。 通过博文了解 1💝💝💝-----实…

MIPI协议介绍

MIPI协议介绍 mipi 协议分为 CSI 和DSI,两者的区别在于 CSI用于接收sensor数据流 DSI用于连接显示屏 csi分类 csi 分为 csi2 和 csi3 csi2根据物理层分为 c-phy 和 d-phy, csi-3采用的是m-phy 一般采用csi2 c-phy 和 d-phy的区别 d-phy的时钟线和数据线是分开的,2根线一对…

AI应用开发平台 和 通用自动化工作流工具 的详细对比,涵盖定义、核心功能、典型工具、适用场景及优缺点分析

以下是 AI应用开发平台 和 通用自动化工作流工具 的详细对比&#xff0c;涵盖定义、核心功能、典型工具、适用场景及优缺点分析&#xff1a; 1. AI应用开发平台 vs 通用自动化工作流工具 (1) 定义与目标 类型AI应用开发平台通用自动化工作流工具定义用于快速构建、训练、部署…

智慧社区数据可视化中枢平台——Axure全场景交互式大屏解决方案

在数字化治理的时代浪潮中&#xff0c;社区管理正面临数据碎片化、响应滞后、决策盲区等核心挑战。如何将分散的安防、环境、能源、民生服务等数据整合为可操作的智慧洞察&#xff1f;如何让冰冷的数字转化为社区管理者手中的决策利器&#xff1f;Axure智慧社区可视化大屏原型模…

Axure高保真AI算法训练平台

点击下载《Axure高保真AI算法训练平台(.rp) 》 原型效果&#xff1a;https://axhub.im/ax9/69fdf8f2b10b59c3/#g1 摘要 本文介绍了一款功能全面且高效的AI算法训练平台&#xff0c;旨在为数据科学家、研究人员和工程师提供从数据准备到模型部署的一站式解决方案。该平台由四大…

C++ Json-Rpc框架-3项目实现(2)

一.消息分发Dispatcher实现 Dispatcher 就是“消息分发中枢”&#xff1a;根据消息类型 MType&#xff0c;把消息派发给对应的处理函数&#xff08;Handler&#xff09;执行。 初版&#xff1a; #pragma once #include "net.hpp" #include "message.hpp"n…

OpenAI发布GPT-4.1系列模型——开发者可免费使用

OpenAI刚刚推出GPT-4.1模型家族&#xff0c;包含GPT-4.1、GPT-4.1 Mini和GPT-4.1 Nano三款模型。重点是——现在全部免费开放&#xff01; 虽然技术升级值得关注&#xff0c;但真正具有变革意义的是开发者能通过Cursor、Windsurf和GitHub Copilot等平台立即免费调用这些模型。…