SpringCloud之SSO单点登录-基于Gateway和OAuth2的跨系统统一认证和鉴权详解

单点登录(SSO)是一种身份验证过程,允许用户通过一次登录访问多个系统。本文将深入解析单点登录的原理,并详细介绍如何在Spring Cloud环境中实现单点登录。通过具体的架构图和代码示例,我们将展示SSO的工作机制和优势,帮助开发者更好地理解和应用这一技术。

在这里插入图片描述


一、单点登录简介

1、单点登录介绍

单点登录(Single Sign-On,简称SSO)是一种认证机制,允许用户通过一次身份验证后,访问多个相互信任的应用系统。它简化了用户的操作,提高了用户体验,同时也降低了管理多个认证系统的复杂性。在现代分布式系统和微服务架构中,SSO尤为重要,因为它可以减少重复的登录操作,统一用户认证入口,提高系统的安全性和可管理性。

2、单点登录原理

SSO的基本原理是通过共享认证状态来实现对多个系统的访问。其核心步骤包括:

  • 用户认证:用户在SSO认证中心进行登录,认证中心验证用户身份后生成一个Token。
  • Token共享:用户访问其他受信任的应用系统时,携带这个Token。应用系统通过验证Token来确认用户身份。
  • 会话管理:SSO系统管理用户会话状态,确保用户在有效期内不需要重复登录。

3、单点登录架构图

在这里插入图片描述


二、单点登录实现

在Spring Cloud环境中实现单点登录需要考虑以下几个步骤:

步骤描述
1. 建立认证中心创建一个专门的认证服务,负责用户登录和Token生成。可以使用Spring Security和OAuth2来实现这一功能。
2. 配置网关服务通过Spring Cloud Gateway或Zuul来实现请求路由和Token验证。
3. 应用服务集成将各个应用服务与认证中心集成,确保每个请求都经过Token验证。

1. 建立认证中心

认证中心负责用户认证和Token生成。可以使用Spring Security和OAuth2来实现认证中心。

OAuth2 协议介绍:

OAuth2 协议是一种授权框架,允许第三方应用在用户授权下,访问用户的资源而无需共享用户的凭据,常用于社交媒体登录等场景。

OAuth2 协议一共支持四种不同的授权模式:

  • 授权码模式:大多数第三方平台登录功能都采用这种模式,因其具有较高的安全性。
  • 简化模式:简化模式不需要第三方服务器(客户端)的参与,直接在浏览器中向授权服务器申请令牌(token)。如果网站是纯静态页面,可以采用这种方式。
  • 密码模式:密码模式要求用户将用户名和密码直接提供给客户端,客户端再使用这些信息向授权服务器申请令牌(token)。这种模式需要用户对客户端有高度的信任,例如客户端应用和服务器提供商是同一家公司。
  • 客户端模式:客户端模式是指客户端以自己的名义而非用户的名义向授权服务器申请授权。严格来说,客户端模式并不属于OAuth协议的典型解决方案,但在某些移动端授权服务器上使用这种模式对开发者来说非常方便。

最常用的是授权码模式,也是我们这里使用的模式

OAuth2 授权码模式示意图:

为了更清晰地展示授权码模式的每个环节,我们可以使用Mermaid将流程分为几个部分。以下是分成四张图分别介绍每个环节的示例代码:

  • Step 1: 用户请求资源并重定向到授权服务器

在这里插入图片描述

  • Step 2: 用户同意授权并获取授权码

在这里插入图片描述

  • Step 3: 客户端交换授权码获取访问令牌

在这里插入图片描述

  • Step 4: 客户端使用访问令牌访问资源服务器

在这里插入图片描述

① 添加OAuth2依赖

给项目添加OAuth2依赖项:

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-oauth2-client</artifactId>
</dependency>
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-oauth2-resource-server</artifactId>
</dependency>
<dependency><groupId>org.springframework.security</groupId><artifactId>spring-security-oauth2-jose</artifactId>
</dependency>
② 配置OAuth2认证服务器

创建并配置OAuth2认证服务器:

