Spring Authorization Server实战

Spring Authorization Server实战

Spring Authorizatin Server

Spring Authorizatin Server是一个框架,它提供了OAuth2.1和OpenID Connect 1.0规范以及其它相关规范的实现,它是基于Spring Security构建的

OAuth2.0协议介绍

OAuth是一个开放标准的授权协议,允许用户授权第三方应用访问其在某个服务提供者上的受保护资源,而无需将其实际的凭证(比如用户和密码)分享给第三方应用。

OAuth2.0协议的流程如下:
在这里插入图片描述
这个流程翻译后如下:

  1. 用户打开客户端后,客户端要求用户给与授权;
  2. 用户同意给客户端授权;
  3. 客户端使用上一步获得授权,向服务器申请令牌;
  4. 授权服务器对客户端认证后,向客户端发放令牌;
  5. 客户端使用令牌,向资源服务器申请获取资源;
  6. 资源服务器确认令牌有效后,向客户端开发资源;

授权流程案例

我们以阿里云盘使用支付宝授权登录来说明这个流程:

  1. 在阿里云盘登录界面,选择支付宝登录;
    在这里插入图片描述

  2. 接着会跳转到支付宝授权的页面,让用户给阿里云盘授权获取用户在支付宝中的信息;
    在这里插入图片描述

  3. 当用户点击同意后,会返回阿里云盘登录界面;

  4. 阿里云盘会使用获得的授权,向支付宝申请token,拿到token后,使用token去支付宝服务器获取用户信息;如果是第一次登录,会根据获取到的信息给用户创建一个阿里云盘的账号,并把支付宝上用户的信息和阿里云盘中创建的账号做一个映射,这样用户下次再登录,直接找到已有的账号登录即可;(这个步骤不需要用户做任何操作,只会在登录界面停留很短的时间,接着就跳转到阿里云盘主界面了)

OAuth2协议的应用场景

OAuth2协议的应用场景非常广泛,只要是涉及到第三方应用程序访问用户数据和资源的场景都可以使用

授权模式

OAuth2有四种授权模式,每种授权模式有不同的应用场景。四种模式如下:

  • 授权码模式:使用最为广泛的模式;比如上面的阿里云盘登录使用的就是授权码模式;
  • 密码模式(Password):密码模式是一种安全级别较低且要求资源拥有者(用户)完全信任服务器的模式。在OAuth2.1中该模式已经被废除,在第三方平台上使用密码模式是一种非常不安全的行为,假设某平台支持QQ登录,如果用户直接使用QQ账号、密码登录,则该平台就获取了用户的QQ账号、密码;

密码模式的流程如下:
在这里插入图片描述

  • 客户端模式(Client Credentials Grant):客户端模式是指客户端以自己的名义进行授权,而不经过用户授权。客户端模式是安全级别最低且要求授权服务器对客户端高度信任的模式。因为客户端向服务器请求认证授权的过程中没有用户的参与,客户端通过提供自己在授权服务器上的信息即可在授权服务器完成认证授权,而客户端获取授权后即可向服务器请求资源。这种模式一般用于对接接口,比如对接北森之类系统的接口;

客户端模式的流程如下:
在这里插入图片描述

  • 令牌刷新模式:如果令牌的有效期到了,如果让客户端重复之前的流程再去获取token,比较麻烦;OAuth2允许用户自动更新令牌。令牌刷新模式是对access_token过期的一种补办操作,OAuth2在给客户端颁发令牌的时候同时给客户端颁发了refresh_token,当access_token过期后,客户端拿refresh_token再去申请新的access_token即可

令牌刷新模式流程如下:
-

OAuth2.1协议

OAuth2.1协议主要是对OAuth2.0的改进,OAuth 2.1去掉了OAuth2.0中的密码模式、简化模式,增加了设备授权码模式,同时也对授权码模式增加了PKCE扩展。
点击查看OAuth2.1的内容

OpenID Connect 1.0协议

