クライアント認証のサポート

クライアント資格情報

client_secret_basic を使用して認証する

HTTP Basic によるクライアント認証はすぐに使用できる状態でサポートされており、有効化するためにカスタマイズする必要はありません。デフォルトの実装は DefaultOAuth2TokenRequestHeadersConverter によって提供されます。

OAuth 2.0 クライアント登録に次の Spring Boot プロパティがあるとします。

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

次の例は、クライアント資格情報の URL エンコードを無効にするように DefaultAuthorizationCodeTokenResponseClient を構成する方法を示しています。

  • Java

  • Kotlin

DefaultOAuth2TokenRequestHeadersConverter<OAuth2AuthorizationCodeGrantRequest> headersConverter =
		new DefaultOAuth2TokenRequestHeadersConverter<>();
headersConverter.setEncodeClientCredentials(false);

OAuth2AuthorizationCodeGrantRequestEntityConverter requestEntityConverter =
		new OAuth2AuthorizationCodeGrantRequestEntityConverter();
requestEntityConverter.setHeadersConverter(headersConverter);

DefaultAuthorizationCodeTokenResponseClient tokenResponseClient =
		new DefaultAuthorizationCodeTokenResponseClient();
tokenResponseClient.setRequestEntityConverter(requestEntityConverter);
val headersConverter = DefaultOAuth2TokenRequestHeadersConverter<OAuth2AuthorizationCodeGrantRequest>()
headersConverter.setEncodeClientCredentials(false)

val requestEntityConverter = OAuth2AuthorizationCodeGrantRequestEntityConverter()
requestEntityConverter.setHeadersConverter(headersConverter)

val tokenResponseClient = DefaultAuthorizationCodeTokenResponseClient()
tokenResponseClient.setRequestEntityConverter(requestEntityConverter)

client_secret_post を使用して認証する

リクエスト本文にクライアント資格情報が含まれるクライアント認証はすぐに使用できる状態でサポートされており、これを有効にするためにカスタマイズする必要はありません。

OAuth 2.0 クライアント登録の次の Spring Boot プロパティは、構成を示しています。

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

JWT ベアラー

JWT ベアラー [IETF] (英語) クライアント認証の詳細については、OAuth 2.0 クライアント認証および認可付与の JSON Web トークン(JWT)プロファイルを参照してください。

JWT Bearer Client Authentication のデフォルトの実装は NimbusJwtClientAuthenticationParametersConverter です。これは、client_assertion パラメーターに署名付き JSON Web トークン(JWS)を追加することにより、トークンリクエストパラメーターをカスタマイズする Converter です。

JWS の署名に使用される java.security.PrivateKey または javax.crypto.SecretKey は、NimbusJwtClientAuthenticationParametersConverter に関連付けられた com.nimbusds.jose.jwk.JWK リゾルバーによって提供されます。

private_key_jwt を使用して認証する

OAuth 2.0 クライアント登録用の次の Spring Boot プロパティがあるとします。

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 を使用して認証する

OAuth 2.0 クライアント登録用の次の Spring Boot プロパティがあるとします。

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 アサーションのカスタマイズ

NimbusJwtClientAuthenticationParametersConverter によって生成された JWT には、デフォルトで isssubaudjtiiatexp クレームが含まれています。Consumer<NimbusJwtClientAuthenticationParametersConverter.JwtClientAuthenticationContext<T>> を setJwtClientAssertionCustomizer() に提供することにより、ヘッダーやクレームをカスタマイズできます。次の例は、JWT のクレームをカスタマイズする方法を示しています。

  • 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")
}

公的認証

パブリッククライアント認証はすぐに使用できる状態でサポートされており、有効にするためにカスタマイズする必要はありません。

OAuth 2.0 クライアント登録の次の Spring Boot プロパティは、構成を示しています。

spring:
  security:
    oauth2:
      client:
        registration:
          okta:
            client-id: client-id
            client-authentication-method: none
            authorization-grant-type: authorization_code
            ...
パブリッククライアントは、コード交換用の証明キー [IETF] (英語) (PKCE) を使用してサポートされます。client-authentication-method が "none" (ClientAuthenticationMethod.NONE) に設定されている場合、PKCE が自動的に使用されます。