【架构设计】单点登录实现技术方案

简介: 【架构设计】单点登录实现技术方案

1 基本介绍

1.1 什么是单点登录

单点登录(Single Sign-On,简称SSO)是一种身份认证的解决方案,它允许用户只需一次登录即可访问多个应用程序或系统。在一个典型的SSO系统中,用户只需通过一次身份认证,就可以获得访问多个应用程序的授权,而不需要在每个应用程序中单独进行身份验证。


1.2 单点登录的原理

单点登录(Single Sign-On,简称SSO)的实现原理通常涉及到以下几个步骤:


1.用户登录认证:用户在访问第一个应用程序时,需要进行身份验证并登录系统。这个过程可以使用任何一种常规的认证方式,比如用户名和密码、二次验证等等。

2.生成令牌:认证通过后,系统会生成一个安全令牌(Token),将它存储在用户的浏览器中,同时将该令牌的信息存储在SSO服务器中。

3.传递令牌:当用户访问其他应用程序时,应用程序将向SSO服务器发送令牌验证请求。SSO服务器会检查浏览器中的令牌信息,并确认用户的身份。

4.验证身份:如果令牌有效且用户已经进行过身份验证,SSO服务器会向应用程序返回一个授权令牌,授权用户访问该应用程序。

5.访问应用程序:应用程序会使用授权令牌来验证用户的身份,并允许用户访问应用程序的资源。


需要注意的是,SSO服务器需要能够识别和验证来自不同应用程序的令牌。为了实现这一点,通常使用标准的认证协议,如OAuth、OpenID Connect等,这些协议为应用程序提供了一种标准的方式来与SSO服务器交互。此外,SSO服务器还需要实现一些安全机制来防止令牌被盗用或伪造,如Token加密、过期时间等等。


1.3 单点登录实现方案

单点登录的实现方式通常有以下几种:


基于JWT实现同域下的单点登录

基于Cookie的SSO

基于Token的SSO

基于SAML的SSO

基于OpenID Connect的SSO

CAS(Central Authentication Service)


需要注意的是,不同的SSO实现方式有不同的优缺点,选择适合自己应用场景的实现方式非常重要。

此外,SSO系统的实现需要考虑安全性和可靠性问题,如令牌加密、过期时间、安全断言的验证等等。


今天详细讲解一下:

  • 基于JWT实现同域下的单点登录
  • CAS(Central Authentication Service)


2 方案介绍

2.1 基于JWT实现同域下的单点登录

同域单点登录(SSO)是一种允许用户在一个网站登录后,在访问其他同域网站时无需再次登录的技术。下面介绍一种基于基于JWT的单点登录的Token同域单点登录实现方案

2.1.1 JWT介绍


JSON Web Token(JWT)是一种轻量级的、基于标准JSON格式的身份验证和授权机制。

在SSO方案中,可以使用JWT作为Token,在JWT中存储用户信息和过期时间等信息。

JWT的签名和加密机制可以保证Token的安全性,防止Token被篡改和伪造。在每次访问其他同域网站时,前端将JWT发送给后端进行验证和解析,以获取用户信息和过期时间等信息。

2.1.2 详细步骤介绍

下面是基于JWT实现同域下的单点登录的详细步骤:


1.用户登录应用程序A,应用程序A将用户的身份信息打包成JWT,并设置有效期和其他必要的信息。JWT的生成可以使用各种JWT库,如jsonwebtoken。

2.应用程序A将JWT存储在cookie或localStorage中,并将其发送给浏览器。

3.用户访问应用程序B,应用程序B将检查cookie或localStorage中是否存在有效的JWT。

4.如果JWT存在且未过期,则应用程序B使用JWT库对JWT进行解码和验证,并从中获取用户的身份信息。

5.如果JWT验证成功,则应用程序B授权用户访问应用程序B。

6.如果JWT不存在或已过期,则应用程序B要求用户登录。