OpenID Connect 1.0 是 OAuth 2.0 协议之上的一个简单的身份层。其实就是客户端向认证服务器请求认证授权的时候,多返回一个 id_token,该 id_token 是一串使用 jwt 加密过的字符串。
OpenID Connect 1.0协议详细内容

OAuth实战

授权服务器

引入依赖

    <properties><java.version>17</java.version><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding><spring-boot.version>3.1.4</spring-boot.version></properties>
        <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-security</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-oauth2-authorization-server</artifactId></dependency>

相关配置


@Configuration
@EnableWebSecurity
public class SecurityConfig {/***  Spring Authorization Server 相关配置*  主要配置OAuth 2.1和OpenID Connect 1.0*/@Bean@Order(1)public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http)throws Exception {OAuth2AuthorizationServerConfiguration.applyDefaultSecurity(http);http.getConfigurer(OAuth2AuthorizationServerConfigurer.class)//开启OpenID Connect 1.0(其中oidc为OpenID Connect的缩写).oidc(Customizer.withDefaults());http//将需要认证的请求,重定向到login进行登录认证。.exceptionHandling((exceptions) -> exceptions.defaultAuthenticationEntryPointFor(new LoginUrlAuthenticationEntryPoint("/login"),new MediaTypeRequestMatcher(MediaType.TEXT_HTML)))// 使用jwt处理接收到的access token.oauth2ResourceServer((resourceServer) -> resourceServer.jwt(Customizer.withDefaults()));return http.build();}/***  Spring Security 过滤链配置(此处是纯Spring Security相关配置)*/@Bean@Order(2)public SecurityFilterChain defaultSecurityFilterChain(HttpSecurity http)throws Exception {http.authorizeHttpRequests((authorize) -> authorize//设置所有请求都需要认证,未认证的请求都被重定向到login页面进行登录.anyRequest().authenticated())// 由Spring Security过滤链中UsernamePasswordAuthenticationFilter过滤器拦截处理“login”页面提交的登录信息。.formLogin(Customizer.withDefaults());return http.build();}/*** 设置用户信息,校验用户名、密码*/@Beanpublic UserDetailsService userDetailsService() {UserDetails userDetails = User.withDefaultPasswordEncoder().username("test").password("123456").roles("USER").build();//基于内存的用户数据校验return new InMemoryUserDetailsManager(userDetails);}/*** 注册客户端信息** 查询认证服务器信息* http://127.0.0.1:9000/.well-known/openid-configuration** 获取授权码* http://localhost:9000/oauth2/authorize?response_type=code&client_id=oidc-client&scope=profile openid&redirect_uri=http://www.baidu.com**/@Beanpublic RegisteredClientRepository registeredClientRepository() {RegisteredClient oidcClient = RegisteredClient.withId(UUID.randomUUID().toString()).clientId("oidc-client")//{noop}开头,表示“secret”以明文存储.clientSecret("{noop}secret").clientAuthenticationMethod(ClientAuthenticationMethod.CLIENT_SECRET_BASIC)// 配置授权码模式,刷新令牌,客户端模式.authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE).authorizationGrantType(AuthorizationGrantType.REFRESH_TOKEN).authorizationGrantType(AuthorizationGrantType.CLIENT_CREDENTIALS)//认证回调地址,接收认证服务器回传的code,需要和客户端配置的一致.redirectUri("http://spring-oauth-client:9001/login/oauth2/code/messaging-client-oidc")//没有客户端时使用.redirectUri("http://www.baidu.com").postLogoutRedirectUri("http://127.0.0.1:8080/").clientName("web-client")//设置客户端权限范围.scope(OidcScopes.OPENID).scope(OidcScopes.PROFILE)//客户端设置用户需要确认授权.clientSettings(ClientSettings.builder().requireAuthorizationConsent(true).build()).build();//配置基于内存的客户端信息return new InMemoryRegisteredClientRepository(oidcClient);}/*** 配置 JWK,为JWT(id_token)提供加密密钥,用于加密/解密或签名/验签* JWK详细见:https://datatracker.ietf.org/doc/html/draft-ietf-jose-json-web-key-41*/@Beanpublic JWKSource<SecurityContext> jwkSource() {KeyPair keyPair = generateRsaKey();RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();RSAKey rsaKey = new RSAKey.Builder(publicKey).privateKey(privateKey).keyID(UUID.randomUUID().toString()).build();JWKSet jwkSet = new JWKSet(rsaKey);return new ImmutableJWKSet<>(jwkSet);}/***  生成RSA密钥对,给上面jwkSource() 方法的提供密钥对*/private static KeyPair generateRsaKey() {KeyPair keyPair;try {KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");keyPairGenerator.initialize(2048);keyPair = keyPairGenerator.generateKeyPair();}catch (Exception ex) {throw new IllegalStateException(ex);}return keyPair;}/*** 配置jwt解析器*/@Beanpublic JwtDecoder jwtDecoder(JWKSource<SecurityContext> jwkSource) {return OAuth2AuthorizationServerConfiguration.jwtDecoder(jwkSource);}/*** 配置授权服务器请求地址*/@Beanpublic AuthorizationServerSettings authorizationServerSettings() {//什么都不配置,则使用默认地址return AuthorizationServerSettings.builder().build();}
}

