Document Jwt Client Authentication support

Closes gh-9578
This commit is contained in:
Joe Grandja 2021-05-14 22:04:28 -04:00
parent 85fb9c09a5
commit e51ca79954
4 changed files with 129 additions and 5 deletions

View File

@ -526,8 +526,8 @@ client-registration.attlist &=
## The client secret.
attribute client-secret {xsd:token}?
client-registration.attlist &=
## The method used to authenticate the client with the provider. The supported values are client_secret_basic, client_secret_post and none (public clients).
attribute client-authentication-method {"client_secret_basic" | "basic" | "client_secret_post" | "post" | "none"}?
## The method used to authenticate the client with the provider. The supported values are client_secret_basic, client_secret_post, private_key_jwt, client_secret_jwt and none (public clients).
attribute client-authentication-method {"client_secret_basic" | "basic" | "client_secret_post" | "post" | "private_key_jwt" | "client_secret_jwt" | "none"}?
client-registration.attlist &=
## The OAuth 2.0 Authorization Framework defines four Authorization Grant types. The supported values are authorization_code, client_credentials, password, implicit, as well as, extension grant type urn:ietf:params:oauth:grant-type:jwt-bearer.
attribute authorization-grant-type {"authorization_code" | "client_credentials" | "password" | "implicit" | "urn:ietf:params:oauth:grant-type:jwt-bearer"}?

View File

@ -1657,7 +1657,8 @@
<xs:attribute name="client-authentication-method">
<xs:annotation>
<xs:documentation>The method used to authenticate the client with the provider. The supported values are
client_secret_basic, client_secret_post and none (public clients).
client_secret_basic, client_secret_post, private_key_jwt, client_secret_jwt and none
(public clients).
</xs:documentation>
</xs:annotation>
<xs:simpleType>
@ -1666,6 +1667,8 @@
<xs:enumeration value="basic"/>
<xs:enumeration value="client_secret_post"/>
<xs:enumeration value="post"/>
<xs:enumeration value="private_key_jwt"/>
<xs:enumeration value="client_secret_jwt"/>
<xs:enumeration value="none"/>
</xs:restriction>
</xs:simpleType>

View File

@ -1061,7 +1061,7 @@ The client secret.
[[nsa-client-registration-client-authentication-method]]
* **client-authentication-method**
The method used to authenticate the Client with the Provider.
The supported values are *client_secret_basic*, *client_secret_post* and *none* https://tools.ietf.org/html/rfc6749#section-2.1[(public clients)].
The supported values are *client_secret_basic*, *client_secret_post*, *private_key_jwt*, *client_secret_jwt* and *none* https://tools.ietf.org/html/rfc6749#section-2.1[(public clients)].
[[nsa-client-registration-authorization-grant-type]]

View File

@ -12,6 +12,9 @@ At a high-level, the core features available are:
* https://tools.ietf.org/html/rfc6749#section-1.3.3[Resource Owner Password Credentials]
* https://datatracker.ietf.org/doc/html/rfc7523#section-2.1[JWT Bearer]
.Client Authentication support
* https://datatracker.ietf.org/doc/html/rfc7523#section-2.2[JWT Bearer]
.HTTP Client support
* <<oauth2Client-webclient-servlet, `WebClient` integration for Servlet Environments>> (for requesting protected resources)
@ -155,6 +158,8 @@ The following sections will go into more detail on the core components used by O
** <<oauth2Client-client-creds-grant, Client Credentials>>
** <<oauth2Client-password-grant, Resource Owner Password Credentials>>
** <<oauth2Client-jwt-bearer-grant, JWT Bearer>>
* <<oauth2Client-client-auth-support>>
** <<oauth2Client-jwt-bearer-auth, JWT Bearer>>
* <<oauth2Client-additional-features>>
** <<oauth2Client-registered-authorized-client, Resolving an Authorized Client>>
* <<oauth2Client-webclient-servlet>>
@ -207,7 +212,7 @@ public final class ClientRegistration {
<2> `clientId`: The client identifier.
<3> `clientSecret`: The client secret.
<4> `clientAuthenticationMethod`: The method used to authenticate the Client with the Provider.
The supported values are *client_secret_basic*, *client_secret_post* and *none* https://tools.ietf.org/html/rfc6749#section-2.1[(public clients)].
The supported values are *client_secret_basic*, *client_secret_post*, *private_key_jwt*, *client_secret_jwt* and *none* https://tools.ietf.org/html/rfc6749#section-2.1[(public clients)].
<5> `authorizationGrantType`: The OAuth 2.0 Authorization Framework defines four https://tools.ietf.org/html/rfc6749#section-1.3[Authorization Grant] types.
The supported values are `authorization_code`, `client_credentials`, `password`, as well as, extension grant type `urn:ietf:params:oauth:grant-type:jwt-bearer`.
<6> `redirectUri`: The client's registered redirect URI that the _Authorization Server_ redirects the end-user's user-agent
@ -1851,6 +1856,122 @@ class OAuth2ResourceServerController {
====
[[oauth2Client-client-auth-support]]
=== Client Authentication Support
[[oauth2Client-jwt-bearer-auth]]
==== JWT Bearer
[NOTE]
Please refer to JSON Web Token (JWT) Profile for OAuth 2.0 Client Authentication and Authorization Grants for further details on https://datatracker.ietf.org/doc/html/rfc7523#section-2.2[JWT Bearer] Client Authentication.
The default implementation for JWT Bearer Client Authentication is `NimbusJwtClientAuthenticationParametersConverter`,
which is a `Converter` that customizes the Token Request parameters by adding
a signed JSON Web Token (JWS) in the `client_assertion` parameter.
The `java.security.PrivateKey` or `javax.crypto.SecretKey` used for signing the JWS
is supplied by the `com.nimbusds.jose.jwk.JWK` resolver associated with `NimbusJwtClientAuthenticationParametersConverter`.
===== Authenticate using `private_key_jwt`
Given the following Spring Boot 2.x properties for an OAuth 2.0 Client registration:
[source,yaml]
----
spring:
security:
oauth2:
client:
registration:
okta:
client-id: okta-client-id
client-authentication-method: private_key_jwt
authorization-grant-type: authorization_code
...
----
The following example shows how to configure `DefaultAuthorizationCodeTokenResponseClient`:
====
.Java
[source,java,role="primary"]
----
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);
----
====
===== Authenticate using `client_secret_jwt`
Given the following Spring Boot 2.x properties for an OAuth 2.0 Client registration:
[source,yaml]
----
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
...
----
The following example shows how to configure `DefaultClientCredentialsTokenResponseClient`:
====
.Java
[source,java,role="primary"]
----
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);
----
====
[[oauth2Client-additional-features]]
=== Additional Features