# 客户端身份验证支持

## JWT 持有人

|   |有关[JWT Bearer](https://datatracker.ietf.org/doc/html/rfc7523#section-2.2)客户端身份验证的更多详细信息，请参考 JSON Web Token 配置文件中的 OAuth2.0 客户端身份验证和授权授予。|
|---|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|

JWT 承载客户端身份验证的默认实现是`NimbusJwtClientAuthenticationParametersConverter`，这是一个`Converter`，它通过在`client_assertion`参数中添加签名的 JSON Web 令牌来定制令牌请求参数。

用于对 JWS 进行签名的`java.security.PrivateKey`或`javax.crypto.SecretKey`由与`NimbusJwtClientAuthenticationParametersConverter`关联的`com.nimbusds.jose.jwk.JWK`解析器提供。

### 使用`private_key_jwt`进行身份验证

给出了 OAuth2.0 客户端注册的以下 Spring Boot2.x 属性：

```
spring:
  security:
    oauth2:
      client:
        registration:
          okta:
            client-id: okta-client-id
            client-authentication-method: private_key_jwt
            authorization-grant-type: authorization_code
            ...
```

下面的示例展示了如何配置`WebClientReactiveAuthorizationCodeTokenResponseClient`:

爪哇

```
Function<ClientRegistration, JWK> jwkResolver = (clientRegistration) -> {
	if (clientRegistration.getClientAuthenticationMethod().equals(ClientAuthenticationMethod.PRIVATE_KEY_JWT)) {
		// Assuming RSA key type
		RSAPublicKey publicKey = ...
		RSAPrivateKey privateKey = ...
		return new RSAKey.Builder(publicKey)
				.privateKey(privateKey)
				.keyID(UUID.randomUUID().toString())
				.build();
	}
	return null;
};

WebClientReactiveAuthorizationCodeTokenResponseClient tokenResponseClient =
		new WebClientReactiveAuthorizationCodeTokenResponseClient();
tokenResponseClient.addParametersConverter(
		new NimbusJwtClientAuthenticationParametersConverter<>(jwkResolver));
```

Kotlin

```
val jwkResolver: Function<ClientRegistration, JWK> =
    Function<ClientRegistration, JWK> { clientRegistration ->
        if (clientRegistration.clientAuthenticationMethod.equals(ClientAuthenticationMethod.PRIVATE_KEY_JWT)) {
            // Assuming RSA key type
            var publicKey: RSAPublicKey = ...
            var privateKey: RSAPrivateKey = ...
            RSAKey.Builder(publicKey)
                    .privateKey(privateKey)
                    .keyID(UUID.randomUUID().toString())
                .build()
        }
        null
    }

val tokenResponseClient = WebClientReactiveAuthorizationCodeTokenResponseClient()
tokenResponseClient.addParametersConverter(
    NimbusJwtClientAuthenticationParametersConverter(jwkResolver)
)
```

### 使用`client_secret_jwt`进行身份验证

给出了 OAuth2.0 客户端注册的以下 Spring Boot2.x 属性：

```
spring:
  security:
    oauth2:
      client:
        registration:
          okta:
            client-id: okta-client-id
            client-secret: okta-client-secret
            client-authentication-method: client_secret_jwt
            authorization-grant-type: client_credentials
            ...
```

下面的示例展示了如何配置`WebClientReactiveClientCredentialsTokenResponseClient`:

爪哇

```
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;
};

WebClientReactiveClientCredentialsTokenResponseClient tokenResponseClient =
		new WebClientReactiveClientCredentialsTokenResponseClient();
tokenResponseClient.addParametersConverter(
		new NimbusJwtClientAuthenticationParametersConverter<>(jwkResolver));
```

Kotlin

```
val jwkResolver = Function<ClientRegistration, JWK?> { clientRegistration: ClientRegistration ->
    if (clientRegistration.clientAuthenticationMethod == ClientAuthenticationMethod.CLIENT_SECRET_JWT) {
        val secretKey = SecretKeySpec(
            clientRegistration.clientSecret.toByteArray(StandardCharsets.UTF_8),
            "HmacSHA256"
        )
        OctetSequenceKey.Builder(secretKey)
            .keyID(UUID.randomUUID().toString())
            .build()
    }
    null
}

val tokenResponseClient = WebClientReactiveClientCredentialsTokenResponseClient()
tokenResponseClient.addParametersConverter(
    NimbusJwtClientAuthenticationParametersConverter(jwkResolver)
)
```

[OAuth2 授权授予](authorization-grants.html)[OAuth2 授权客户](authorized-clients.html)