若依RuoYi-Vue项目接入第三方系统?手把手教你实现SSO单点登录(附完整代码)

若依RuoYi-Vue项目SSO单点登录深度整合指南

1. 企业级SSO架构设计原理

在数字化转型浪潮中,企业往往需要整合多个业务系统(如CRM、OA、ERP等),而统一身份认证成为刚需。基于若依(RuoYi-Vue)框架构建SSO认证中心,能够实现"一次登录,全网通行"的效果。其核心原理是通过中央认证服务(CAS)模式,将若依系统改造为认证枢纽。

关键组件交互流程

  1. 用户访问业务系统A时被重定向到若依登录页
  2. 成功认证后生成加密令牌(Token)并返回业务系统
  3. 业务系统携带令牌向若依验证中心发起校验请求
  4. 验证通过后建立本地会话,完成单点登录

注意:令牌应采用JWT标准格式,包含用户标识、有效期和数字签名,避免使用简单DES加密

典型SSO架构中的技术挑战包括:

  • 跨域会话管理
  • 令牌防篡改机制
  • 分布式会话同步
  • 安全退出所有系统

2. 若依后端改造实战

2.1 认证中心核心代码实现

SsoLoginController基础上进行企业级增强:

@PostMapping("/verify") @ApiOperation("令牌验证接口") public AjaxResult verifyToken(@RequestParam String token) { // JWT解析验证 Claims claims = Jwts.parser() .setSigningKey(secretKey) .parseClaimsJws(token) .getBody(); // 检查过期时间 if(claims.getExpiration().before(new Date())){ return AjaxResult.error("令牌已过期"); } // 返回用户基本信息 Map<String, Object> result = new HashMap<>(); result.put("username", claims.getSubject()); result.put("deptId", claims.get("deptId")); return AjaxResult.success(result); }

2.2 安全增强配置

SecurityConfig中增加OAuth2资源服务器配置:

@Override protected void configure(HttpSecurity http) throws Exception { http.oauth2ResourceServer() .jwt() .decoder(jwtDecoder()); // 原有配置... } @Bean public JwtDecoder jwtDecoder() { return NimbusJwtDecoder.withSecretKey( Keys.hmacShaKeyFor(secretKey.getBytes()) ).build(); }

关键参数对比

参数项简单实现企业级方案
令牌类型DES加密字符串JWT标准令牌
传输安全URL参数传递HTTPS+HttpOnly Cookie
会话管理内存存储Redis集群存储
跨域支持CORS精细控制

3. 前端接入方案详解

3.1 若依作为认证提供方

改造permission.js实现全局登录拦截:

router.beforeEach(async (to, from, next) => { // 白名单路径直接放行 if (whiteList.includes(to.path)) { next() return } // 检查是否存在有效令牌 const hasToken = getToken() if (hasToken) { next() } else { // 重定向到统一登录页 window.location.href = `https://sso.ruoyi.com/login?redirect=${encodeURIComponent(to.fullPath)}` } })

3.2 业务系统接入方案

第三方Vue应用接入示例:

// 在main.js中添加全局拦截 axios.interceptors.response.use(response => { return response }, error => { if (error.response.status === 401) { // 跳转到若依认证中心 const currentUrl = window.location.href window.location.href = `https://sso.ruoyi.com/login?service=${encodeURIComponent(currentUrl)}` } return Promise.reject(error) })

常见问题解决方案

  • 跨域问题:配置Nginx反向代理或后端CORS
  • 令牌过期:实现静默续签机制
  • 样式冲突:使用iframe嵌入或CSS命名空间隔离

4. 生产环境部署要点

4.1 高可用架构设计

建议采用以下部署架构:

  1. 认证服务集群部署,负载均衡
  2. Redis哨兵模式存储会话数据
  3. Nginx配置SSL终端和HTTP/2
  4. 分布式日志收集系统

4.2 性能优化配置

application.yml中添加关键参数:

spring: session: store-type: redis redis: flush-mode: on_save namespace: ruoyi:sessions security: oauth2: resourceserver: jwt: issuer-uri: https://sso.ruoyi.com

监控指标参考值

指标名称预警阈值优化建议
认证延迟>500ms增加Redis节点
并发会话数>10,000水平扩展实例
CPU使用率>70%优化JWT验签算法

5. 进阶安全策略

实现防重放攻击机制:

@RestController @RequestMapping("/api/sso") public class SsoController { @PostMapping("/nonce") public AjaxResult generateNonce() { String nonce = UUID.randomUUID().toString(); redisTemplate.opsForValue().set( "nonce:"+nonce, "1", 5, TimeUnit.MINUTES ); return AjaxResult.success(nonce); } }

在网关层添加安全过滤器:

public class SsoSecurityFilter implements Filter { @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) { HttpServletRequest req = (HttpServletRequest) request; String nonce = req.getHeader("X-Nonce"); if(!redisTemplate.hasKey("nonce:"+nonce)){ throw new IllegalStateException("非法请求"); } redisTemplate.delete("nonce:"+nonce); chain.doFilter(request, response); } }

实际部署中发现,采用JWT+Redis双校验机制可以在保证性能的同时有效防止令牌盗用。建议关键业务系统额外添加二次验证层,如短信验证码或生物识别验证。