应网友要求,从本文开始我们将实现一套基于springboot3+springsecurity的单点登录认证系统。
单点登录的实现方式有多种,接下来我们会以oauth2为例来介绍和实现。
单点登录(Single Sign-On,简称SSO)是一种身份验证机制,它允许用户一次登录后,在多个应用系统中无需再次输入用户名和密码就能访问。SSO的主要价值在于提高用户体验、增强安全性和简化管理。
SSO的实现通常依赖于标准协议和技术,常见的有以下几种:
SSO常见的实现方案、优缺点及其适用场景对比如下:
方案说明 | 优缺点 | 适用场景 |
---|---|---|
基于Cookie实现 | 优点1:简单易实现:利用HTTP Cookie进行状态维护,实现相对简单。 优点2:无状态服务:服务器不需要保存每个用户的会话状态,减轻了服务器负担。 缺点1:跨域限制:Cookie受同源策略限制,不适用于跨域场景。 缺点2:安全性问题:Cookie容易被截获或伪造,需要HTTPS等安全措施保护。 |
同一域名或子域名下的多个应用。 |
基于Session实现 | 状态持久化:可以存储更多的用户信息,支持更复杂的会话管理。 灵活性:通过分布式Session可以支持高可用和负载均衡。 性能开销:每次请求都需要查询Session信息,增加数据库或缓存系统的负担。 跨域问题:同样受限于同源策略,不适合跨域应用。 |
需要存储大量会话数据的场景,且应用位于同一域名下 |
基于Token的实现 | 无状态:服务器不需要保存会话状态,提高可伸缩性和安全性。 跨域支持:Token可以跨域传输,适用于微服务架构或多域名环境。 安全性:使用加密算法确保Token的安全性。 Token过期管理:需要设计合理的Token生命周期和刷新机制。 存储开销:对于大量并发用户,Token的存储和管理可能成为瓶颈。 |
微服务架构或涉及多域名的应用。 |
联邦身份认证 | 互操作性:遵循开放标准,支持跨组织的身份验证和授权。 灵活性:支持多种认证方式和第三方身份提供商。 复杂性:实现和配置较为复杂,需要对标准协议有深入理解。 依赖外部服务:如果使用第三方身份提供商,可能存在服务不可用的风险。 |
要跨组织或跨平台的身份认证,如企业间合作、***机构间的互联互通。如常见的Oauth2.0、CAS、SAML2.0等。 |
集中式身份管理 | 统一管理:集中管理用户身份和权限,简化管理和审计工作。 高效性:避免了每个应用独立维护用户信息的重复工作。 单点故障:集中式服务一旦出现问题,可能影响所有依赖它的应用。 迁移成本:如果已有大量应用,迁移到集中式身份管理系统可能需要较大的工程量。 |
大型企业内部或组织结构复杂的应用集群,需要统一的用户管理和权限控制 |
OAuth 2.0 是一种认证授权协议标准,有客户端模式(client_credentials)、密码模式(password)、简化模式(implicit)、授权码模式(authorization_code)、token刷新模式(refresh_token)。
介绍 OAuth 2.0 前,先介绍一下 OAuth 2.0 中涉及到的几种角色。
客户端(client):使用认证服务器作为认证渠道的平台,一般指的是第三方应用。例如,微信提供 OAuth 2.0 认证平台,我们的 APP 支持微信登录,那么我们的 APP 对于微信服务来说就是客户端。又例如,我们是***某一平台的服务,我们平台维护的数据代表着足够高的权威,那么其他***部门或合作方,需要从我们的平台中查询数据,或者利用我们平台的认证进行登录,那么其他部门或合作方的应用就是客户端。
资源服务器(Resource Server):简单的说,就是提供接口给客户端访问的服务器,访问资源服务器上受保护的接口,则需要带上令牌(token)。例如分布式微服务中的用户服务、订单服务等部署的服务器都属于资源服务器。
资源所有者(Resource Owner):拥有该资源的主体对象,一般指用户。客户端向资源服务器请求获取用户数据时,资源所有者参与确认授权或拒绝操作。
认证服务器(Authorization Server):对客户端和用户进行身份认证、授权的服务器,认证授权成功,则颁发令牌(token)。
客户端模式官网交互图如下:
客户端模式是拿权级别最低额且要求服务器对客户端高度信任的模式,因为客户端向认证服务器请求认证授权的过程中,自始至终都没有用户的参与,未经过用户允许,客户端凭借提供自己在认证服务器追测的信息即可在认证服务器完成认证授权,而客户端获得认证授权后,泽拥有从资源服务器操作用户数据的去厄,这种模式一般应用于公司内部系统或者有着高度保密责任的合作伙伴之间的对接,使用较多的场景是两个不同系统之间的开放API的认证。其时序图如下:
简要说明如下:
官网交互图如下:
这种方式是在客户端模式的基础上使用用户的账号和密码做认证,是一种相对来说非常不安全的方式,在oauth2.1中该方式已经被废弃了,不做过多说明。
官网交互图如下:
授权码模式是 OAuth 2.0 协议中安全级别最高的一种认证模式,与密码模式类似,都需要使用到用户的账号信息在认证平台的登录操作,但有所不同的是,密码模式是要求用户直接将自己在认证平台的账号、密码提供给第三方应用(客户端),由第三方平台进行代理用户在认证平台的登录操作;而授权码模式则是用户在认证平台提供的界面进行登录,然后通过用户确认授权后才将一次性授权码提供给第三方应用,第三方应用拿到一次性授权码以后才去认证平台获取 token。
授权码模式的时序图如下:
时序图说明如下:
授权码是我们在日常开发中最常见的认证方式了,虽略显复杂但却能保证安全性。如我们接入企业微信、微信登录时它们提供的都是基于授权码模式的相关API。
官网交互图如下:
简化模式(或者叫做隐身模式)是相对于授权码模式而言的,对授权码模式的交互做了一下简化,省去了客户端使用授权码去认证服务器换取令牌的操作,及用户在代理页面选择授权范围提交确认后认证服务器通过客户端注册的毁掉地址直接给客户端返回令牌了。
其时序图如下所示:
官网交互图如下:
RefreshToken模式是对access_token过期的一种补办操作,换句话说可以叫做自动续期。它在给客户端办法access_token的时候也会同时发放refresh_token,而refresh_token的有效期要远大于access_token的有效期,当客户端发现access_token过期时,客户端可以带着refresh_token向认证服务器请求一个新的access_token, 从而避免了用户的再次登录。当然如果refresh_token也过期的话是需要用户重新进行登录的。
其时序图如下:
相对来说比较好理解,不做过多说明。
Oauth2.1中去掉了密码模式、简化模式,增加了设备授权码模式,同时也对授权码模式增加了PKCE扩展,下面对Oauth2.1中的认证授权模式进行一些讲解。
OAuth2.0的客户端模式在OAuth2.1中被保留下来,基本流程和实现方案上与OAuth2.0中的是一致的。
授权码模式交互过程与OAuth2.0的是一致的,OAuth2.1版本提供了PKCE扩展。
PKCE(Proof Key for Code Exchange)是OAuth 2.1标准中推荐用于增强授权码(Authorization Code)流安全性的一个机制,特别是在处理公共客户端(public clients)时,如移动应用或JavaScript前端应用,这些客户端通常无法安全地存储客户端密钥(client secret)。PKCE通过引入临时的code_verifier和code_challenge对来防止中间人攻击和重放攻击。
在OAuth 2.1中,PKCE的流程如下:
在OAuth 2.1中,PKCE是强制性的,这意味着所有支持OAuth 2.1的授权服务器必须实现并支持PKCE,以确保更高的安全性。
设备授权码模式(Device Authorization grant)是OAuth 2.1规范中定义的一种授权模式,主要用于那些没有浏览器或者输入能力有限的设备,例如智能电视、游戏机、打印机等。这种模式允许设备发起授权请求,而最终的用户认证和授权决策则在另一个设备上完成,通常是用户的智能手机或计算机。
设备授权码模式的流程如下:
官网交互流程图如下:
该模式与oauth2.0的Refresh Token一致,不做赘述。
OpenID Connect (OIDC) 是一种基于 OAuth 2.x 的身份验证层,它允许应用程序不仅获取对资源的访问权限,还能获取有关授权用户的信息,包括但不限于用户的较早标识符、姓名、电子邮件等。
OpenID Connect 1.0(通常简称 OIDC)是建立在 OAuth 2.x 授权协议之上的,它利用 OAuth 的授权码、隐式、密码和客户端凭证等授权模式来实现身份验证。
OIDC 的核心概念包括:
通过这些特性,OpenID Connect 为基于 OAuth 2.x 的应用程序提供了一个标准化的方法来处理用户身份验证,使得开发者可以轻松地在不同服务之间实现单点登录(SSO)和身份信息共享。
本文主要是对单点登录及其实现方式做了一些介绍,同时介绍了OAuth2.0和OAuth2.1中的授权模式和一些关键概念,以此来作为后续文章的理论铺垫。接下来,我将基于本文的理论结合实际代码进行完整的流程实现。
针对本文提到的各个内容有任何疑问或者建议欢迎留言评论~~~
者可以轻松地在不同服务之间实现单点登录(SSO)和身份信息共享。
本文主要是对单点登录及其实现方式做了一些介绍,同时介绍了OAuth2.0和OAuth2.1中的授权模式和一些关键概念,以此来作为后续文章的理论铺垫。接下来,我将基于本文的理论结合实际代码进行完整的流程实现。
针对本文提到的各个内容有任何疑问或者建议欢迎留言评论~~~
创作不易,欢迎一键三连~~~~
TAG:如何实现单点登录