From 02cc2e9d14879b12dc5761c25b19573ab0a5e3cd Mon Sep 17 00:00:00 2001 From: Tran Ngoc Nhan Date: Thu, 25 Jun 2026 15:42:42 +0700 Subject: [PATCH] Fix TokenType Comparison Logic Compare OAuth2AccessToken.TokenType using equals() instead of == in BearerTokenAuthentication, since TokenType instances are not guaranteed to be singletons and reference comparison can incorrectly reject an otherwise-equal bearer token. Closes gh-19377 Signed-off-by: Josh Cummings <3627351+jzheaux@users.noreply.github.com> --- .../BearerTokenAuthentication.java | 5 ++-- .../BearerTokenAuthenticationTests.java | 28 +++++++++++++++++++ 2 files changed, 31 insertions(+), 2 deletions(-) diff --git a/oauth2/oauth2-resource-server/src/main/java/org/springframework/security/oauth2/server/resource/authentication/BearerTokenAuthentication.java b/oauth2/oauth2-resource-server/src/main/java/org/springframework/security/oauth2/server/resource/authentication/BearerTokenAuthentication.java index 0da2633c7a..59c230ecf7 100644 --- a/oauth2/oauth2-resource-server/src/main/java/org/springframework/security/oauth2/server/resource/authentication/BearerTokenAuthentication.java +++ b/oauth2/oauth2-resource-server/src/main/java/org/springframework/security/oauth2/server/resource/authentication/BearerTokenAuthentication.java @@ -53,7 +53,7 @@ public class BearerTokenAuthentication extends AbstractOAuth2TokenAuthentication public BearerTokenAuthentication(OAuth2AuthenticatedPrincipal principal, OAuth2AccessToken credentials, Collection authorities) { super(credentials, principal, credentials, authorities); - Assert.isTrue(credentials.getTokenType() == OAuth2AccessToken.TokenType.BEARER, + Assert.isTrue(OAuth2AccessToken.TokenType.BEARER.equals(credentials.getTokenType()), "credentials must be a bearer token"); this.attributes = Collections.unmodifiableMap(new LinkedHashMap<>(principal.getAttributes())); setAuthenticated(true); @@ -121,7 +121,8 @@ public class BearerTokenAuthentication extends AbstractOAuth2TokenAuthentication */ @Override public B token(OAuth2AccessToken token) { - Assert.isTrue(token.getTokenType() == OAuth2AccessToken.TokenType.BEARER, "token must be a bearer token"); + Assert.isTrue(OAuth2AccessToken.TokenType.BEARER.equals(token.getTokenType()), + "token must be a bearer token"); super.credentials(token); return super.token(token); } diff --git a/oauth2/oauth2-resource-server/src/test/java/org/springframework/security/oauth2/server/resource/authentication/BearerTokenAuthenticationTests.java b/oauth2/oauth2-resource-server/src/test/java/org/springframework/security/oauth2/server/resource/authentication/BearerTokenAuthenticationTests.java index d1fef9d1f8..56a3ee90c1 100644 --- a/oauth2/oauth2-resource-server/src/test/java/org/springframework/security/oauth2/server/resource/authentication/BearerTokenAuthenticationTests.java +++ b/oauth2/oauth2-resource-server/src/test/java/org/springframework/security/oauth2/server/resource/authentication/BearerTokenAuthenticationTests.java @@ -173,4 +173,32 @@ public class BearerTokenAuthenticationTests { assertThat(authorities).containsExactlyInAnyOrder("FACTOR_ONE", "FACTOR_TWO"); } + // gh-19377 + @Test + public void compareCredentialsHasBearerTokenType() { + Instant current = Instant.now(); + Instant after1hour = Instant.now().plusSeconds(3600); + OAuth2AccessToken oAuth2AccessToken = new OAuth2AccessToken(new OAuth2AccessToken.TokenType("Bearer"), "token", + current, after1hour); + BearerTokenAuthentication authenticated = new BearerTokenAuthentication(this.principal, oAuth2AccessToken, + this.authorities); + assertThat(authenticated.getName()).isEqualTo(this.name); + assertThat(authenticated.getCredentials()) + .isEqualTo(new OAuth2AccessToken(OAuth2AccessToken.TokenType.BEARER, "token", current, after1hour)); + } + + // gh-19377 + @Test + public void toBuilderCompareCredentialsHasBearerTokenType() { + Instant current = Instant.now(); + Instant after1hour = Instant.now().plusSeconds(3600); + OAuth2AccessToken oAuth2AccessToken = new OAuth2AccessToken(new OAuth2AccessToken.TokenType("Bearer"), "token", + current, after1hour); + BearerTokenAuthentication token = new BearerTokenAuthentication(this.principal, this.token, this.authorities); + BearerTokenAuthentication authenticated = token.toBuilder().token(oAuth2AccessToken).build(); + assertThat(authenticated.getName()).isEqualTo(this.name); + assertThat(authenticated.getCredentials()) + .isEqualTo(new OAuth2AccessToken(OAuth2AccessToken.TokenType.BEARER, "token", current, after1hour)); + } + }