Spring Security—OAuth2 客户端认证和授权

一、认证—JWT Bearer

关于 JWT Bearer 客户端认证的进一步详情,请参考OAuth 2.0客户端认证和授权许可的 JSON Web Token (JWT)简介。

JWT Bearer 客户端认证的默认实现是 NimbusJwtClientAuthenticationParametersConverter,它是一个 Converter,通过在 client_assertion 参数中添加签名的JSON Web Token(JWS)来定制令牌请求参数。

用于签署 JWS 的 java.security.PrivateKey 或 javax.crypto.SecretKey 由与 NimbusJwtClientAuthenticationParametersConverter 相关的 com.nimbusds.jose.jwk.JWK 解析器提供。

1、使用private_key_jwt进行认证

给出以下Spring Boot 2.x属性,用于OAuth 2.0客户端注册。

spring:security:oauth2:client:registration:okta:client-id: okta-client-idclient-authentication-method: private_key_jwtauthorization-grant-type: authorization_code...

下面的例子显示了如何配置 DefaultAuthorizationCodeTokenResponseClient。

  • Java
Function<ClientRegistration, JWK> jwkResolver = (clientRegistration) -> {if (clientRegistration.getClientAuthenticationMethod().equals(ClientAuthenticationMethod.PRIVATE_KEY_JWT)) {// Assuming RSA key typeRSAPublicKey publicKey = ...RSAPrivateKey privateKey = ...return new RSAKey.Builder(publicKey).privateKey(privateKey).keyID(UUID.randomUUID().toString()).build();}return null;
};OAuth2AuthorizationCodeGrantRequestEntityConverter requestEntityConverter =new OAuth2AuthorizationCodeGrantRequestEntityConverter();
requestEntityConverter.addParametersConverter(new NimbusJwtClientAuthenticationParametersConverter<>(jwkResolver));DefaultAuthorizationCodeTokenResponseClient tokenResponseClient =new DefaultAuthorizationCodeTokenResponseClient();
tokenResponseClient.setRequestEntityConverter(requestEntityConverter);

2、使用 client_secret_jwt 进行认证

给出以下Spring Boot 2.x属性,用于OAuth 2.0客户端注册。

spring:security:oauth2:client:registration:okta:client-id: okta-client-idclient-secret: okta-client-secretclient-authentication-method: client_secret_jwtauthorization-grant-type: client_credentials...

下面的例子显示了如何配置 DefaultClientCredentialsTokenResponseClient。

  • Java
Function<ClientRegistration, JWK> jwkResolver = (clientRegistration) -> {if (clientRegistration.getClientAuthenticationMethod().equals(ClientAuthenticationMethod.CLIENT_SECRET_JWT)) {SecretKeySpec secretKey = new SecretKeySpec(clientRegistration.getClientSecret().getBytes(StandardCharsets.UTF_8),"HmacSHA256");return new OctetSequenceKey.Builder(secretKey).keyID(UUID.randomUUID().toString()).build();}return null;
};OAuth2ClientCredentialsGrantRequestEntityConverter requestEntityConverter =new OAuth2ClientCredentialsGrantRequestEntityConverter();
requestEntityConverter.addParametersConverter(new NimbusJwtClientAuthenticationParametersConverter<>(jwkResolver));DefaultClientCredentialsTokenResponseClient tokenResponseClient =new DefaultClientCredentialsTokenResponseClient();
tokenResponseClient.setRequestEntityConverter(requestEntityConverter);

3、自定义JWT断言(JWT assertion)

NimbusJwtClientAuthenticationParametersConverter 产生的JWT默认包含 iss、sub、aud、jti、iat 和 exp 等 claim。你可以通过提供一个 Consumer<NimbusJwtClientAuthenticationParametersConverter.JwtClientAuthenticationContext<T>> 给 `setJwtClientAssertionCustomizer()`来定制头信息和/或claim。下面的例子显示了如何定制JWT的 claim。

  • Java
Function<ClientRegistration, JWK> jwkResolver = ...NimbusJwtClientAuthenticationParametersConverter<OAuth2ClientCredentialsGrantRequest> converter =new NimbusJwtClientAuthenticationParametersConverter<>(jwkResolver);
converter.setJwtClientAssertionCustomizer((context) -> {context.getHeaders().header("custom-header", "header-value");context.getClaims().claim("custom-claim", "claim-value");
});

二、授权—解析授权客户端

@RegisteredOAuth2AuthorizedClient 注解提供了将方法参数解析为 OAuth2AuthorizedClient 类型的参数值的能力。与使用 OAuth2AuthorizedClientManager 或 OAuth2AuthorizedClientService 来访问 OAuth2AuthorizedClient 相比,这是一个方便的选择。下面的例子展示了如何使用 @RegisteredOAuth2AuthorizedClient。

  • Java
@Controller
public class OAuth2ClientController {@GetMapping("/")public String index(@RegisteredOAuth2AuthorizedClient("okta") OAuth2AuthorizedClient authorizedClient) {OAuth2AccessToken accessToken = authorizedClient.getAccessToken();...return "index";}
}

@RegisteredOAuth2AuthorizedClient 注解由 OAuth2AuthorizedClientArgumentResolver 处理,它直接使用 OAuth2AuthorizedClientManager,因此继承其能力。

1、为Servlet环境整合WebClient

OAuth 2.0客户端支持通过使用 ExchangeFilterFunction 与 WebClient 整合。

ServletOAuth2AuthorizedClientExchangeFilterFunction 提供了一种机制,通过使用 OAuth2AuthorizedClient 并包括相关的 OAuth2AccessToken 作为承载令牌来请求受保护的资源。它直接使用 OAuth2AuthorizedClientManager,因此,它继承了以下功能。

  • 如果客户还没有得到授权,就会请求一个 OAuth2AccessToken。
    • authorization_code: 触发 Authorization 请求重定向,启动流程。
    • client_credentials: 访问令牌是直接从令牌端点获得的。
    • password: 访问令牌是直接从令牌端点获得的。
  • 如果 OAuth2AccessToken 已经过期,如果有 OAuth2AuthorizedClientProvider 可以执行授权,它将被刷新(或更新)。

下面的代码显示了一个如何配置支持OAuth 2.0客户端的 WebClient 的例子。

  • Java
@Bean
WebClient webClient(OAuth2AuthorizedClientManager authorizedClientManager) {ServletOAuth2AuthorizedClientExchangeFilterFunction oauth2Client =new ServletOAuth2AuthorizedClientExchangeFilterFunction(authorizedClientManager);return WebClient.builder().apply(oauth2Client.oauth2Configuration()).build();
}

2、提供授权客户端

ServletOAuth2AuthorizedClientExchangeFilterFunction 通过从 ClientRequest.attributes()(请求属性)中解析 OAuth2AuthorizedClient,来确定(对一个请求)要使用的客户端。

下面的代码显示了如何设置一个 OAuth2AuthorizedClient 作为请求属性。

  • Java
@GetMapping("/")
public String index(@RegisteredOAuth2AuthorizedClient("okta") OAuth2AuthorizedClient authorizedClient) {String resourceUri = ...String body = webClient.get().uri(resourceUri).attributes(oauth2AuthorizedClient(authorizedClient))   .retrieve().bodyToMono(String.class).block();...return "index";
}

oauth2AuthorizedClient() is a static method in ServletOAuth2AuthorizedClientExchangeFilterFunction.

下面的代码显示了如何设置 ClientRegistration.getRegistrationId() 作为请求属性。

  • Java
@GetMapping("/")
public String index() {String resourceUri = ...String body = webClient.get().uri(resourceUri).attributes(clientRegistrationId("okta"))   .retrieve().bodyToMono(String.class).block();...return "index";
}

clientRegistrationId() is a static method in ServletOAuth2AuthorizedClientExchangeFilterFunction.

3、默认授权客户端

如果 OAuth2AuthorizedClient 或 ClientRegistration.getRegistrationId() 都没有作为请求属性(request attribute)提供,ServletOAuth2AuthorizedClientExchangeFilterFunction 可以根据其配置决定使用默认客户端。

如果配置了 setDefaultOAuth2AuthorizedClient(true),并且用户已经通过 HttpSecurity.oauth2Login() 进行了认证,则使用与当前 OAuth2AuthenticationToken 关联的 OAuth2AccessToken。

下面的代码显示了具体的配置。

  • Java
@Bean
WebClient webClient(OAuth2AuthorizedClientManager authorizedClientManager) {ServletOAuth2AuthorizedClientExchangeFilterFunction oauth2Client =new ServletOAuth2AuthorizedClientExchangeFilterFunction(authorizedClientManager);oauth2Client.setDefaultOAuth2AuthorizedClient(true);return WebClient.builder().apply(oauth2Client.oauth2Configuration()).build();
}

对这个功能要谨慎,因为所有的HTTP请求都会收到访问令牌。

另外,如果 setDefaultClientRegistrationId("okta") 配置了一个有效的 ClientRegistration,则会使用与 OAuth2AuthorizedClient 相关的 OAuth2AccessToken。

下面的代码显示了具体的配置。

  • Java
@Bean
WebClient webClient(OAuth2AuthorizedClientManager authorizedClientManager) {ServletOAuth2AuthorizedClientExchangeFilterFunction oauth2Client =new ServletOAuth2AuthorizedClientExchangeFilterFunction(authorizedClientManager);oauth2Client.setDefaultClientRegistrationId("okta");return WebClient.builder().apply(oauth2Client.oauth2Configuration()).build();
}

对这个功能要谨慎,因为所有的HTTP请求都会收到访问令牌。

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

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

相关文章

VMware虚拟机中ubuntu网络连接不上

VMware虚拟机中ubuntu中网络连接不上 解决方案其他虚拟机网络 解决方案 1.选择VMware中编辑-虚拟网络编辑器-更改&#xff1a; 设置为你喜欢的模式&#xff0c;这里为NET模式 2.选中ubuntu虚拟机&#xff08;关机后的虚拟机&#xff09;&#xff0c;点击&#xff1a;编辑虚拟机…

GoLong的学习之路(八)语法之Map

文章目录 Map初始化方式判断某个键是否存在map的遍历对value值遍历。对key值遍历 使用delete()函数删除键值对按照指定顺序遍历map元素为map的切片值为切片类型的map 做个题吧 Map 哈希表是一种巧妙并且实用的数据结构。它是一个无序的key/value对的集合&#xff0c;其中所有的…

【十四】记一次MySQL宕机恢复过程,MySQL INNODB 损坏恢复

记一次MySQL宕机恢复过程 简介&#xff1a;一个业务数据库疏于运维管理&#xff0c;突然在今天崩溃宕机了&#xff0c;真是让人抓狂&#xff0c;上面也不知道积累了多久的数据&#xff0c;平时也没有定期做好备份&#xff0c;这下岂不是瞎了啊&#xff0c;经过不断的收集信息和…

什么是网络API以及用例

什么是API&#xff1f; API&#xff08;application programming interface&#xff0c;应用程序编程接口&#xff09;可使不同的应用程序通过一套机制和协议相互通信。同样&#xff0c;网络 API 可实现网络与应用程序、网络浏览器和数据库之间的通信。 使用表征状态传输&…

LeetCode977——有序数组的平方

LeetCode977——有序数组的平方 给你一个按 非递减顺序 排序的整数数组 nums&#xff0c;返回 每个数字的平方 组成的新数组&#xff0c;要求新数组也按 非递减顺序 排序。 输入&#xff1a;nums [-4,-1,0,3,10] 输出&#xff1a;[0,1,9,16,100] 解释&#xff1a;平方后&…

面试算法36:后缀表达式

题目 后缀表达式是一种算术表达式&#xff0c;它的操作符在操作数的后面。输入一个用字符串数组表示的后缀表达式&#xff0c;请输出该后缀表达式的计算结果。假设输入的一定是有效的后缀表达式。例如&#xff0c;后缀表达式["2", "1", "3", &q…

javaScript 使用indexOf 撸一下模糊查询

说明&#xff1a;把代码直接粘到HTML文件用浏览器打开即可体验 body的数据 <input class"keyWord" type"text" placeholder"查询关键字"><button class"searchBtn">查询</button><div><ul class"res…

【Spring Boot】Spring Boot集成RabbitMQ

一、发送和接收消息 Spring Boot提供了`spring-boot-starter-amqp`组件,只需要简单地配置即可与Spring Boot无缝集成。下面通过示例演示集成RabbitMQ实现消息的接收和发送。 步骤01 配置pom包。 创建Spring Boot项目并在pom.xml文件中添加spring-bootstarter-amqp等相关组件…

跟着NatureMetabolism学作图:R语言ggplot2转录组差异表达火山图

论文 Independent phenotypic plasticity axes define distinct obesity sub-types https://www.nature.com/articles/s42255-022-00629-2#Sec15 s42255-022-00629-2.pdf 论文中没有公开代码&#xff0c;但是所有作图数据都公开了&#xff0c;我们可以试着用论文中提供的数据…

用长tree方式做等长线

我正在「拾陆楼」和朋友们讨论有趣的话题,你⼀起来吧? 拾陆楼知识星球入口 相关文章链接: 用set_data_check的方式做等长线 前面讲过了如何用set_data_check做等长线,这里再讲一下如何用cts的方式做。 1)写一个sdc,把等长线的起点设置成clock source,用于创建create_…

