当前位置: 首页 > article >正文

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
        );

http://www.kler.cn/news/302771.html

相关文章:

  • 计算机毕业设计选题推荐-土地承包管理系统-Java/Python项目实战(亮点:数据可视化分析、账号锁定、智能推荐)
  • oracel数据库中如果一个表在插入数据会影响另外一个表的查询?
  • 借助Aapose.Cells 在 C# 中将 TXT 转换为 JSON
  • R134a制冷剂简介
  • [ESP32]:如何在micropython中添加C库
  • ESP32 UDP 05
  • 计算机网络基本概述
  • 单考一个OCP认证?还是OCP和OCM认证都要考?
  • 基于深度学习的气象图像分类【mobilenet+VGG16+swin_transfomer+PyQt5界面】
  • Docker进入正在运行的容器的命令
  • 大数据Flink(一百一十七):Flink SQL的窗口操作
  • 爆改YOLOv8|使用MobileViTv1替换Backbone
  • 9.13信锐面经
  • 【北京迅为】《STM32MP157开发板使用手册》-第十八章 Debian文件系统
  • JavaScript使用地理位置 API
  • k8s--资源管理
  • js几个常用数组处理函数(或数组对象处理函数)的使用方法
  • 内存分配形式介绍,你知道哪些?
  • proteus+51单片机+AD/DA学习5
  • 性能测试有哪些典型问题?怎样去定位具体原因?
  • numpy03:numpy广播机制,花式索引取值,统计方法,数组的拆分与合并,线性代数方法
  • C++ 左值与右值浅谈
  • 每天一道面试题(9):lock 和 synchronized 区别
  • C# WPF中实现图表生成的五种方式
  • 【SpringCloud】微服务架构演进与Spring Cloud简介
  • 基于spring的博客系统(二)
  • Go Playground 在线编程环境
  • 优购电商小程序的设计与实现+ssm(lw+演示+源码+运行)
  • MySql8.x---开窗函数
  • HTTP 协议介绍