Spring Boot项目中实现OAuth2客户端模式(Client Credentials Grant Type)
背景
在项目中难免需要和外部系统进行对接,既然对接那就需要进行鉴权认证,一般外围系统的对接交互方式协议分两种:https和内网;如果是https,有些场景也需要进一步进行接口层面的鉴权认证,虽然通道已经进行了保障了
OAuth2基础知识
在学习本篇OAuth2的客户端模式认证之前,大家需要先了解OAuth2几种认证模式,分别使用场景
【OAuth2】详细讲解
OAuth2场景的认证模式:验证码和客户端
springboot整合支付宝第三方授权登录代码实现详细教程
20220419_SpringBoot-OAuth2-Gitee第三方登录
上面是博主认为比较有学习价值的学习视频,讲的比较清楚,可以深入了解验证码认证的过程
本篇主要讲客户端模式,其实客户端模式不属于OAuth2的范畴,因为没有了用户,但是有客户端id,所以也纳入了OAuth2范畴
OAuth2客户端认证
在Spring Boot项目中实现OAuth2客户端模式(Client Credentials Grant Type)对第三方接口进行认证,通常涉及以下几个步骤:
设置OAuth2服务提供商:你需要有一个支持OAuth2的服务提供商,该服务提供商能够颁发访问令牌(Access Token)。如果你自己控制服务提供商,那么你需要设置好OAuth2服务器端。
客户端应用程序配置:在客户端应用程序中配置OAuth2客户端凭证,包括客户端ID (client_id) 和客户端密钥 (client_secret)。
获取访问令牌:使用客户端凭证向OAuth2授权服务器请求访问令牌。
使用访问令牌访问资源:获取到访问令牌之后,将其添加到请求头中,用于访问受保护的资源。
客户端服务搭建
下面是一个简单的示例,展示如何在Spring Boot项目中实现OAuth2客户端模式认证,并调用受保护的资源API。
添加依赖
首先,确保你的Spring Boot项目中包含了Spring Security OAuth2相关依赖:
<!-- 在pom.xml中添加 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-oauth2-client</artifactId>
</dependency>
配置application.properties或application.yml
在application.properties或application.yml中配置OAuth2客户端信息:
# application.properties
spring.security.oauth2.client.provider.custom_oauth2.token-uri=http://your-oauth2-server.com/oauth/token
spring.security.oauth2.client.provider.custom_oauth2.authorization-uri=http://your-oauth2-server.com/oauth/authorize
spring.security.oauth2.client.provider.custom_oauth2.user-name-attribute=id
spring.security.oauth2.client.registration.custom_oauth2.client-id=your_client_id
spring.security.oauth2.client.registration.custom_oauth2.client-secret=your_client_secret
spring.security.oauth2.client.registration.custom_oauth2.scope=read,write
spring.security.oauth2.client.registration.custom_oauth2.authorization-grant-type=client_credentials
spring.security.oauth2.client.registration.custom_oauth2.redirect-uri-template=https://your-app.com/login/oauth2/code/custom_oauth2
创建OAuth2客户端配置
你可以创建一个配置类来指定OAuth2客户端的细节
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.web.server.ServerHttpSecurity;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.server.SecurityWebFilterChain;
import org.springframework.security.config.annotation.web.reactive.EnableWebFluxSecurity;
import org.springframework.security.config.annotation.web.reactive.EnableWebFluxSecurity;
import org.springframework.security.config.web.server.ServerHttpSecurity;
import org.springframework.security.web.server.SecurityWebFilterChain;
@EnableWebFluxSecurity
public class WebSecurityConfig {
@Bean
public SecurityWebFilterChain securityWebFilterChain(ServerHttpSecurity http) {
http
.authorizeExchange()
.anyExchange().authenticated()
.and()
.oauth2Login(); // 启用OAuth2登录
return http.build();
}
}
调用受保护资源
一旦获取到了访问令牌,你可以在HTTP请求头中包含Authorization字段,值为Bearer {access_token},来访问受保护的资源:
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.web.client.RestTemplate;
public class ResourceFetcher {
public void fetchResource(String accessToken) {
HttpHeaders headers = new HttpHeaders();
headers.setBearerAuth(accessToken); // 设置Bearer Token
HttpEntity<String> entity = new HttpEntity<>("body", headers);
RestTemplate restTemplate = new RestTemplate();
ResponseEntity<String> response = restTemplate.exchange(
"http://protected-resource.com/api/resource",
HttpMethod.GET,
entity,
String.class
);