@Configuration
@EnableAuthorizationServer
public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {@Autowiredprivate AuthenticationManager authenticationManager;@Overridepublic void configure(ClientDetailsServiceConfigurer clients) throws Exception {clients.inMemory().withClient("client-id").secret("{noop}client-secret").authorizedGrantTypes("authorization_code", "refresh_token", "password").scopes("read", "write").redirectUris("http://localhost:8081/login/oauth2/code/custom");}@Overridepublic void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {endpoints.authenticationManager(authenticationManager).tokenStore(new InMemoryTokenStore());}
}
③ 配置Spring Security

创建并配置Spring Security:

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {@Overrideprotected void configure(AuthenticationManagerBuilder auth) throws Exception {auth.inMemoryAuthentication().withUser("user").password("{noop}password").roles("USER");}@Overrideprotected void configure(HttpSecurity http) throws Exception {http.authorizeRequests().anyRequest().authenticated().and().formLogin().permitAll();}@Bean@Overridepublic AuthenticationManager authenticationManagerBean() throws Exception {return super.authenticationManagerBean();}
}

2. 配置网关服务

网关服务负责路由请求和验证Token。我们使用Spring Cloud Gateway来实现。

① 添加网关服务依赖

给项目添加网关服务依赖项:

<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-oauth2-client</artifactId>
</dependency>
② 增加Gateway配置

在application.yml中添加Gateway配置:

spring:cloud:gateway:routes:- id: user-serviceuri: lb://USER-SERVICEpredicates:- Path=/user/**filters:- TokenRelaysecurity:oauth2:client:provider:custom:authorization-uri: http://localhost:8080/oauth/authorizetoken-uri: http://localhost:8080/oauth/tokenuser-info-uri: http://localhost:8080/userinfojwk-set-uri: http://localhost:8080/.well-known/jwks.jsonregistration:custom:client-id: client-idclient-secret: client-secretauthorization-grant-type: authorization_coderedirect-uri: "{baseUrl}/login/oauth2/code/{registrationId}"scope: read,write

3. 应用服务集成

每个微服务都需要配置为资源服务器,以确保每个请求都经过Token验证。

① 给每个服务添加依赖

给每个服务添加OAuth2资源服务器依赖项:

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-oauth2-resource-server</artifactId>
</dependency>
② 给每个服务添加配置

在application.yml中添加OAuth2资源服务器配置:

spring:security:oauth2:resourceserver:jwt:issuer-uri: http://localhost:8080/
③ 配置安全策略

创建并配置Spring Security以确保所有请求都经过Token验证:

@Configuration
@EnableWebSecurity
public class ResourceServerConfig extends WebSecurityConfigurerAdapter {@Overrideprotected void configure(HttpSecurity http) throws Exception {http.authorizeRequests().antMatchers("/public/**").permitAll().anyRequest().authenticated().and().oauth2ResourceServer().jwt();}
}

4、编写单点登录接口

在实现单点登录的过程中,涉及到客户端应用向认证中心请求认证并获取Token,然后将Token传递给各个微服务以进行资源访问。以下是单点登录调用代码的详细步骤,包括获取授权码、请求访问令牌以及使用令牌访问受保护资源的示例代码。

① 获取授权码

首先,客户端应用需要引导用户到SSO认证中心进行登录,并获取授权码。
可以通过浏览器重定向实现:

@GetMapping("/login")
public void login(HttpServletResponse response) throws IOException {String authorizationUri = "http://localhost:8080/oauth/authorize";String clientId = "client-id";String redirectUri = "http://localhost:8081/callback";String responseType = "code";String scope = "read write";String authUrl = authorizationUri + "?response_type=" + responseType+ "&client_id=" + clientId+ "&redirect_uri=" + URLEncoder.encode(redirectUri, "UTF-8")+ "&scope=" + URLEncoder.encode(scope, "UTF-8");response.sendRedirect(authUrl);
}
② 获取访问令牌

用户在认证中心成功登录后,认证中心会重定向回客户端应用,并附带授权码。
客户端应用需要使用这个授权码来请求访问令牌:

@GetMapping("/callback")
public String callback(@RequestParam("code") String code, Model model) {String tokenUri = "http://localhost:8080/oauth/token";String clientId = "client-id";String clientSecret = "client-secret";String redirectUri = "http://localhost:8081/callback";RestTemplate restTemplate = new RestTemplate();HttpHeaders headers = new HttpHeaders();headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);headers.setBasicAuth(clientId, clientSecret);MultiValueMap<String, String> params = new LinkedMultiValueMap<>();params.add("grant_type", "authorization_code");params.add("code", code);params.add("redirect_uri", redirectUri);HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<>(params, headers);ResponseEntity<Map> response = restTemplate.exchange(tokenUri, HttpMethod.POST, request, Map.class);Map<String, Object> responseBody = response.getBody();String accessToken = (String) responseBody.get("access_token");model.addAttribute("accessToken", accessToken);return "home";
}
③ 使用访问令牌访问受保护资源