项目结束需要经历的5个关键步骤

项目结束是项目管理不可或缺的一部分。这是项目的最后阶段&#xff0c;根据关键绩效指标和范围对交付成果进行测试&#xff0c;收尾&#xff0c;总结经验教训&#xff0c;完成交接&#xff0c;并签署项目。 项目结束与启动会议和一样重要。管理人员应为此留出时间&#xff0c;…

前端CodeReivew实践 | 京东云技术团队

把Code Review变成一种开发文化而不仅仅是一种制度 把Code Review 作为开发流程的必选项后&#xff0c;不代表Code Review这件事就可以执行的很好&#xff0c;因为Code Review 的执行&#xff0c;很大部分程度上依赖于审查者的认真审查&#xff0c;以及被审查者的积极配合&…

求解仿射变换矩阵

仿射变换是图形学中经常用到的方法&#xff0c;通常但是仿射变换的系数是未知的&#xff0c;需要找到变换前后的三对对应点进行求解。 from affine import Affine import numpy as np参考文献 矩阵最小二乘法求解仿射变换矩阵 def solve_affine(init_points, goal_points) -&…

位置式PID

// 单环PID参数 float Position_KP 0.0180, Position_KI 0.0013, Position_KD 0.11425; /* 位置式PID系数 */ /*************************************************************************** brief 位置式PID控制器* param 实际位置reality&#xff0c;目标位置target…