客户端

引入依赖

        <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-security</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-oauth2-client</artifactId></dependency>

yml文件配置

logging:level:org.springframework.security: tracespring:application:name: auth-clientsecurity:oauth2:client:provider:#认证服务器信息oauth-server:issuer-uri: http://spring-oauth-server:9000   #授权地址authorizationUri: ${spring.security.oauth2.client.provider.oauth-server.issuer-uri}/oauth2/authorize  #OAuth2认证服务器的授权端点地址tokenUri: ${spring.security.oauth2.client.provider.oauth-server.issuer-uri}/oauth2/token    #令牌获取地址registration:messaging-client-oidc:provider: oauth-server  #认证提供者,标识由哪个认证服务器进行认证,和上面的oauth-server进行关联client-name: web-client      #客户端名称client-id: oidc-client    #客户端id,从认证平台申请的客户端idclient-secret: secret      #客户端秘钥client-authentication-method: client_secret_basic  #客户端认证方式,除了client_secret_basic还有client_secret_post、client_secret_jwt、private_key_jwt等authorization-grant-type: authorization_code     #使用授权码模式获取令牌(token)redirect-uri: http://spring-oauth-client:9001/login/oauth2/code/messaging-client-oidc   #回调地址,接收认证服务器回传code的接口地址scope:      #OAuth2客户端的权限范围- profile  #允许客户端获取用户的个人资料信息- openid   #penid 是一个特定的 scope 值,它用于 OpenID Connect 协议中。当客户端应用请求 openid 范围时,它表明应用想要验证用户的身份

资源服务器

引入依赖

        <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-oauth2-resource-server</artifactId></dependency>

配置

