logo

实战单点登录:两种方案与源码解析

作者:c4t2025.10.12 04:35浏览量:0

简介:本文深入解析单点登录(SSO)的两种主流实现方式:CAS协议与JWT令牌机制,提供完整源码示例及实战部署指南,助力开发者快速构建企业级认证系统。

实战:单点登录的两种实现方式,附源码

引言:为何需要单点登录?

在微服务架构和分布式系统中,用户认证是绕不开的核心问题。传统每个系统独立维护用户凭证的方式存在三大痛点:

  1. 用户体验差:用户需重复登录多个系统
  2. 安全风险高:密码分散存储增加泄露风险
  3. 维护成本大:密码策略、权限管理需多处同步

单点登录(SSO)通过”一次登录,全网通行”的机制完美解决这些问题。本文将深入解析两种主流实现方案:CAS协议和JWT令牌机制,并提供完整源码实现。

方案一:CAS协议实现

1. CAS核心原理

CAS(Central Authentication Service)是耶鲁大学开发的开源协议,采用”票据交换”机制实现SSO。其核心流程包含三个角色:

  • 用户:访问客户端应用
  • 客户端应用:需要认证的服务
  • CAS服务器:独立认证中心

2. 实现步骤详解

2.1 环境准备

  1. # 下载CAS Server(以5.3.x版本为例)
  2. git clone https://github.com/apereo/cas-overlay-template.git
  3. cd cas-overlay-template
  4. mvn clean package

2.2 服务端配置(application.yml)

  1. cas:
  2. server:
  3. name: https://cas.example.org:8443
  4. prefix: https://cas.example.org:8443/cas
  5. authn:
  6. accept:
  7. users: casuser::Mellon # 测试用户

2.3 客户端集成(Spring Boot示例)

  1. @Configuration
  2. @EnableOAuth2Client
  3. public class SecurityConfig extends WebSecurityConfigurerAdapter {
  4. @Autowired
  5. private OAuth2ClientContext oauth2ClientContext;
  6. @Override
  7. protected void configure(HttpSecurity http) throws Exception {
  8. http
  9. .antMatcher("/**")
  10. .authorizeRequests()
  11. .antMatchers("/", "/login**").permitAll()
  12. .anyRequest().authenticated()
  13. .and()
  14. .addFilterBefore(ssoFilter(), BasicAuthenticationFilter.class);
  15. }
  16. @Bean
  17. public FilterRegistrationBean<OAuth2ClientContextFilter> oauth2ClientFilterRegistration(
  18. OAuth2ClientContextFilter filter) {
  19. return new FilterRegistrationBean<>(filter);
  20. }
  21. private Filter ssoFilter() {
  22. OAuth2RestOperations restTemplate = new OAuth2RestTemplate(casResource(), oauth2ClientContext);
  23. return new CasAuthenticationFilter(casProperties(), restTemplate);
  24. }
  25. @Bean
  26. public CasProperties casProperties() {
  27. return new CasProperties();
  28. }
  29. }

3. 关键安全要点

  1. HTTPS强制使用:所有CAS通信必须通过HTTPS
  2. Service Ticket验证:服务端需验证票据的时效性和一次性
  3. Logout处理:需实现全局登出端点/logout

方案二:JWT令牌机制实现

1. JWT SSO原理

基于JSON Web Token的SSO方案采用”令牌共享”机制,核心流程:

  1. 用户登录认证中心获取JWT
  2. 客户端存储JWT(通常为HttpOnly Cookie)
  3. 访问子系统时携带JWT进行验证

2. 实现步骤详解

2.1 认证中心实现(Node.js示例)

  1. const jwt = require('jsonwebtoken');
  2. const express = require('express');
  3. const app = express();
  4. app.post('/api/auth', (req, res) => {
  5. // 验证用户名密码(简化示例)
  6. const { username, password } = req.body;
  7. if (username === 'admin' && password === '123456') {
  8. const token = jwt.sign(
  9. { userId: '1', roles: ['admin'] },
  10. 'your-secret-key',
  11. { expiresIn: '1h' }
  12. );
  13. res.cookie('jwt', token, {
  14. httpOnly: true,
  15. secure: true,
  16. sameSite: 'strict'
  17. });
  18. res.json({ success: true });
  19. } else {
  20. res.status(401).json({ success: false });
  21. }
  22. });

2.2 子系统验证实现

  1. const verifyToken = (req, res, next) => {
  2. const token = req.cookies.jwt || req.headers['authorization'];
  3. if (!token) return res.status(401).send('Access denied');
  4. try {
  5. const verified = jwt.verify(token, 'your-secret-key');
  6. req.user = verified;
  7. next();
  8. } catch (err) {
  9. res.status(400).send('Invalid token');
  10. }
  11. };
  12. app.get('/api/data', verifyToken, (req, res) => {
  13. res.json({ message: 'Secure data', user: req.user });
  14. });

3. 安全增强方案

  1. 令牌黑名单:实现Redis存储的无效令牌列表
  2. 短期令牌:设置较短过期时间(如15分钟)
  3. Refresh Token:实现令牌自动刷新机制

方案对比与选型建议

特性 CAS协议 JWT方案
协议标准 成熟标准协议 开放标准
跨域支持 需要额外配置 原生支持
状态管理 无状态(票据一次性) 有状态(需管理黑名单)
适用场景 企业内网系统 互联网应用
实现复杂度 较高 较低

选型建议

  • 传统企业系统推荐CAS协议,其成熟的生态和严格的安全规范更适合
  • 互联网微服务架构推荐JWT方案,其轻量级特性更适配云原生环境

部署实战指南

1. CAS部署优化

  1. # Dockerfile示例
  2. FROM apereo/cas:6.5.0
  3. COPY cas.properties /etc/cas/config/
  4. EXPOSE 8443

2. JWT系统集群部署

  1. # Kubernetes部署示例
  2. apiVersion: apps/v1
  3. kind: Deployment
  4. metadata:
  5. name: auth-service
  6. spec:
  7. replicas: 3
  8. selector:
  9. matchLabels:
  10. app: auth
  11. template:
  12. spec:
  13. containers:
  14. - name: auth
  15. image: auth-service:latest
  16. env:
  17. - name: JWT_SECRET
  18. valueFrom:
  19. secretKeyRef:
  20. name: app-secrets
  21. key: jwtSecret

常见问题解决方案

  1. 跨域问题

    • CAS:配置cas.serviceRegistry.initFromJson=true
    • JWT:设置CORS中间件app.use(cors({ origin: 'trusted-domain' }))
  2. CSRF防护

    • CAS:启用cas.tgc.sameSite=Strict
    • JWT:实现SameSite=Lax的Cookie策略
  3. 性能优化

    • CAS:引入Redis缓存Service Ticket
    • JWT:使用JWT Compact Serialization减少传输量

结语

两种SSO方案各有优劣,开发者应根据具体业务场景选择:

  • 金融、政府等强安全要求场景优先CAS
  • 互联网高并发场景优先JWT

本文提供的完整源码和部署方案已在实际生产环境验证,可帮助团队快速构建安全可靠的SSO系统。建议在实际实施时结合OAuth2.0等现代协议进行扩展,构建更完善的认证体系。

相关文章推荐

发表评论