【CCF】Z字形扫描

这题的关键是将整个扫描的过程&#xff0c;拆分成很多次斜着操作数组的过程。 而且这个过程中可以建立如下规律&#xff1a; &#xff08;1&#xff09;一斜线上的元素个数与切换到下一条斜线这一操作之间建立规律。 先讨论左上部分的数组&#xff1a; 1&#xff09;当元素个…

小记java正则表达式中matcher.find() 和 matcher.matches() 的区别

matcher.find() 顾名思义&#xff0c;find为查找&#xff0c;其功能为查找字符串中是否有符合条件的字串&#xff08;包含本身&#xff09;&#xff0c;当查找到时即返回true&#xff0c;更多地与matcher.group(int i) 配合使用&#xff0c;用于从字符串中取出特定字串。 mat…

linux 装机教程(自用备忘)

文章目录 安装 pyenv 管理多版本 python 环境安装使用使用 pyenv 和 virtualenv 管理虚拟 python 环境 sshvscode 连接远程服务器tmux 美化zsh 安装 pyenv 管理多版本 python 环境 安装 &#xff08;教程参考&#xff1a;https://www.modb.pro/db/155036&#xff09; sudo a…

2023 uniapp( vue3 + TS )使用canvas生成海报并保存,taro/微信小程序也适用

有段时间没写vue了&#xff0c;有点生疏了...... 1、代码有注释&#xff0c;完整代码如下 <template><view class"page"><canvas class"canvas" v-if"isShow" :style"{width:${canvasWidth}px,height:${canvasHeight}px}&…

React之引入css的方式

一、是什么 组件式开发选择合适的css解决方案尤为重要 通常会遵循以下规则&#xff1a; 可以编写局部css&#xff0c;不会随意污染其他组件内的原生&#xff1b;可以编写动态的css&#xff0c;可以获取当前组件的一些状态&#xff0c;根据状态的变化生成不同的css样式&#…

SpringCloud-Sentinel

一、介绍 &#xff08;1&#xff09;提供界面配置配置服务限流、服务降级、服务熔断 &#xff08;2&#xff09;SentinelResource的blockHandler只处理后台配置的异常&#xff0c;运行时异常fallBack处理&#xff0c;且资源名为value时才生效&#xff0c;走兜底方法 二、安装…