You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何基于新版Spring Authorization Server实现OAuth2 private_key_jwt授权(JWS、JWT Bearer)及相关实现示例咨询

嘿,我来帮你梳理下如何基于新版Spring Authorization Server实现private_key_jwt授权,同时给你一些可落地的示例参考~

基于新版Spring Authorization Server实现OAuth2 private_key_jwt授权指南

一、基础依赖准备

首先确保你的项目引入了最新版的Spring Authorization Server依赖:

Maven 依赖

<dependency>
    <groupId>org.springframework.security</groupId>
    <artifactId>spring-security-oauth2-authorization-server</artifactId>
    <version>1.2.3</version> <!-- 请使用最新稳定版本 -->
</dependency>

Gradle 依赖

implementation 'org.springframework.security:spring-security-oauth2-authorization-server:1.2.3'

另外,客户端生成签名JWT需要用到Nimbus JOSE + JWT库,也需要引入:

<!-- Maven -->
<dependency>
    <groupId>com.nimbusds</groupId>
    <artifactId>nimbus-jose-jwt</artifactId>
    <version>9.37.3</version>
</dependency>

二、授权服务器配置

1. 注册支持private_key_jwt的客户端

创建RegisteredClient Bean,指定客户端的认证方式为PRIVATE_KEY_JWT,并配置客户端的JWKS端点(授权服务器会从这里获取公钥来验证JWT签名):

@Bean
public RegisteredClientRepository registeredClientRepository() {
    RegisteredClient privateKeyJwtClient = RegisteredClient.withId(UUID.randomUUID().toString())
            .clientId("private-key-jwt-demo-client")
            // 指定认证方式为private_key_jwt
            .clientAuthenticationMethod(ClientAuthenticationMethod.PRIVATE_KEY_JWT)
            // 根据业务需求选择授权类型,比如客户端凭证模式
            .authorizationGrantType(AuthorizationGrantType.CLIENT_CREDENTIALS)
            .scope("demo-api:read")
            // 客户端的JWKS端点,授权服务器会通过这里获取公钥验证签名
            .jwkSetUri("http://localhost:8081/.well-known/jwks.json")
            .build();

    return new InMemoryRegisteredClientRepository(privateKeyJwtClient);
}

2. 授权服务器基础配置

配置AuthorizationServerSettings Bean,保持默认即可,它会启用JWT Bearer相关的认证逻辑:

@Bean
public AuthorizationServerSettings authorizationServerSettings() {
    return AuthorizationServerSettings.builder().build();
}

三、客户端生成签名JWT(private_key_jwt凭证)

客户端需要生成一个用自身私钥签名的JWT作为认证凭证,下面是示例代码:

import com.nimbusds.jose.JWSAlgorithm;
import com.nimbusds.jose.JWSHeader;
import com.nimbusds.jose.JWSSigner;
import com.nimbusds.jose.crypto.RSASSASigner;
import com.nimbusds.jwt.JWTClaimsSet;
import com.nimbusds.jwt.SignedJWT;

import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.interfaces.RSAPrivateKey;
import java.util.Date;
import java.util.UUID;

public class PrivateKeyJwtGenerator {
    public static String generateClientAssertion(String clientId, String tokenEndpoint) throws Exception {
        // 生产环境请使用存储的私钥,这里仅为示例生成临时RSA密钥对
        KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
        keyPairGenerator.initialize(2048);
        KeyPair keyPair = keyPairGenerator.generateKeyPair();
        RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();

        // 构建JWS头部,指定签名算法为RS256
        JWSHeader header = new JWSHeader.Builder(JWSAlgorithm.RS256)
                .keyID("client-demo-key-1") // 需要和JWKS中的kid一致
                .build();

        // 构建JWT声明
        JWTClaimsSet claimsSet = new JWTClaimsSet.Builder()
                .subject(clientId) // 主体为客户端ID
                .issuer(clientId) // 签发者为客户端ID
                .audience(tokenEndpoint) // 受众为授权服务器的token端点
                .expirationTime(new Date(System.currentTimeMillis() + 3600 * 1000)) // 1小时过期
                .issueTime(new Date())
                .jwtID(UUID.randomUUID().toString()) // 唯一标识
                .build();

        // 签名生成JWT
        SignedJWT signedJWT = new SignedJWT(header, claimsSet);
        JWSSigner signer = new RSASSASigner(privateKey);
        signedJWT.sign(signer);

        return signedJWT.serialize();
    }
}

四、测试private_key_jwt授权流程

用curl发送请求到授权服务器的token端点,携带生成的客户端JWT:

curl --location --request POST 'http://localhost:8080/oauth2/token' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'grant_type=client_credentials' \
--data-urlencode 'client_assertion_type=urn:ietf:params:oauth:client-assertion-type:jwt-bearer' \
--data-urlencode 'client_assertion=<替换为你生成的JWT字符串>' \
--data-urlencode 'scope=demo-api:read'

如果配置正确,你会收到包含access_token的响应。

五、官方示例参考

虽然官方文档暂时没有详细的private_key_jwt实现说明,但Spring Authorization Server的官方代码仓库中包含了专门的private_key_jwt示例模块,涵盖了完整的客户端注册、JWKS服务搭建以及端到端的流程测试,你可以直接参考这个示例来完善自己的实现。

内容的提问来源于stack exchange,提问作者Wojciech Marusarz

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.28 21:47:45