Skip to content

Commit 07d69cb

Browse files
liuyunshjgrandja
authored andcommitted
Validate client secret not expired
Closes gh-850
1 parent 502fa24 commit 07d69cb

File tree

2 files changed

+29
-0
lines changed

2 files changed

+29
-0
lines changed

oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/authentication/ClientSecretAuthenticationProvider.java

+7
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515
*/
1616
package org.springframework.security.oauth2.server.authorization.authentication;
1717

18+
import java.time.Instant;
19+
1820
import org.springframework.security.authentication.AuthenticationProvider;
1921
import org.springframework.security.core.Authentication;
2022
import org.springframework.security.core.AuthenticationException;
@@ -107,6 +109,11 @@ public Authentication authenticate(Authentication authentication) throws Authent
107109
throwInvalidClient(OAuth2ParameterNames.CLIENT_SECRET);
108110
}
109111

112+
if (registeredClient.getClientSecretExpiresAt() != null &&
113+
Instant.now().isAfter(registeredClient.getClientSecretExpiresAt())) {
114+
throwInvalidClient("client_secret_expires_at");
115+
}
116+
110117
// Validate the "code_verifier" parameter for the confidential client, if available
111118
this.codeVerifierAuthenticator.authenticateIfAvailable(clientAuthentication, registeredClient);
112119

oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/authentication/ClientSecretAuthenticationProviderTests.java

+22
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515
*/
1616
package org.springframework.security.oauth2.server.authorization.authentication;
1717

18+
import java.time.Instant;
19+
import java.time.temporal.ChronoUnit;
1820
import java.util.HashMap;
1921
import java.util.Map;
2022

@@ -182,6 +184,26 @@ public void authenticateWhenInvalidClientSecretThenThrowOAuth2AuthenticationExce
182184
verify(this.passwordEncoder).matches(any(), any());
183185
}
184186

187+
@Test
188+
public void authenticateWhenExpiredClientSecretThenThrowOAuth2AuthenticationException() {
189+
RegisteredClient registeredClient = TestRegisteredClients.registeredClient()
190+
.clientSecretExpiresAt(Instant.now().minus(1, ChronoUnit.HOURS).truncatedTo(ChronoUnit.SECONDS))
191+
.build();
192+
when(this.registeredClientRepository.findByClientId(eq(registeredClient.getClientId())))
193+
.thenReturn(registeredClient);
194+
195+
OAuth2ClientAuthenticationToken authentication = new OAuth2ClientAuthenticationToken(
196+
registeredClient.getClientId(), ClientAuthenticationMethod.CLIENT_SECRET_BASIC, registeredClient.getClientSecret(), null);
197+
assertThatThrownBy(() -> this.authenticationProvider.authenticate(authentication))
198+
.isInstanceOf(OAuth2AuthenticationException.class)
199+
.extracting(ex -> ((OAuth2AuthenticationException) ex).getError())
200+
.satisfies(error -> {
201+
assertThat(error.getErrorCode()).isEqualTo(OAuth2ErrorCodes.INVALID_CLIENT);
202+
assertThat(error.getDescription()).contains("client_secret_expires_at");
203+
});
204+
verify(this.passwordEncoder).matches(any(), any());
205+
}
206+
185207
@Test
186208
public void authenticateWhenValidCredentialsThenAuthenticated() {
187209
RegisteredClient registeredClient = TestRegisteredClients.registeredClient().build();

0 commit comments

Comments
 (0)