7.在用户注销或会话过期时,应用程序A和B都需要清除JWT。

需要注意以下几点:

  • 应用程序A和B必须使用相同的JWT密钥,以确保JWT在不同的应用程序之间是可验证的。
  • 应用程序应该使用HTTPS协议来保护JWT的传输,以避免中间人攻击。
  • 应用程序应该设置JWT的有效期适当,以避免安全漏洞和用户体验之间的矛盾。
  • 应用程序应该定期更改JWT密钥,以增强安全性。

总之,基于JWT实现同域下的单点登录可以提高用户体验和应用程序的安全性,但需要注意确保JWT的安全性和可靠性。

2.1.3 图解步骤


2.1.4 JWT代码示例

不能直接放项目代码,所以放了示例,具体的规则,根据你的项目去设置,这个只是个示例。

当使用Java实现JWT时,可以使用Java JWT库(Java JWT Library)来生成和验证JWT。

下面是一个使用Java JWT库创建和验证JWT的示例代码:

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import java.util.Date;
public class JwtUtils {
    private static final String SECRET_KEY = "your-secret-key"; // 密钥,用于签名和验证JWT
    private static final long EXPIRATION_TIME = 3600_000; // 有效期,单位为毫秒,这里设置为1小时
    public static String createJwt(String subject) {
        Date now = new Date();
        Date expiration = new Date(now.getTime() + EXPIRATION_TIME);
        return Jwts.builder()
                .setSubject(subject)
                .setIssuedAt(now)
                .setExpiration(expiration)
                .signWith(SignatureAlgorithm.HS256, SECRET_KEY)
                .compact();
    }
    public static String verifyJwt(String jwt) {
        try {
            Claims claims = Jwts.parser()
                    .setSigningKey(SECRET_KEY)
                    .parseClaimsJws(jwt)
                    .getBody();
            return claims.getSubject();
        } catch (Exception e) {
            // JWT验证失败,可能是过期或伪造
            return null;
        }
    }
}

在上述示例代码中,createJwt方法用于生成JWT,包括设置sub(subject)、iat(issued at)和exp(expiration time)声明,并使用HS256算法和密钥对JWT进行签名。verifyJwt方法用于验证JWT,并从中提取sub声明。

以下是使用示例:

public class Example {
    public static void main(String[] args) {
        String jwt = JwtUtils.createJwt("123");
        System.out.println(jwt);
        String subject = JwtUtils.verifyJwt(jwt);
        System.out.println(subject);
    }
}

在上述示例中,createJwt方法生成JWT,并将其打印到控制台。verifyJwt方法验证JWT,并将其中的sub声明提取出来打印到控制台。


需要注意的是,在实际应用中,应该将密钥和有效期等敏感信息存储在安全的地方,如配置文件或环境变量中,并使用安全加密方式进行存储和传输。

2.1.5 拓展

将Cookie的域设置为顶域实现方式

1 前端

将Cookie的域设置为顶域(即一级域名),需要在设置Cookie时将domain属性设置为顶域名,例如,如果当前网站的域名为example.com,那么可以将domain属性设置为".example.com",表示该Cookie在该域名及其所有子域名下都有效。

在使用Node.js的Express框架时,可以通过设置res.cookie()方法的domain选项来设置Cookie的域,例如:

res.cookie('mycookie', 'myvalue', { domain: '.example.com' });

在上面的例子中,domain选项被设置为".example.com",表示该Cookie在example.com及其所有子域名下都有效。

2 后端

在Java中,可以通过设置Cookie的domain属性来将Cookie的域设置为顶域(即一级域名)。

假设当前网站的域名为example.com,如果要将Cookie的域设置为该域名及其所有子域名下都有效,可以通过以下方式设置:

Cookie cookie = new Cookie("mycookie", "myvalue"); cookie.setDomain(".example.com"); // 将域设置为".example.com" response.addCookie(cookie); // 将Cookie添加到HTTP响应中

