فهرست منبع

Document Jwt Client Authentication support

Closes gh-9578
Joe Grandja 4 سال پیش
والد
کامیت
e51ca79954

+ 2 - 2
config/src/main/resources/org/springframework/security/config/spring-security-5.5.rnc

@@ -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"}?

+ 4 - 1
config/src/main/resources/org/springframework/security/config/spring-security-5.5.xsd

@@ -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>

+ 1 - 1
docs/manual/src/docs/asciidoc/_includes/servlet/appendix/namespace.adoc

@@ -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]]

+ 122 - 1
docs/manual/src/docs/asciidoc/_includes/servlet/oauth2/oauth2-client.adoc

@@ -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