获取访问令牌后,客户端应用可以使用这个令牌来访问受保护的资源。
以下是如何使用RestTemplate访问受保护资源的示例代码:

@GetMapping("/resource")
public String getResource(@RequestParam("accessToken") String accessToken, Model model) {String resourceUri = "http://localhost:8082/resource";RestTemplate restTemplate = new RestTemplate();HttpHeaders headers = new HttpHeaders();headers.setBearerAuth(accessToken);HttpEntity<String> request = new HttpEntity<>(headers);ResponseEntity<String> response = restTemplate.exchange(resourceUri, HttpMethod.GET, request, String.class);String resource = response.getBody();model.addAttribute("resource", resource);return "resource";
}

5、示例项目结构

示例项目结构如下:

/sso-auth-server├── src/main/java/com/example/auth│   ├── AuthorizationServerConfig.java│   ├── SecurityConfig.java│   └── Application.java└── src/main/resources└── application.yml/sso-gateway├── src/main/java/com/example/gateway│   └── Application.java└── src/main/resources└── application.yml/sso-user-service├── src/main/java/com/example/user│   ├── ResourceServerConfig.java│   └── Application.java└── src/main/resources└── application.yml/sso-client├── src/main/java/com/example/client│   ├── SsoController.java│   └── Application.java└── src/main/resources└── application.yml

这个结构包括四个主要部分:

  • 认证服务器 (sso-auth-server):负责用户认证和Token生成。
  • 网关服务 (sso-gateway):负责路由请求和Token验证。
  • 用户服务 (sso-user-service):作为资源服务器,提供受保护的资源。
  • 客户端应用 (sso-client):负责引导用户登录、获取Token并访问受保护资源。

三、单点登录总结

1、单点登录的优势

优势描述
用户体验提升用户只需一次登录即可访问所有系统,避免了重复登录的繁琐操作。
安全性增强统一的认证入口和集中式管理可以提高系统的安全性,减少各个系统独立管理认证信息的风险。
管理简化集中管理用户身份信息和认证逻辑,简化了系统的维护和管理工作。
提高生产力减少了用户在不同系统之间切换的时间,进而提升了整体工作效率。
降低开发成本开发者只需实现一次认证和授权逻辑,可以节省开发和维护多个认证系统的成本。
统一用户管理用户数据和权限集中存储和管理,使得用户信息更新和权限变更更加便捷高效。
改善审计和合规性集中的认证和授权机制有助于监控用户行为,满足法规和审计的要求。
便于集成扩展可以方便地集成新的应用系统,无需为每个新系统单独配置登录和认证流程。

2、单点登录总结

单点登录(Single Sign-On, SSO)在现代分布式系统中扮演着重要角色,它不仅提高了用户体验,还增强了系统的安全性。通过Spring Cloud实现SSO,可以充分利用Spring的生态系统和强大的功能,实现高效的身份认证和授权管理。

在实际应用中,开发者应根据具体需求和系统架构选择合适的实现方案,并不断优化以提高系统性能和安全性。以下是一些关键点:

  • 技术选型:选择适合业务需求的SSO实现方式,如基于OAuth2、JWT或CAS等。
  • 安全策略:确保数据传输和存储的安全,采用加密技术保护用户信息,防范攻击。
  • 性能优化:通过负载均衡、缓存和异步处理等技术提升系统的响应速度和稳定性。
  • 用户管理:集中管理用户身份信息,确保用户数据的一致性和准确性。
  • 日志和监控:实施全面的日志记录和监控机制,及时发现和处理潜在问题,确保系统的正常运行。
  • 容错机制:设计健壮的容错机制,确保系统在出现故障时能够快速恢复。

通过以上措施,可以有效提升单点登录系统的整体表现,满足企业的业务需求和安全要求。

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/843686.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

HCIP-Datacom-ARST自选题库__BGP多选【22道题】

