客户端认证的支持
本站(springdoc.cn)中的内容来源于 spring.io ,原始版权归属于 spring.io。由 springdoc.cn 进行翻译,整理。可供个人学习、研究,未经许可,不得进行任何转载、商用或与之相关的行为。 商标声明:Spring 是 Pivotal Software, Inc. 在美国以及其他国家的商标。 |
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
解析器提供。
使用private_key_jwt进行认证
给出以下Spring Boot 2.x属性,用于OAuth 2.0客户端注册。
spring:
security:
oauth2:
client:
registration:
okta:
client-id: okta-client-id
client-authentication-method: private_key_jwt
authorization-grant-type: authorization_code
...
下面的例子显示了如何配置 DefaultAuthorizationCodeTokenResponseClient
。
-
Java
-
Kotlin
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;
};
OAuth2AuthorizationCodeGrantRequestEntityConverter requestEntityConverter =
new OAuth2AuthorizationCodeGrantRequestEntityConverter();
requestEntityConverter.addParametersConverter(
new NimbusJwtClientAuthenticationParametersConverter<>(jwkResolver));
DefaultAuthorizationCodeTokenResponseClient tokenResponseClient =
new DefaultAuthorizationCodeTokenResponseClient();
tokenResponseClient.setRequestEntityConverter(requestEntityConverter);
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 requestEntityConverter = OAuth2AuthorizationCodeGrantRequestEntityConverter()
requestEntityConverter.addParametersConverter(
NimbusJwtClientAuthenticationParametersConverter(jwkResolver)
)
val tokenResponseClient = DefaultAuthorizationCodeTokenResponseClient()
tokenResponseClient.setRequestEntityConverter(requestEntityConverter)
使用 client_secret_jwt 进行认证
给出以下Spring Boot 2.x属性,用于OAuth 2.0客户端注册。
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
...
下面的例子显示了如何配置 DefaultClientCredentialsTokenResponseClient
。
-
Java
-
Kotlin
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);
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 requestEntityConverter = OAuth2ClientCredentialsGrantRequestEntityConverter()
requestEntityConverter.addParametersConverter(
NimbusJwtClientAuthenticationParametersConverter(jwkResolver)
)
val tokenResponseClient = DefaultClientCredentialsTokenResponseClient()
tokenResponseClient.setRequestEntityConverter(requestEntityConverter)
自定义JWT断言(JWT assertion)
NimbusJwtClientAuthenticationParametersConverter
产生的JWT默认包含 iss
、sub
、aud
、jti
、iat
和 exp
等 claim。你可以通过提供一个 Consumer<NimbusJwtClientAuthenticationParametersConverter.JwtClientAuthenticationContext<T>>
给 `setJwtClientAssertionCustomizer()`来定制头信息和/或claim。下面的例子显示了如何定制JWT的 claim。
-
Java
-
Kotlin
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");
});
val jwkResolver = ...
val converter: NimbusJwtClientAuthenticationParametersConverter<OAuth2ClientCredentialsGrantRequest> =
NimbusJwtClientAuthenticationParametersConverter(jwkResolver)
converter.setJwtClientAssertionCustomizer { context ->
context.headers.header("custom-header", "header-value")
context.claims.claim("custom-claim", "claim-value")
}