@Configuration
@EnableWebSecurity
@EnableMethodSecurity(jsr250Enabled = true, securedEnabled = true)
public class ResourceServerConfig {@BeanSecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {http.authorizeHttpRequests((authorizeHttpRequests) -> authorizeHttpRequests//所有的访问都需要通过身份认证.anyRequest().authenticated()).oauth2ResourceServer((oauth2ResourceServer) -> oauth2ResourceServer.jwt(Customizer.withDefaults()));return http.build();}}

配置文件

server:port: 9002logging:level:org.springframework.security: tracespring:application:name: spring-oauth-resourcesecurity:oauth2:resource-server:jwt:issuer-uri: http://spring-oauth-server:9000

测试

直接访问资源服务器中的资源,不代码token
在这里插入图片描述
使用http://spring-oauth-client:9001/token地址,向客户端发起请求,获取token
在这里插入图片描述

携带token访问资源服务器上的资源
在这里插入图片描述

参考

  1. 理解OAuth 2.0
  2. OAuth 2.0
  3. Spring Authorization Server

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

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

相关文章

使用docker swarm搭建ruoyi集群环境

整体目标 项目背景 领导给到了我一个客户&#xff0c;客户商业模式为成本制作&#xff0c;成本核算。其中涉及到大量涉密数据&#xff0c;且与我们现有产品几乎没有兼容点&#xff08;我们是一套低代码的框架&#xff0c;客户有很多业务二开&#xff09; 测试环境给到了我6台…

大模型学习笔记 - LLM模型架构

LLM 模型架构 LLM 模型架构 1. LLM 核心模型 Transformer2. 详细配置 2.1 归一化方法2.2 归一化模块位置2.3 激活函数2.4 位置编码 2.4.1 绝对位置编码2.4.2 相对位置编码2.4.3 旋转位置编码 RoPE2.4.4 ALiBi位置编码 2.5 注意力机制 2.5.1 完整自注意力机制2.5.2 稀疏注意力机…

ChatGPT实战100例 - (20) 如何玩转影刀RPA

文章目录 ChatGPT实战100例 - (20) 如何玩转影刀RPA背景需求需求分析与流程设计一、需求收集二、流程梳理三、可行性分析流程设计(详细步骤)具体步骤的影刀RPA实现流程图总结AIGC在影刀RPA中的使用总结其他RPA步骤中可能用到AIGC的地方展望总结ChatGPT实战100例 - (20) 如何玩…

LeYOLO, New Scalable and Efficient CNN Architecture for Object Detection

LeYOLO, New Scalable and Efficient CNN Architecture for Object Detection 论文链接&#xff1a;http://arxiv.org/abs/2406.14239 代码链接&#xff1a;https://github.com/LilianHollard/LeYOLO 一、介绍 本文关注基于FLOP的高效目标检测计算的神经网络架构设计选择&am…

【Vite】快速入门及其配置

概述 Vite是前端构建工具。vite 相较于webpack,vite采用了不同的运行方式&#xff1a; 开发时&#xff0c;并不对代码打包&#xff0c;而是直接采用ESM的方式来运行项目在项目打包部署时&#xff0c;使用 rollup 对项目进行打包除了速度外&#xff0c;vite使用起来也更加方便…

驱动程序在\device\raidport1 上检测到控制器错误

&#x1f3c6;本文收录于《CSDN问答解答》专栏&#xff0c;主要记录项目实战过程中的Bug之前因后果及提供真实有效的解决方案&#xff0c;希望能够助你一臂之力&#xff0c;帮你早日登顶实现财富自由&#x1f680;&#xff1b;同时&#xff0c;欢迎大家关注&&收藏&…

全新UI自助图文打印系统小程序源码/自助云打印机前后端源码

全新UI自助图文打印系统小程序源码&#xff0c;自助云打印机前后端源码。最新的自助图文打印系统和证件照云打印小程序源码采用了PHP作为后端开发语言&#xff0c;旨在为用户提供全面的自助打印服务。 这些服务覆盖了多种文件格式&#xff0c;包括文档、图片、表格等。除此之外…

pipeline:无题

这里写自定义目录标题 复盘我是如何做的撰写评审文档O-KR-KA任务网络图与计划资源需求 && 风险项资源需求风险项 其他 讨论、评审文档撰写评审纪要、结论 反思 复盘 目前工作中的一个现状是&#xff0c;在季度开始的时候需要自己思考方向、规划工作&#xff1b;可能还需…

手机接Usb hub再连接电脑下D+D-波形

&#x1f3c6;本文收录于《CSDN问答解答》专栏&#xff0c;主要记录项目实战过程中的Bug之前因后果及提供真实有效的解决方案&#xff0c;希望能够助你一臂之力&#xff0c;帮你早日登顶实现财富自由&#x1f680;&#xff1b;同时&#xff0c;欢迎大家关注&&收藏&…

医联体信息平台建设方案PPT(54页)

文章摘要&#xff1a; 医联体信息平台现状当前医联体信息平台存在脱离医疗业务建设的倾向&#xff0c;导致信息孤岛&#xff0c;业务协同困难。 建设存在的问题主要问题包括健康档案无法动态更新和共享&#xff0c;信息系统之间信息共享和协同不足。 医联体信息平台建设方案方…

堆及堆的管理

堆的作用 堆是用来作为存储空间的 堆的创建与释放 分离的空闲空间的管理建议使用链表 在链表中指定空间大小及下一块空闲链表

2.3 大模型硬件基础:AI芯片(上篇) —— 《带你自学大语言模型》系列

本系列目录 《带你自学大语言模型》系列部分目录及计划&#xff0c;完整版目录见&#xff1a;带你自学大语言模型系列 —— 前言 第一部分 走进大语言模型&#xff08;科普向&#xff09; 第一章 走进大语言模型 1.1 从图灵机到GPT&#xff0c;人工智能经历了什么&#xff1…

Qt创建列表,通过外部按钮控制列表的选中下移、上移以及左侧图标的显现

引言 项目中需要使用列表QListWidget,但是不能直接拿来使用。需要创建一个列表,通过向上和向下的按钮来向上或者向下移动选中列表项,当当前项背选中再去点击确认按钮,会在列表项的前面出现一个图标。 实现效果 本实例实现的效果如下: 实现思路 思路一 直接采用QLis…

day5 分布式节点

文章目录 1 流程回顾2 抽象 PeerPicker3 节点选择与 HTTP 客户端4 实现主流程5 main 函数测试。6 QA 本文代码地址&#xff1a; 本文是7天用Go从零实现分布式缓存GeeCache的第五篇。 注册节点(Register Peers)&#xff0c;借助一致性哈希算法选择节点。实现 HTTP 客户端&…

CTF-Web习题:[BJDCTF2020]Mark Loves cat

题目链接&#xff1a;Mark Loves cat 解题思路 访问靶机网站后得到如下页面&#xff1a; 先浏览网页&#xff0c;发现最下面有一个"dog"字样&#xff0c;此时翻看源码并没有什么发现 那就例行进行目录扫描&#xff0c;源码泄露扫描&#xff0c;用dirsearch目录扫…

威尔史密斯太太贾达平特:友谊在迷恋浪漫的世界中很重要 坦言与威尔·史密斯20多年婚姻中犯下的错误

这位威尔史密斯的太太、著名演员兼音乐家贾达萍克特史密斯 (Jada Pinkett Smith) 因其在 Facebook Watch 系列《Red Table Talk》中的直言不讳而闻名&#xff0c;她的表达方式证明了她的诚实以及她渴望说出自己的想法。 这段揭露真相的视频讲述了她与威尔史密斯 (Will Smith) …

在LabVIEW中实现图像矫正

在LabVIEW中实现图像矫正&#xff0c;特别是将倾斜的笔记本图像&#xff08;如左图&#xff09;校正为正视图像&#xff08;如右图&#xff09;&#xff0c;通常需要以下几个步骤&#xff1a; 1. 获取图像 使用图像采集设备或加载图像文件来获取图像数据。 2. 图像预处理 对…

鸿蒙语言基础类库:【@system.storage (数据存储)】

数据存储 说明&#xff1a; 从API Version 6开始&#xff0c;该模块不再维护&#xff0c;可以使用模块[ohos.data.storage]。在API Version 9后&#xff0c;推荐使用新模块[ohos.data.preferences]。本模块首批接口从API version 3开始支持。后续版本的新增接口&#xff0c;采用…

鸿蒙OpenHarmony Native API【HiLog】

HiLog Overview Description: HiLog模块实现日志打印功能。 开发者可以通过使用这些接口实现日志相关功能&#xff0c;输出日志时可以指定日志类型、所属业务领域、日志TAG标识、日志级别等。 syscap SystemCapability.HiviewDFX.HiLog Since: 8 Summary Files File …

springboot服务如何执行sql脚本文件

当sql脚本文件包含不同数据库实例sql时&#xff0c;遍历读取sql文件再插入时&#xff0c;由于是不同的数据库实例这种方式就不行了&#xff0c;这时就需要程序直接执行sql脚本。 springboot执行sql脚本 /*** 执行sql脚本* throws SQLException*/ private void executeSqlScri…