1.BGP认证可以防止非法路由器与BGP路由器建立邻居&#xff0c;BGP认证可以分为MD5认证和Keychain认证&#xff0c;请问以下哪些BGP报文会携带BCGP Keychain认证信息?(报头携带) open Update Notication Keepalive 2.传统的BGP-4只能管理IPv4单播路由信息&#xff0c;MP-B…

Spring-Cloud-OpenFeign源码解析-04-调用流程分析

在Spring-Cloud-OpenFeign源码解析-03-FeignClientFactoryBean分析到&#xff0c;通过Autowired或者Resource注入FeignClient实例的时候&#xff0c;实际上返回的是JDK动态代理对象&#xff0c;具体的实现逻辑在InvocationHandler的invoke方法中 回看ReflectiveFeign.newInsta…

AI大模型日报#0528:Greg专访 | 为什么OpenAI最先做出GPT-4、xAI获60亿美元融资、李飞飞经典对话Hinton

导读&#xff1a;AI大模型日报&#xff0c;爬虫LLM自动生成&#xff0c;一文览尽每日AI大模型要点资讯&#xff01;目前采用“文心一言”&#xff08;ERNIE 4.0&#xff09;、“零一万物”&#xff08;Yi-34B&#xff09;生成了今日要点以及每条资讯的摘要。欢迎阅读&#xff0…

YOLOv8/YOLOv7/YOLOv5+CRNN-车牌识别、车牌关键点定位、车牌检测(毕业设计)

目录 一、前言1、项目介绍2、图片测试效果展示 二、项目环境配置1、pytorch安装&#xff08;gpu版本和cpu版本的安装)2、pycocotools的安装3、其他包的安装 三、yolov8/yolov7/yolov5CRNN-中文车牌识别、车牌关键点定位、车牌检测算法1、yolov8算法介绍2、CRNN算法介绍3、算法流…

【加密与解密(第四版)】第十三章笔记

第十三章 HOOK技术 13.1 Hook概述 IAT HOOK&#xff08;改地址&#xff09; BOOL IAT_InstallHook(){BOOL bResult FALSE ;HMODULE hCurExe GetModuleHandle(NULL);PULONG_PTR pt ;ULONG_PTR OrginalAddr;bResult InstallModuleIATHook(hCurExe,"user32.dll",&qu…

韩顺平0基础学Java——第13天

p264-p284 安装IDEA&#xff0c;熟悉一下软件。 尴尬了&#xff0c;难道是这个版本的idea不支持jdk17&#xff0c;难受住了 成功了&#xff0c;顺便跑一下昨天的作业&#xff1a; 这都要跑2秒&#xff1f;是电脑的问题还是谁的问题&#xff1f;控制台里跑的好快的哦 设置id…

Thingsboard规则链:Message type switch节点详解

在物联网解决方案中&#xff0c;数据的高效处理与自动化决策流程是实现智能化管理的基础。Thingsboard&#xff0c;作为一个强大的开源物联网平台&#xff0c;通过其规则引擎为用户提供了一系列灵活的节点来定制复杂的业务逻辑。其中&#xff0c;Message Type Switch节点是构建…

BookxNote Pro 宝藏 PDF 笔记软件

一、简介 1、BookxNote Pro 是一款专为电子书阅读和学习笔记设计的软件&#xff0c;支持多种电子书格式&#xff0c;如PDF和EPUB&#xff0c;能够帮助用户高效地管理和阅读电子书籍&#xff0c;同时具备强大的笔记功能&#xff0c;允许用户对书籍内容进行标注、摘录和思维导图绘…

Springboot启动时报错Property ‘mapperLocations‘ was not specified.

这几天没整boot 晚上直接运行不了了 本想是在表现层写点代码测测接口的 localhost8080找半天 结果404 先考虑好久 是不是url输入错了 然后 就发现 结果boot都不能启动了 JUnit也测不出来 找了半天 结果是开关机导致数据库没开 手动打开服务 找到MySQL启动 IDEA连接数据…

ssm/springoot养老院问诊服务预约系统_96316老年人服务系统

2.管理员&#xff1a; &#xff08;1&#xff09;登入注册页面&#xff1a;管理员进行操作时需要是已注册登入的 &#xff08;2&#xff09;权限管理&#xff1a;管理员登入后可以运用权限进行相应的操作管理。 &#xff08;3&#xff09;用户管理&#xff1a;对用户进行删除、…

