专业的JAVA编程教程与资源

网站首页 > java教程 正文

单点登录(SSO)原理大揭秘:大龄程序员的硬核解析,看完秒懂!

temp10 2025-04-26 21:04:22 java教程 10 ℃ 0 评论

大家好,我是一名“久经沙场”的大龄程序员,今天我们来聊聊单点登录(SSO)的实现原理。单点登录是每个中大型系统必备的功能,但很多开发者对它一知半解,甚至觉得它很神秘。本文将用通俗易懂的语言,结合图文和代码,带你彻底搞懂 SSO 的实现原理。看完这篇文章,你不仅能轻松应对面试,还能在项目中游刃有余地实现 SSO!快来点赞、转发,分享给你的小伙伴吧!


1. 什么是单点登录(SSO)?

单点登录(Single Sign-On,简称 SSO)是一种用户身份验证机制,允许用户通过一次登录访问多个相互信任的应用系统。举个例子:

单点登录(SSO)原理大揭秘:大龄程序员的硬核解析,看完秒懂!

  • 你登录了淘宝后,可以直接访问天猫、阿里云等阿里系应用,无需再次登录。
  • 你登录了 Google 后,可以直接使用 Gmail、YouTube 等服务。

SSO 的核心目标是 提升用户体验降低系统复杂度


2. SSO 的核心原理

SSO 的核心原理可以用一句话概括:通过一个中央认证中心(CAS)管理用户的登录状态,并将登录状态共享给其他子系统。下面我们通过一个典型的 SSO 流程来详细解析。


SSO 流程详解

步骤 1:用户访问子系统 A

  1. 用户访问子系统 A(例如 app1.example.com)。
  2. 子系统 A 检查用户是否已登录。
  3. 如果未登录,重定向到中央认证中心(CAS)。

步骤 2:用户登录 CAS

  1. 用户在 CAS 页面输入用户名和密码。
  2. CAS 验证用户身份,生成一个全局会话(Global Session)和一个令牌(Ticket)。
  3. CAS 将用户重定向回子系统 A,并附带 Ticket。

步骤 3:子系统 A 验证 Ticket

  1. 子系统 A 向 CAS 发送请求,验证 Ticket 的有效性。
  2. CAS 返回验证结果,并附带用户信息。
  3. 子系统 A 创建局部会话(Local Session),并标记用户为已登录。

步骤 4:用户访问子系统 B

  1. 用户访问子系统 B(例如 app2.example.com)。
  2. 子系统 B 检查用户是否已登录。
  3. 如果未登录,重定向到 CAS。

步骤 5:CAS 检查全局会话

  1. CAS 发现用户已登录(存在全局会话),直接生成一个新的 Ticket。
  2. CAS 将用户重定向回子系统 B,并附带 Ticket。

步骤 6:子系统 B 验证 Ticket

  1. 子系统 B 向 CAS 发送请求,验证 Ticket 的有效性。
  2. CAS 返回验证结果,并附带用户信息。
  3. 子系统 B 创建局部会话,并标记用户为已登录。

3. 关键技术点

(1)Cookie 的作用

  • CAS 和子系统之间通过 Cookie 共享用户的登录状态。
  • CAS 的 Cookie 是全局的(例如 .example.com),子系统的 Cookie 是局部的(例如 app1.example.com)。

(2)Ticket 的作用

  • Ticket 是一个临时令牌,用于在 CAS 和子系统之间传递用户的登录状态。
  • Ticket 是一次性的,验证后立即失效。

(3)Session 的作用

  • CAS 维护一个全局会话(Global Session),用于存储用户的登录状态。
  • 每个子系统维护一个局部会话(Local Session),用于存储用户在该系统的登录状态。

4. 代码实现

下面是一个简单的 SSO 实现示例,使用 Spring Boot 和 Redis 作为全局会话存储。

CAS 服务端

@RestController
public class CASController {

    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    @PostMapping("/login")
    public String login(@RequestParam String username, @RequestParam String password, HttpServletResponse response) {
        // 验证用户名和密码
        if ("admin".equals(username) && "123456".equals(password)) {
            // 生成 Ticket
            String ticket = UUID.randomUUID().toString();
            // 存储全局会话
            redisTemplate.opsForValue().set(ticket, username);
            // 设置全局 Cookie
            response.addCookie(new Cookie("sso_token", ticket));
            return ticket;
        }
        return "登录失败";
    }

    @GetMapping("/validate")
    public String validate(@RequestParam String ticket) {
        // 验证 Ticket
        return redisTemplate.opsForValue().get(ticket);
    }
}

子系统 A

@RestController
public class App1Controller {

    @GetMapping("/home")
    public String home(@RequestParam(required = false) String ticket, HttpServletResponse response) {
        if (ticket != null) {
            // 向 CAS 验证 Ticket
            String username = restTemplate.getForObject("http://cas.example.com/validate?ticket=" + ticket, String.class);
            if (username != null) {
                // 创建局部会话
                response.addCookie(new Cookie("app1_token", username));
                return "欢迎回来," + username;
            }
        }
        // 重定向到 CAS
        return "redirect:http://cas.example.com/login?redirect=http://app1.example.com/home";
    }
}

5. 总结

单点登录(SSO)的实现原理并不复杂,核心是通过一个中央认证中心(CAS)管理用户的登录状态,并将登录状态共享给其他子系统。本文通过图文和代码,详细解析了 SSO 的流程和关键技术点。希望这篇文章能帮助你彻底搞懂 SSO,并在实际项目中灵活应用。

如果你觉得这篇文章对你有帮助,别忘了 点赞、转发,分享给你的小伙伴!关注我,获取更多硬核技术干货!


我是大龄程序员,技术永不老!

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表