Skip to content

Commit 0e50933

Browse files
committed
Assert unique identifiers in JdbcRegisteredClientRepository
Closes gh-959
1 parent 061badf commit 0e50933

File tree

3 files changed

+58
-2
lines changed

3 files changed

+58
-2
lines changed

oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/client/JdbcRegisteredClientRepository.java

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,8 @@ public class JdbcRegisteredClientRepository implements RegisteredClientRepositor
100100
+ " WHERE " + PK_FILTER;
101101
// @formatter:on
102102

103+
private static final String COUNT_REGISTERED_CLIENT_SQL = "SELECT COUNT(*) FROM " + TABLE_NAME + " WHERE ";
104+
103105
private final JdbcOperations jdbcOperations;
104106
private RowMapper<RegisteredClient> registeredClientRowMapper;
105107
private Function<RegisteredClient, List<SqlParameterValue>> registeredClientParametersMapper;
@@ -141,11 +143,31 @@ private void updateRegisteredClient(RegisteredClient registeredClient) {
141143
}
142144

143145
private void insertRegisteredClient(RegisteredClient registeredClient) {
146+
assertUniqueIdentifiers(registeredClient);
144147
List<SqlParameterValue> parameters = this.registeredClientParametersMapper.apply(registeredClient);
145148
PreparedStatementSetter pss = new ArgumentPreparedStatementSetter(parameters.toArray());
146149
this.jdbcOperations.update(INSERT_REGISTERED_CLIENT_SQL, pss);
147150
}
148151

152+
private void assertUniqueIdentifiers(RegisteredClient registeredClient) {
153+
Integer count = this.jdbcOperations.queryForObject(
154+
COUNT_REGISTERED_CLIENT_SQL + "client_id = ?",
155+
Integer.class,
156+
registeredClient.getClientId());
157+
if (count != null && count > 0) {
158+
throw new IllegalArgumentException("Registered client must be unique. " +
159+
"Found duplicate client identifier: " + registeredClient.getClientId());
160+
}
161+
count = this.jdbcOperations.queryForObject(
162+
COUNT_REGISTERED_CLIENT_SQL + "client_secret = ?",
163+
Integer.class,
164+
registeredClient.getClientSecret());
165+
if (count != null && count > 0) {
166+
throw new IllegalArgumentException("Registered client must be unique. " +
167+
"Found duplicate client secret for identifier: " + registeredClient.getId());
168+
}
169+
}
170+
149171
@Override
150172
public RegisteredClient findById(String id) {
151173
Assert.hasText(id, "id cannot be empty");

oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/client/JdbcRegisteredClientRepositoryTests.java

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,40 @@ public void saveWhenClientSecretNullThenSaved() {
162162
assertThat(registeredClient).isEqualTo(expectedRegisteredClient);
163163
}
164164

165+
@Test
166+
public void saveWhenExistingClientIdThenThrowIllegalArgumentException() {
167+
RegisteredClient registeredClient1 = TestRegisteredClients.registeredClient()
168+
.id("registration-1")
169+
.clientId("client-1")
170+
.build();
171+
this.registeredClientRepository.save(registeredClient1);
172+
RegisteredClient registeredClient2 = TestRegisteredClients.registeredClient()
173+
.id("registration-2")
174+
.clientId("client-1")
175+
.build();
176+
assertThatIllegalArgumentException()
177+
.isThrownBy(() -> this.registeredClientRepository.save(registeredClient2))
178+
.withMessage("Registered client must be unique. Found duplicate client identifier: " + registeredClient2.getClientId());
179+
}
180+
181+
@Test
182+
public void saveWhenExistingClientSecretThenThrowIllegalArgumentException() {
183+
RegisteredClient registeredClient1 = TestRegisteredClients.registeredClient()
184+
.id("registration-1")
185+
.clientId("client-1")
186+
.clientSecret("secret")
187+
.build();
188+
this.registeredClientRepository.save(registeredClient1);
189+
RegisteredClient registeredClient2 = TestRegisteredClients.registeredClient()
190+
.id("registration-2")
191+
.clientId("client-2")
192+
.clientSecret("secret")
193+
.build();
194+
assertThatIllegalArgumentException()
195+
.isThrownBy(() -> this.registeredClientRepository.save(registeredClient2))
196+
.withMessage("Registered client must be unique. Found duplicate client secret for identifier: " + registeredClient2.getId());
197+
}
198+
165199
@Test
166200
public void saveLoadRegisteredClientWhenCustomStrategiesSetThenCalled() throws Exception {
167201
RowMapper<RegisteredClient> registeredClientRowMapper = spy(new RegisteredClientRowMapper());

oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/client/TestRegisteredClients.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ public static RegisteredClient.Builder registeredClient() {
3131
return RegisteredClient.withId("registration-1")
3232
.clientId("client-1")
3333
.clientIdIssuedAt(Instant.now().truncatedTo(ChronoUnit.SECONDS))
34-
.clientSecret("secret")
34+
.clientSecret("secret-1")
3535
.authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE)
3636
.authorizationGrantType(AuthorizationGrantType.REFRESH_TOKEN)
3737
.clientAuthenticationMethod(ClientAuthenticationMethod.CLIENT_SECRET_BASIC)
@@ -43,7 +43,7 @@ public static RegisteredClient.Builder registeredClient2() {
4343
return RegisteredClient.withId("registration-2")
4444
.clientId("client-2")
4545
.clientIdIssuedAt(Instant.now().truncatedTo(ChronoUnit.SECONDS))
46-
.clientSecret("secret")
46+
.clientSecret("secret-2")
4747
.authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE)
4848
.authorizationGrantType(AuthorizationGrantType.REFRESH_TOKEN)
4949
.authorizationGrantType(AuthorizationGrantType.CLIENT_CREDENTIALS)

0 commit comments

Comments
 (0)