From 65e3a5ec9b84fdda89ce0fb226b2418572cdd81c Mon Sep 17 00:00:00 2001
From: Joe Grandja <10884212+jgrandja@users.noreply.github.com>
Date: Wed, 26 Mar 2025 05:22:44 -0400
Subject: [PATCH] Add authorization server metadata for DPoP support
Issue gh-1813
Closes gh-1951
---
...ractOAuth2AuthorizationServerMetadata.java | 47 ++++++++++++++++++-
...horizationServerMetadataClaimAccessor.java | 17 ++++++-
...AuthorizationServerMetadataClaimNames.java | 14 +++++-
...ionServerMetadataHttpMessageConverter.java | 4 +-
...dcProviderConfigurationEndpointFilter.java | 18 ++++++-
...orizationServerMetadataEndpointFilter.java | 20 +++++++-
...Auth2AuthorizationServerMetadataTests.java | 42 ++++++++++++++++-
...viderConfigurationEndpointFilterTests.java | 4 +-
...tionServerMetadataEndpointFilterTests.java | 4 +-
9 files changed, 160 insertions(+), 10 deletions(-)
diff --git a/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/AbstractOAuth2AuthorizationServerMetadata.java b/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/AbstractOAuth2AuthorizationServerMetadata.java
index 4b6bec59..e1254f0c 100644
--- a/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/AbstractOAuth2AuthorizationServerMetadata.java
+++ b/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/AbstractOAuth2AuthorizationServerMetadata.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2020-2024 the original author or authors.
+ * Copyright 2020-2025 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -25,6 +25,7 @@ import java.util.List;
import java.util.Map;
import java.util.function.Consumer;
+import org.springframework.security.oauth2.jose.jws.JwsAlgorithms;
import org.springframework.security.oauth2.server.authorization.util.SpringAuthorizationServerVersion;
import org.springframework.util.Assert;
@@ -48,6 +49,9 @@ import org.springframework.util.Assert;
* @see 3.3 Mutual-TLS Client
* Certificate-Bound Access Tokens Metadata
+ * @see 5.1 OAuth 2.0 Demonstrating
+ * Proof of Possession (DPoP) Metadata
*/
public abstract class AbstractOAuth2AuthorizationServerMetadata
implements OAuth2AuthorizationServerMetadataClaimAccessor, Serializable {
@@ -379,6 +383,37 @@ public abstract class AbstractOAuth2AuthorizationServerMetadata
tlsClientCertificateBoundAccessTokens);
}
+ /**
+ * Add a {@link JwsAlgorithms JSON Web Signature (JWS) algorithm} to the
+ * collection of {@code dpop_signing_alg_values_supported} in the resulting
+ * {@link AbstractOAuth2AuthorizationServerMetadata}, OPTIONAL.
+ * @param dPoPSigningAlgorithm the {@link JwsAlgorithms JSON Web Signature (JWS)
+ * algorithm} supported for DPoP Proof JWTs
+ * @return the {@link AbstractBuilder} for further configuration
+ * @since 1.5
+ */
+ public B dPoPSigningAlgorithm(String dPoPSigningAlgorithm) {
+ addClaimToClaimList(OAuth2AuthorizationServerMetadataClaimNames.DPOP_SIGNING_ALG_VALUES_SUPPORTED,
+ dPoPSigningAlgorithm);
+ return getThis();
+ }
+
+ /**
+ * A {@code Consumer} of the {@link JwsAlgorithms JSON Web Signature (JWS)
+ * algorithms} supported for DPoP Proof JWTs allowing the ability to add, replace,
+ * or remove.
+ * @param dPoPSigningAlgorithmsConsumer a {@code Consumer} of the
+ * {@link JwsAlgorithms JSON Web Signature (JWS) algorithms} supported for DPoP
+ * Proof JWTs
+ * @return the {@link AbstractBuilder} for further configuration
+ * @since 1.5
+ */
+ public B dPoPSigningAlgorithms(Consumer> dPoPSigningAlgorithmsConsumer) {
+ acceptClaimValues(OAuth2AuthorizationServerMetadataClaimNames.DPOP_SIGNING_ALG_VALUES_SUPPORTED,
+ dPoPSigningAlgorithmsConsumer);
+ return getThis();
+ }
+
/**
* Use this claim in the resulting
* {@link AbstractOAuth2AuthorizationServerMetadata}.
@@ -506,6 +541,16 @@ public abstract class AbstractOAuth2AuthorizationServerMetadata
.get(OAuth2AuthorizationServerMetadataClaimNames.CODE_CHALLENGE_METHODS_SUPPORTED),
"codeChallengeMethods cannot be empty");
}
+ if (getClaims()
+ .get(OAuth2AuthorizationServerMetadataClaimNames.DPOP_SIGNING_ALG_VALUES_SUPPORTED) != null) {
+ Assert.isInstanceOf(List.class,
+ getClaims().get(OAuth2AuthorizationServerMetadataClaimNames.DPOP_SIGNING_ALG_VALUES_SUPPORTED),
+ "dPoPSigningAlgorithms must be of type List");
+ Assert.notEmpty(
+ (List>) getClaims()
+ .get(OAuth2AuthorizationServerMetadataClaimNames.DPOP_SIGNING_ALG_VALUES_SUPPORTED),
+ "dPoPSigningAlgorithms cannot be empty");
+ }
}
@SuppressWarnings("unchecked")
diff --git a/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/OAuth2AuthorizationServerMetadataClaimAccessor.java b/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/OAuth2AuthorizationServerMetadataClaimAccessor.java
index 54c6057c..a7ceb35e 100644
--- a/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/OAuth2AuthorizationServerMetadataClaimAccessor.java
+++ b/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/OAuth2AuthorizationServerMetadataClaimAccessor.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2020-2024 the original author or authors.
+ * Copyright 2020-2025 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,6 +19,7 @@ import java.net.URL;
import java.util.List;
import org.springframework.security.oauth2.core.ClaimAccessor;
+import org.springframework.security.oauth2.jose.jws.JwsAlgorithms;
/**
* A {@link ClaimAccessor} for the "claims" an Authorization Server describes about its
@@ -40,6 +41,9 @@ import org.springframework.security.oauth2.core.ClaimAccessor;
* @see 3.3 Mutual-TLS Client
* Certificate-Bound Access Tokens Metadata
+ * @see 5.1 OAuth 2.0 Demonstrating
+ * Proof of Possession (DPoP) Metadata
*/
public interface OAuth2AuthorizationServerMetadataClaimAccessor extends ClaimAccessor {
@@ -193,4 +197,15 @@ public interface OAuth2AuthorizationServerMetadataClaimAccessor extends ClaimAcc
OAuth2AuthorizationServerMetadataClaimNames.TLS_CLIENT_CERTIFICATE_BOUND_ACCESS_TOKENS));
}
+ /**
+ * Returns the {@link JwsAlgorithms JSON Web Signature (JWS) algorithms} supported for
+ * DPoP Proof JWTs {@code (dpop_signing_alg_values_supported)}.
+ * @return the {@link JwsAlgorithms JSON Web Signature (JWS) algorithms} supported for
+ * DPoP Proof JWTs
+ * @since 1.5
+ */
+ default List getDPoPSigningAlgorithms() {
+ return getClaimAsStringList(OAuth2AuthorizationServerMetadataClaimNames.DPOP_SIGNING_ALG_VALUES_SUPPORTED);
+ }
+
}
diff --git a/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/OAuth2AuthorizationServerMetadataClaimNames.java b/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/OAuth2AuthorizationServerMetadataClaimNames.java
index 0a410bf3..7a47498b 100644
--- a/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/OAuth2AuthorizationServerMetadataClaimNames.java
+++ b/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/OAuth2AuthorizationServerMetadataClaimNames.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2020-2024 the original author or authors.
+ * Copyright 2020-2025 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,6 +15,8 @@
*/
package org.springframework.security.oauth2.server.authorization;
+import org.springframework.security.oauth2.jose.jws.JwsAlgorithms;
+
/**
* The names of the "claims" an Authorization Server describes about its configuration,
* used in OAuth 2.0 Authorization Server Metadata and OpenID Connect Discovery 1.0.
@@ -32,6 +34,9 @@ package org.springframework.security.oauth2.server.authorization;
* @see 3.3 Mutual-TLS Client
* Certificate-Bound Access Tokens Metadata
+ * @see 5.1 OAuth 2.0 Demonstrating
+ * Proof of Possession (DPoP) Metadata
*/
public class OAuth2AuthorizationServerMetadataClaimNames {
@@ -130,6 +135,13 @@ public class OAuth2AuthorizationServerMetadataClaimNames {
*/
public static final String TLS_CLIENT_CERTIFICATE_BOUND_ACCESS_TOKENS = "tls_client_certificate_bound_access_tokens";
+ /**
+ * {@code dpop_signing_alg_values_supported} - the {@link JwsAlgorithms JSON Web
+ * Signature (JWS) algorithms} supported for DPoP Proof JWTs
+ * @since 1.5
+ */
+ public static final String DPOP_SIGNING_ALG_VALUES_SUPPORTED = "dpop_signing_alg_values_supported";
+
protected OAuth2AuthorizationServerMetadataClaimNames() {
}
diff --git a/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/http/converter/OAuth2AuthorizationServerMetadataHttpMessageConverter.java b/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/http/converter/OAuth2AuthorizationServerMetadataHttpMessageConverter.java
index a2db1d72..3339ebea 100644
--- a/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/http/converter/OAuth2AuthorizationServerMetadataHttpMessageConverter.java
+++ b/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/http/converter/OAuth2AuthorizationServerMetadataHttpMessageConverter.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2020-2024 the original author or authors.
+ * Copyright 2020-2025 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -169,6 +169,8 @@ public class OAuth2AuthorizationServerMetadataHttpMessageConverter
collectionStringConverter);
claimConverters.put(OAuth2AuthorizationServerMetadataClaimNames.CODE_CHALLENGE_METHODS_SUPPORTED,
collectionStringConverter);
+ claimConverters.put(OAuth2AuthorizationServerMetadataClaimNames.DPOP_SIGNING_ALG_VALUES_SUPPORTED,
+ collectionStringConverter);
this.claimTypeConverter = new ClaimTypeConverter(claimConverters);
}
diff --git a/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/oidc/web/OidcProviderConfigurationEndpointFilter.java b/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/oidc/web/OidcProviderConfigurationEndpointFilter.java
index 556964cf..b527396f 100644
--- a/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/oidc/web/OidcProviderConfigurationEndpointFilter.java
+++ b/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/oidc/web/OidcProviderConfigurationEndpointFilter.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2020-2024 the original author or authors.
+ * Copyright 2020-2025 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -31,6 +31,7 @@ import org.springframework.security.oauth2.core.AuthorizationGrantType;
import org.springframework.security.oauth2.core.ClientAuthenticationMethod;
import org.springframework.security.oauth2.core.endpoint.OAuth2AuthorizationResponseType;
import org.springframework.security.oauth2.core.oidc.OidcScopes;
+import org.springframework.security.oauth2.jose.jws.JwsAlgorithms;
import org.springframework.security.oauth2.jose.jws.SignatureAlgorithm;
import org.springframework.security.oauth2.server.authorization.context.AuthorizationServerContext;
import org.springframework.security.oauth2.server.authorization.context.AuthorizationServerContextHolder;
@@ -118,6 +119,7 @@ public final class OidcProviderConfigurationEndpointFilter extends OncePerReques
.tokenIntrospectionEndpointAuthenticationMethods(clientAuthenticationMethods())
.codeChallengeMethod("S256")
.tlsClientCertificateBoundAccessTokens(true)
+ .dPoPSigningAlgorithms(dPoPSigningAlgorithms())
.subjectType("public")
.idTokenSigningAlgorithm(SignatureAlgorithm.RS256.getName())
.scope(OidcScopes.OPENID);
@@ -151,6 +153,20 @@ public final class OidcProviderConfigurationEndpointFilter extends OncePerReques
};
}
+ private static Consumer> dPoPSigningAlgorithms() {
+ return (algs) -> {
+ algs.add(JwsAlgorithms.RS256);
+ algs.add(JwsAlgorithms.RS384);
+ algs.add(JwsAlgorithms.RS512);
+ algs.add(JwsAlgorithms.PS256);
+ algs.add(JwsAlgorithms.PS384);
+ algs.add(JwsAlgorithms.PS512);
+ algs.add(JwsAlgorithms.ES256);
+ algs.add(JwsAlgorithms.ES384);
+ algs.add(JwsAlgorithms.ES512);
+ };
+ }
+
private static String asUrl(String issuer, String endpoint) {
return UriComponentsBuilder.fromUriString(issuer).path(endpoint).build().toUriString();
}
diff --git a/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/web/OAuth2AuthorizationServerMetadataEndpointFilter.java b/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/web/OAuth2AuthorizationServerMetadataEndpointFilter.java
index 043b9b63..608766ae 100644
--- a/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/web/OAuth2AuthorizationServerMetadataEndpointFilter.java
+++ b/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/web/OAuth2AuthorizationServerMetadataEndpointFilter.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2020-2024 the original author or authors.
+ * Copyright 2020-2025 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -30,6 +30,7 @@ import org.springframework.http.server.ServletServerHttpResponse;
import org.springframework.security.oauth2.core.AuthorizationGrantType;
import org.springframework.security.oauth2.core.ClientAuthenticationMethod;
import org.springframework.security.oauth2.core.endpoint.OAuth2AuthorizationResponseType;
+import org.springframework.security.oauth2.jose.jws.JwsAlgorithms;
import org.springframework.security.oauth2.server.authorization.OAuth2AuthorizationServerMetadata;
import org.springframework.security.oauth2.server.authorization.context.AuthorizationServerContext;
import org.springframework.security.oauth2.server.authorization.context.AuthorizationServerContextHolder;
@@ -115,7 +116,8 @@ public final class OAuth2AuthorizationServerMetadataEndpointFilter extends OnceP
.tokenIntrospectionEndpoint(asUrl(issuer, authorizationServerSettings.getTokenIntrospectionEndpoint()))
.tokenIntrospectionEndpointAuthenticationMethods(clientAuthenticationMethods())
.codeChallengeMethod("S256")
- .tlsClientCertificateBoundAccessTokens(true);
+ .tlsClientCertificateBoundAccessTokens(true)
+ .dPoPSigningAlgorithms(dPoPSigningAlgorithms());
this.authorizationServerMetadataCustomizer.accept(authorizationServerMetadata);
@@ -146,6 +148,20 @@ public final class OAuth2AuthorizationServerMetadataEndpointFilter extends OnceP
};
}
+ private static Consumer> dPoPSigningAlgorithms() {
+ return (algs) -> {
+ algs.add(JwsAlgorithms.RS256);
+ algs.add(JwsAlgorithms.RS384);
+ algs.add(JwsAlgorithms.RS512);
+ algs.add(JwsAlgorithms.PS256);
+ algs.add(JwsAlgorithms.PS384);
+ algs.add(JwsAlgorithms.PS512);
+ algs.add(JwsAlgorithms.ES256);
+ algs.add(JwsAlgorithms.ES384);
+ algs.add(JwsAlgorithms.ES512);
+ };
+ }
+
private static String asUrl(String issuer, String endpoint) {
return UriComponentsBuilder.fromUriString(issuer).path(endpoint).toUriString();
}
diff --git a/oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/OAuth2AuthorizationServerMetadataTests.java b/oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/OAuth2AuthorizationServerMetadataTests.java
index 0a031afb..86fa599a 100644
--- a/oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/OAuth2AuthorizationServerMetadataTests.java
+++ b/oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/OAuth2AuthorizationServerMetadataTests.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2020-2024 the original author or authors.
+ * Copyright 2020-2025 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -24,6 +24,7 @@ import java.util.List;
import org.junit.jupiter.api.Test;
import org.springframework.security.oauth2.core.ClientAuthenticationMethod;
+import org.springframework.security.oauth2.jose.jws.JwsAlgorithms;
import org.springframework.security.oauth2.server.authorization.OAuth2AuthorizationServerMetadata.Builder;
import static org.assertj.core.api.Assertions.assertThat;
@@ -63,6 +64,8 @@ public class OAuth2AuthorizationServerMetadataTests {
.tokenIntrospectionEndpointAuthenticationMethod(ClientAuthenticationMethod.CLIENT_SECRET_BASIC.getValue())
.codeChallengeMethod("S256")
.tlsClientCertificateBoundAccessTokens(true)
+ .dPoPSigningAlgorithm(JwsAlgorithms.RS256)
+ .dPoPSigningAlgorithm(JwsAlgorithms.ES256)
.claim("a-claim", "a-value")
.build();
@@ -87,6 +90,8 @@ public class OAuth2AuthorizationServerMetadataTests {
.containsExactly(ClientAuthenticationMethod.CLIENT_SECRET_BASIC.getValue());
assertThat(authorizationServerMetadata.getCodeChallengeMethods()).containsExactly("S256");
assertThat(authorizationServerMetadata.isTlsClientCertificateBoundAccessTokens()).isTrue();
+ assertThat(authorizationServerMetadata.getDPoPSigningAlgorithms()).containsExactly(JwsAlgorithms.RS256,
+ JwsAlgorithms.ES256);
assertThat(authorizationServerMetadata.getClaimAsString("a-claim")).isEqualTo("a-value");
}
@@ -113,6 +118,7 @@ public class OAuth2AuthorizationServerMetadataTests {
assertThat(authorizationServerMetadata.getTokenIntrospectionEndpoint()).isNull();
assertThat(authorizationServerMetadata.getTokenIntrospectionEndpointAuthenticationMethods()).isNull();
assertThat(authorizationServerMetadata.getCodeChallengeMethods()).isNull();
+ assertThat(authorizationServerMetadata.getDPoPSigningAlgorithms()).isNull();
}
@Test
@@ -152,6 +158,7 @@ public class OAuth2AuthorizationServerMetadataTests {
.isEqualTo(url("https://example.com/oauth2/introspect"));
assertThat(authorizationServerMetadata.getTokenIntrospectionEndpointAuthenticationMethods()).isNull();
assertThat(authorizationServerMetadata.getCodeChallengeMethods()).isNull();
+ assertThat(authorizationServerMetadata.getDPoPSigningAlgorithms()).isNull();
assertThat(authorizationServerMetadata.getClaimAsString("some-claim")).isEqualTo("some-value");
}
@@ -191,6 +198,7 @@ public class OAuth2AuthorizationServerMetadataTests {
.isEqualTo(url("https://example.com/oauth2/introspect"));
assertThat(authorizationServerMetadata.getTokenIntrospectionEndpointAuthenticationMethods()).isNull();
assertThat(authorizationServerMetadata.getCodeChallengeMethods()).isNull();
+ assertThat(authorizationServerMetadata.getDPoPSigningAlgorithms()).isNull();
assertThat(authorizationServerMetadata.getClaimAsString("some-claim")).isEqualTo("some-value");
}
@@ -536,6 +544,38 @@ public class OAuth2AuthorizationServerMetadataTests {
assertThat(authorizationServerMetadata.getCodeChallengeMethods()).containsExactly("some-authentication-method");
}
+ @Test
+ public void buildWhenDPoPSigningAlgorithmsNotListThenThrowIllegalArgumentException() {
+ Builder builder = this.minimalBuilder.claims((claims) -> claims
+ .put(OAuth2AuthorizationServerMetadataClaimNames.DPOP_SIGNING_ALG_VALUES_SUPPORTED, "not-a-list"));
+
+ assertThatIllegalArgumentException().isThrownBy(builder::build)
+ .withMessageStartingWith("dPoPSigningAlgorithms must be of type List");
+ }
+
+ @Test
+ public void buildWhenDPoPSigningAlgorithmsEmptyListThenThrowIllegalArgumentException() {
+ Builder builder = this.minimalBuilder.claims(
+ (claims) -> claims.put(OAuth2AuthorizationServerMetadataClaimNames.DPOP_SIGNING_ALG_VALUES_SUPPORTED,
+ Collections.emptyList()));
+
+ assertThatIllegalArgumentException().isThrownBy(builder::build)
+ .withMessage("dPoPSigningAlgorithms cannot be empty");
+ }
+
+ @Test
+ public void buildWhenDPoPSigningAlgorithmsAddingOrRemovingThenCorrectValues() {
+ OAuth2AuthorizationServerMetadata authorizationServerMetadata = this.minimalBuilder
+ .dPoPSigningAlgorithm(JwsAlgorithms.RS256)
+ .dPoPSigningAlgorithms((algs) -> {
+ algs.clear();
+ algs.add(JwsAlgorithms.ES256);
+ })
+ .build();
+
+ assertThat(authorizationServerMetadata.getDPoPSigningAlgorithms()).containsExactly(JwsAlgorithms.ES256);
+ }
+
@Test
public void claimWhenNameNullThenThrowIllegalArgumentException() {
assertThatIllegalArgumentException()
diff --git a/oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/oidc/web/OidcProviderConfigurationEndpointFilterTests.java b/oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/oidc/web/OidcProviderConfigurationEndpointFilterTests.java
index 5532813c..80b70e30 100644
--- a/oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/oidc/web/OidcProviderConfigurationEndpointFilterTests.java
+++ b/oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/oidc/web/OidcProviderConfigurationEndpointFilterTests.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2020-2024 the original author or authors.
+ * Copyright 2020-2025 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -148,6 +148,8 @@ public class OidcProviderConfigurationEndpointFilterTests {
"\"introspection_endpoint_auth_methods_supported\":[\"client_secret_basic\",\"client_secret_post\",\"client_secret_jwt\",\"private_key_jwt\",\"tls_client_auth\",\"self_signed_tls_client_auth\"]");
assertThat(providerConfigurationResponse).contains("\"code_challenge_methods_supported\":[\"S256\"]");
assertThat(providerConfigurationResponse).contains("\"tls_client_certificate_bound_access_tokens\":true");
+ assertThat(providerConfigurationResponse).contains(
+ "\"dpop_signing_alg_values_supported\":[\"RS256\",\"RS384\",\"RS512\",\"PS256\",\"PS384\",\"PS512\",\"ES256\",\"ES384\",\"ES512\"]");
assertThat(providerConfigurationResponse).contains("\"subject_types_supported\":[\"public\"]");
assertThat(providerConfigurationResponse).contains("\"id_token_signing_alg_values_supported\":[\"RS256\"]");
assertThat(providerConfigurationResponse).contains("\"userinfo_endpoint\":\"https://example.com/userinfo\"");
diff --git a/oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/web/OAuth2AuthorizationServerMetadataEndpointFilterTests.java b/oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/web/OAuth2AuthorizationServerMetadataEndpointFilterTests.java
index 005f5859..4f9de8e1 100644
--- a/oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/web/OAuth2AuthorizationServerMetadataEndpointFilterTests.java
+++ b/oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/web/OAuth2AuthorizationServerMetadataEndpointFilterTests.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2020-2024 the original author or authors.
+ * Copyright 2020-2025 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -145,6 +145,8 @@ public class OAuth2AuthorizationServerMetadataEndpointFilterTests {
"\"introspection_endpoint_auth_methods_supported\":[\"client_secret_basic\",\"client_secret_post\",\"client_secret_jwt\",\"private_key_jwt\",\"tls_client_auth\",\"self_signed_tls_client_auth\"]");
assertThat(authorizationServerMetadataResponse).contains("\"code_challenge_methods_supported\":[\"S256\"]");
assertThat(authorizationServerMetadataResponse).contains("\"tls_client_certificate_bound_access_tokens\":true");
+ assertThat(authorizationServerMetadataResponse).contains(
+ "\"dpop_signing_alg_values_supported\":[\"RS256\",\"RS384\",\"RS512\",\"PS256\",\"PS384\",\"PS512\",\"ES256\",\"ES384\",\"ES512\"]");
}
@Test