国产数据库替代加速 助力数字中国建设

5月24日&#xff0c;随着第七届数字中国建设峰会在福州的成功举办&#xff0c;释放数据要素价值、发展新质生产力成为当下热议的话题。 数据作为新型生产要素&#xff0c;是数字化、网络化、智能化的重要基础。北京人大金仓信息技术股份有限公司&#xff08;以下简称人大金仓&a…

OpenHarmony实战开发——宿舍全屋智能开发指南

项目说明 基于OpenAtom OpenHarmony&#xff08;以下简称“OpenHarmony”&#xff09;、数字管家开发宿舍全屋智能&#xff0c;实现碰一碰开门、碰一碰开灯、碰一碰开风扇以及烟感检测。因为各项目开发流程大体相似&#xff0c;本文主要以碰一碰开门为例介绍如何在现有OpenHar…

西储大学数据集学习

数据集下载地址&#xff1a;CWRU凯斯西储大学轴承数据数据集——附&#xff1a;下载链接_西储大学轴承数据集下载-CSDN博客 最近研究故障诊断&#xff0c;先对使用比较多的西储大学数据集研究。以资料【1】中的内容展开研究。 1、轴承的结构 轴承分为外圈、内圈、保持架和滚珠…

CC工具箱使用指南:【Word特定文本批量替换(BHM)】

一、简介 群友定制工具。 工具所要做的是批量更新Word模板中的特定文本。 输入参数为一个Word模板和Excel更新数据。 Word模板长这样&#xff1a; Word中需要更新的文本都用大括号及里内部的标签标注出来。 对应的Excel长这样&#xff1a; 第一行的标签和Word里的一一对应…

mysql 按区间统计 3 分钟维度

根据 UNIX_TIMESTAMP 去掉分钟后的的位数 思路如下select UNIX_TIMESTAMP(now()) 当前时间 秒,now() 当前时间,FROM_UNIXTIME(FLOOR(UNIX_TIMESTAMP(CURRENT_TIMESTAMP) / (3 * 60)) * (3 * 60)) 3分钟为分隔去掉多余位数当前时间 秒 当前时间 3分钟为分隔去掉多余…

【招聘】易基因科技诚聘销售总监 虚位以待

&#x1f680; 关于我们 易基因拥有一支充满活力的科研服务团队&#xff0c;致力于以“引领表观遗传学科学研究与临床应用”为愿景&#xff0c;依托高通量测序技术和云数据分析平台&#xff0c;为医疗机构、科研机构、企事业单位等提供以表观遗传学技术为核心的多组学科研服务…

翻译《The Old New Thing》- What did MakeProcInstance do?

What did MakeProcInstance do? - The Old New Thing (microsoft.com)https://devblogs.microsoft.com/oldnewthing/20080207-00/?p23533 Raymond Chen 2008年02月07日 MakeProcInstance 做了什么&#xff1f; MakeProcInstance 宏实际上什么也不做。 #define MakeProcInst…

教师岗位等级划分标准

教师岗位等级的划分是否真的能够全面反映教师的专业能力和教学效果&#xff1f;晋升机制是否公正合理&#xff0c;能否真正激励教师持续进步&#xff1f; 教师岗位等级&#xff0c;其实就是对教师专业技能和教学经验的一种评价和激励。教师的岗位等级一般分为12个级别&#xff…

关于Profinet远程IO模块的超详细讲解

什么是Profinet远程IO模块 Profinet是新一代基于工业以太网技术的自动化总线标准&#xff0c;它为自动化通信领域提供了一个完整的网络解决方案&#xff0c;用于连接远程输入输出&#xff08;IO&#xff09;设备到Profinet网络。它可以通过以太网进行通信&#xff0c;并支持实…

I.MX6ULL主频和时钟配置实验

系列文章目录 I.MX6ULL主频和时钟配置实验 I.MX6ULL主频和时钟配置实验 系列文章目录一、前言二、I.MX6U 时钟系统详解三、硬件原理四、 7 路 PLL 时钟源五、时钟树简介六、内核时钟设置七、PFD 时钟设置八、AHB、IPG 和 PERCLK 根时钟设置九、实验程序编写十、编译下载10.1编写…