在上面的代码中,使用Cookie类创建了一个名为"mycookie",值为"myvalue"的Cookie,并通过setDomain()方法将其域设置为".example.com"。

然后,将Cookie添加到HTTP响应中,即可将该Cookie发送给客户端。

2.2 CAS实现单点登录:

CAS是一个开源的单点登录协议,它使用Ticket Granting Ticket(TGT)和Service Ticket(ST)来实现单点登录。用户登录后,CAS服务器会生成一个TGT,并将其存储在用户的浏览器中。当用户访问其他应用程序时,应用程序会向CAS服务器发送一个ST验证请求。CAS服务器会检查TGT和ST,并确认用户的身份后,向应用程序发回授权信息。

下面是使用CAS实现单点登录的详细步骤:

  1. 部署CAS服务器
  2. 配置CAS客户端
  3. 用户登录
  4. 验证票据
  5. 获取服务票据
  6. 验证服务票据

1 部署CAS服务器:

首先需要在服务器上部署CAS服务器,并配置其参数,如登录页面、认证方式、客户端等。可以使用Maven或手动下载CAS Server WAR包,然后将其部署到Web容器中,如Tomcat或Jetty。在部署之前,需要先配置CAS服务器的参数,如CAS服务名称、CAS服务地址、登录页面、认证方式等。在完成配置后,启动Web容器,并访问CAS登录页面,以确保CAS服务器能够正常工作。

2 配置CAS客户端:

对于需要实现单点登录的应用程序,需要将其配置为CAS客户端,并在其上实现CAS协议。可以使用CAS客户端库,如Jasig CAS Client、Spring Security CAS等,也可以手动实现CAS协议。在CAS客户端中,需要指定CAS服务器的地址和协议,并设置CAS客户端的参数,如服务名称、退出URL等。为了实现单点登录,所有需要实现单点登录的应用程序都需要配置为CAS客户端。

3 用户登录:

当用户访问CAS客户端时,CAS客户端会将用户重定向到CAS服务器的登录页面,要求用户输入用户名和密码进行身份验证。用户输入用户名和密码后,CAS服务器根据配置的认证方式进行身份验证。如果身份验证成功,则CAS服务器生成一个票据(Ticket),并将其返回给CAS客户端。

4 验证票据:

CAS客户端收到票据后,将其发送给CAS服务器进行验证。如果票据有效,则CAS服务器会生成一个票据授权(Ticket Granting Ticket,TGT),并将其返回给CAS客户端。TGT是CAS服务器生成的一个唯一标识符,用于标识用户的身份信息。

5 获取服务票据:

CAS客户端使用TGT来获取服务票据(Service Ticket,ST),并将其发送给CAS服务器。服务票据包含了用户的身份信息,可以用于在应用程序中进行身份验证。CAS客户端使用服务名称(service)作为参数请求ST,CAS服务器根据TGT生成ST,并将其返回给CAS客户端。

6 验证服务票据:

应用程序收到服务票据后,将其发送给CAS客户端进行验证。如果服务票据有效,则CAS客户端会将其中的用户身份信息提取出来,并将其传递给应用程序。应用程序可以根据身份信息进行用户授权和访问控制。

优缺点

优点:

  1. 用户体验好:使用CAS实现单点登录可以提高用户体验,用户只需要登录一次就可以访问多个应用程序,不需要重复输入用户名和密码。
  2. 安全性高:CAS使用票据(Ticket)来验证用户身份,票据只能在CAS服务器和客户端之间传递,防止了密码被截获的风险。此外,CAS支持多种认证方式,如LDAP、数据库、Active Directory等,可以根据需要选择适合自己的认证方式。
  3. 可扩展性好:CAS支持多种客户端库和API,可以轻松地与其他应用程序集成。此外,CAS还支持多种存储方式,如内存、数据库、LDAP等,可以根据需要进行扩展。
  4. 开源免费:CAS是一个开源项目,可以免费使用和修改,没有额外的授权费用。

缺点:

  1. 配置和实现复杂:CAS的配置和实现较为复杂,需要对CAS服务器和客户端进行配置和开发,需要一定的技术和经验。
  2. 单点故障:由于CAS是一个中心化的单点登录服务,如果CAS服务器出现故障,所有的应用程序都将无法访问,可能会影响业务运行。
  3. 性能瓶颈:由于所有的应用程序都需要通过CAS服务器进行身份验证,如果请求量过大,可能会导致CAS服务器性能瓶颈。

综上所述,CAS实现单点登录具有良好的用户体验和安全性,但需要注意配置和实现细节,同时需要解决单点故障和性能瓶颈等问题。

小结

需要注意,CAS服务器和客户端之间的通信应该使用HTTPS协议进行加密,以保证安全性。此外,CAS服务器和客户端之间的通信需要使用相同的加密密钥,以确保票据的安全性。

总之,使用CAS实现单点登录可以提高用户体验和应用程序的安全性,但需要注意配置和实现细节。

3 总结

总结一下单点登录要实现的内容:

  • 单点登录(SSO系统)是保障各业务系统的用户资源的安全 。
  • 各个业务系统获得的信息是,这个用户能不能访问我的资源。
  • 单点登录,资源都在各个业务系统这边,不在SSO那一方。
  • 用户在给SSO服务器提供了用户名密码后,作为业务系统并不知道这件事。 SSO随便给业务系统一个ST,那么业务系统是不能确定这个ST是用户伪造的,还是真的有效,所以网关要进行JWT校验,从而保证token的有效性


相关实践学习
基于函数计算快速搭建Hexo博客系统
本场景介绍如何使用阿里云函数计算服务命令行工具快速搭建一个Hexo博客。
相关文章
|
3月前
|
负载均衡 关系型数据库 应用服务中间件
高可用系列文章之二 - 传统分层架构技术方案
高可用系列文章之二 - 传统分层架构技术方案
|
21小时前
|
Kubernetes API 开发者
构建高效微服务架构:后端开发的新范式
【5月更文挑战第2天】 随着现代软件开发的演进,传统的单体应用已难以满足快速变化的业务需求和敏捷开发的挑战。本文探讨了如何通过构建高效的微服务架构来提升后端开发的灵活性、可维护性和扩展性。我们将深入分析微服务的核心组件,包括服务拆分、容器化、API网关和持续集成/持续部署(CI/CD)等关键技术,并讨论它们如何共同作用以支持复杂的业务场景和云原生应用的需求。
6 1
|
21小时前
|
负载均衡 Java API
构建高效微服务架构:API网关与服务熔断策略
【5月更文挑战第2天】 在微服务架构中,确保系统的高可用性与灵活性是至关重要的。本文将深入探讨如何通过实施有效的API网关和设计合理的服务熔断机制来提升分布式系统的鲁棒性。我们将分析API网关的核心职责,包括请求路由、负载均衡、认证授权以及限流控制,并讨论如何利用熔断器模式防止故障传播,维护系统的整体稳定性。文章还将介绍一些实用的技术和工具,如Netflix Zuul、Spring Cloud Gateway以及Hystrix,以帮助开发者构建一个可靠且高效的微服务环境。
|
2天前
|
监控 安全 开发者
构建高效可靠的微服务架构:后端开发的新范式
【4月更文挑战第30天】随着现代软件开发的复杂性日益增加,传统的单体应用架构已难以满足快速迭代与灵活部署的需求。微服务架构作为一种新兴的设计理念,它通过将一个大型应用程序拆分成一系列小而专注的服务来提供解决方案。本文旨在探讨如何构建一个高效且可靠的微服务架构系统,涵盖从设计原则、技术选型到部署实践的全方位知识,为后端开发者提供一种全新的开发思路和实践指导。
|
2天前
|
Java 调度 开发者
构建高效微服务架构:后端开发的新趋势深入理解操作系统之进程调度策略
【4月更文挑战第30天】 随着企业数字化转型的不断深入,传统的单体应用逐渐不能满足快速迭代和灵活部署的需求。微服务架构以其高度模块化、独立部署和易于扩展的特性,成为现代后端开发的重要趋势。本文将探讨如何构建一个高效的微服务架构,包括关键的设计原则、技术选型以及可能面临的挑战。
|
2天前
|
Cloud Native Devops 持续交付
构建未来:云原生架构在企业数字化转型中的关键作用构建高效微服务架构:后端开发的新范式
【4月更文挑战第30天】 随着企业加速其数字化进程,云原生架构已成为支撑复杂、可伸缩和灵活应用的骨干。本文探讨了云原生技术的崛起,重点分析了其在促进业务敏捷性、提高运营效率及推动创新方面的核心价值。通过深入剖析云原生生态系统的关键技术组件,如容器化、微服务、持续集成/持续部署(CI/CD)和DevOps实践,揭示了企业如何利用这些技术来构建和维护高度可用且动态的IT环境。文章还提出了一个多维度的采纳框架,帮助企业评估和实施云原生解决方案,以实现真正的业务价值。 【4月更文挑战第30天】在现代软件开发的快速演变中,微服务架构已经成为一种领先的设计模式,用于构建可扩展、灵活且容错的应用程序。与传
|
2天前
|
消息中间件 监控 负载均衡
构建高效微服务架构:后端开发的新范式
【4月更文挑战第30天】 在现代软件开发的浪潮中,微服务架构已成为一种广泛采用的设计模式。它通过将大型应用程序拆分成一组小型、松散耦合的服务来增强系统的可维护性、可扩展性和敏捷性。本文将探讨如何构建一个高效的微服务架构,包括关键的设计原则、技术选型、以及实现过程中的最佳实践。我们将深入讨论微服务间的通信机制、数据一致性问题、服务发现与负载均衡策略,以及如何确保系统的安全性和监控。
|
2天前
|
运维 监控 数据可视化
探索微服务架构下的系统监控策略
【4月更文挑战第30天】 在当今快速迭代和持续部署盛行的软件发展环境中,微服务架构以其灵活性、可扩展性成为众多企业的首选。然而,随着服务的细分与增多,传统的监控手段已不足以应对复杂多变的系统状态。本文将深入探讨在微服务架构中实施有效系统监控的策略,包括指标的选择、数据的收集与处理,以及监控信息的可视化等方面。通过分析现有问题,并提出切实可行的解决方案,旨在帮助开发者构建更健壮、更易于管理的微服务系统。
|
2天前
|
机器学习/深度学习 安全 网络安全
数字堡垒的构筑者:网络安全与信息安全的深层剖析构建高效微服务架构:后端开发的新趋势
【4月更文挑战第30天】在信息技术高速发展的今天,构建坚不可摧的数字堡垒已成为个人、企业乃至国家安全的重要组成部分。本文深入探讨网络安全漏洞的本质、加密技术的进展以及提升安全意识的必要性,旨在为读者提供全面的网络安全与信息安全知识框架。通过对网络攻防技术的解析和案例研究,我们揭示了防御策略的关键点,并强调了持续教育在塑造安全文化中的作用。
|
2天前
|
缓存 监控 API
构建高效微服务架构:后端开发的新范式
【4月更文挑战第30天】 随着现代软件开发的演进,传统的单体应用逐渐向微服务架构转变。本文将深入探讨微服务的核心概念、优势以及在设计高效后端系统时所面临的挑战。通过实例分析与最佳实践的结合,我们将揭示如何优化微服务的性能,保证系统的可扩展性、可维护性和安全性。