Skip to content

Commit 3455249

Browse files
committed
Set PasswordEncoder in RegisteredClientParameters mapper and hash the client secret before saving it
Closes gh-378
1 parent 41f8c9c commit 3455249

File tree

9 files changed

+95
-18
lines changed

9 files changed

+95
-18
lines changed

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

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@
3636
import org.springframework.jdbc.core.PreparedStatementSetter;
3737
import org.springframework.jdbc.core.RowMapper;
3838
import org.springframework.jdbc.core.SqlParameterValue;
39+
import org.springframework.security.crypto.factory.PasswordEncoderFactories;
40+
import org.springframework.security.crypto.password.PasswordEncoder;
3941
import org.springframework.security.jackson2.SecurityJackson2Modules;
4042
import org.springframework.security.oauth2.core.AuthorizationGrantType;
4143
import org.springframework.security.oauth2.core.ClientAuthenticationMethod;
@@ -291,6 +293,7 @@ private static ClientAuthenticationMethod resolveClientAuthenticationMethod(Stri
291293
*/
292294
public static class RegisteredClientParametersMapper implements Function<RegisteredClient, List<SqlParameterValue>> {
293295
private ObjectMapper objectMapper = new ObjectMapper();
296+
private PasswordEncoder passwordEncoder = PasswordEncoderFactories.createDelegatingPasswordEncoder();
294297

295298
public RegisteredClientParametersMapper() {
296299
ClassLoader classLoader = JdbcRegisteredClientRepository.class.getClassLoader();
@@ -319,7 +322,7 @@ public List<SqlParameterValue> apply(RegisteredClient registeredClient) {
319322
new SqlParameterValue(Types.VARCHAR, registeredClient.getId()),
320323
new SqlParameterValue(Types.VARCHAR, registeredClient.getClientId()),
321324
new SqlParameterValue(Types.TIMESTAMP, clientIdIssuedAt),
322-
new SqlParameterValue(Types.VARCHAR, registeredClient.getClientSecret()),
325+
new SqlParameterValue(Types.VARCHAR, encode(registeredClient.getClientSecret())),
323326
new SqlParameterValue(Types.TIMESTAMP, clientSecretExpiresAt),
324327
new SqlParameterValue(Types.VARCHAR, registeredClient.getClientName()),
325328
new SqlParameterValue(Types.VARCHAR, StringUtils.collectionToCommaDelimitedString(clientAuthenticationMethods)),
@@ -335,6 +338,12 @@ public final void setObjectMapper(ObjectMapper objectMapper) {
335338
this.objectMapper = objectMapper;
336339
}
337340

341+
342+
public final void setPasswordEncoder(PasswordEncoder passwordEncoder) {
343+
Assert.notNull(passwordEncoder, "passwordEncoder cannot be null");
344+
this.passwordEncoder = passwordEncoder;
345+
}
346+
338347
protected final ObjectMapper getObjectMapper() {
339348
return this.objectMapper;
340349
}
@@ -347,6 +356,13 @@ private String writeMap(Map<String, Object> data) {
347356
}
348357
}
349358

359+
private String encode(String value) {
360+
if (value != null) {
361+
return this.passwordEncoder.encode(value);
362+
}
363+
return null;
364+
}
365+
350366
}
351367

352368
}

oauth2-authorization-server/src/test/java/org/springframework/security/config/annotation/web/configurers/oauth2/server/authorization/OAuth2AuthorizationCodeGrantTests.java

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@
8383
import org.springframework.security.oauth2.server.authorization.TestOAuth2Authorizations;
8484
import org.springframework.security.oauth2.server.authorization.authentication.OAuth2AuthorizationCodeRequestAuthenticationToken;
8585
import org.springframework.security.oauth2.server.authorization.client.JdbcRegisteredClientRepository;
86+
import org.springframework.security.oauth2.server.authorization.client.JdbcRegisteredClientRepository.RegisteredClientParametersMapper;
8687
import org.springframework.security.oauth2.server.authorization.client.RegisteredClient;
8788
import org.springframework.security.oauth2.server.authorization.client.RegisteredClientRepository;
8889
import org.springframework.security.oauth2.server.authorization.client.TestRegisteredClients;
@@ -582,8 +583,12 @@ OAuth2AuthorizationConsentService authorizationConsentService(JdbcOperations jdb
582583
}
583584

584585
@Bean
585-
RegisteredClientRepository registeredClientRepository(JdbcOperations jdbcOperations) {
586-
return new JdbcRegisteredClientRepository(jdbcOperations);
586+
RegisteredClientRepository registeredClientRepository(JdbcOperations jdbcOperations, PasswordEncoder passwordEncoder) {
587+
JdbcRegisteredClientRepository jdbcRegisteredClientRepository = new JdbcRegisteredClientRepository(jdbcOperations);
588+
RegisteredClientParametersMapper registeredClientParametersMapper = new RegisteredClientParametersMapper();
589+
registeredClientParametersMapper.setPasswordEncoder(passwordEncoder);
590+
jdbcRegisteredClientRepository.setRegisteredClientParametersMapper(registeredClientParametersMapper);
591+
return jdbcRegisteredClientRepository;
587592
}
588593

589594
@Bean

oauth2-authorization-server/src/test/java/org/springframework/security/config/annotation/web/configurers/oauth2/server/authorization/OAuth2ClientCredentialsGrantTests.java

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@
6767
import org.springframework.security.oauth2.server.authorization.authentication.OAuth2ClientAuthenticationToken;
6868
import org.springframework.security.oauth2.server.authorization.authentication.OAuth2ClientCredentialsAuthenticationToken;
6969
import org.springframework.security.oauth2.server.authorization.client.JdbcRegisteredClientRepository;
70+
import org.springframework.security.oauth2.server.authorization.client.JdbcRegisteredClientRepository.RegisteredClientParametersMapper;
7071
import org.springframework.security.oauth2.server.authorization.client.RegisteredClient;
7172
import org.springframework.security.oauth2.server.authorization.client.RegisteredClientRepository;
7273
import org.springframework.security.oauth2.server.authorization.client.TestRegisteredClients;
@@ -279,8 +280,12 @@ OAuth2AuthorizationService authorizationService(JdbcOperations jdbcOperations, R
279280
}
280281

281282
@Bean
282-
RegisteredClientRepository registeredClientRepository(JdbcOperations jdbcOperations) {
283-
return new JdbcRegisteredClientRepository(jdbcOperations);
283+
RegisteredClientRepository registeredClientRepository(JdbcOperations jdbcOperations, PasswordEncoder passwordEncoder) {
284+
JdbcRegisteredClientRepository jdbcRegisteredClientRepository = new JdbcRegisteredClientRepository(jdbcOperations);
285+
RegisteredClientParametersMapper registeredClientParametersMapper = new RegisteredClientParametersMapper();
286+
registeredClientParametersMapper.setPasswordEncoder(passwordEncoder);
287+
jdbcRegisteredClientRepository.setRegisteredClientParametersMapper(registeredClientParametersMapper);
288+
return jdbcRegisteredClientRepository;
284289
}
285290

286291
@Bean

oauth2-authorization-server/src/test/java/org/springframework/security/config/annotation/web/configurers/oauth2/server/authorization/OAuth2RefreshTokenGrantTests.java

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@
6868
import org.springframework.security.oauth2.server.authorization.OAuth2TokenCustomizer;
6969
import org.springframework.security.oauth2.server.authorization.TestOAuth2Authorizations;
7070
import org.springframework.security.oauth2.server.authorization.client.JdbcRegisteredClientRepository;
71+
import org.springframework.security.oauth2.server.authorization.client.JdbcRegisteredClientRepository.RegisteredClientParametersMapper;
7172
import org.springframework.security.oauth2.server.authorization.client.RegisteredClient;
7273
import org.springframework.security.oauth2.server.authorization.client.RegisteredClientRepository;
7374
import org.springframework.security.oauth2.server.authorization.client.TestRegisteredClients;
@@ -207,8 +208,12 @@ OAuth2AuthorizationService authorizationService(JdbcOperations jdbcOperations, R
207208
}
208209

209210
@Bean
210-
RegisteredClientRepository registeredClientRepository(JdbcOperations jdbcOperations) {
211-
return new JdbcRegisteredClientRepository(jdbcOperations);
211+
RegisteredClientRepository registeredClientRepository(JdbcOperations jdbcOperations, PasswordEncoder passwordEncoder) {
212+
JdbcRegisteredClientRepository jdbcRegisteredClientRepository = new JdbcRegisteredClientRepository(jdbcOperations);
213+
RegisteredClientParametersMapper registeredClientParametersMapper = new RegisteredClientParametersMapper();
214+
registeredClientParametersMapper.setPasswordEncoder(passwordEncoder);
215+
jdbcRegisteredClientRepository.setRegisteredClientParametersMapper(registeredClientParametersMapper);
216+
return jdbcRegisteredClientRepository;
212217
}
213218

214219
@Bean

oauth2-authorization-server/src/test/java/org/springframework/security/config/annotation/web/configurers/oauth2/server/authorization/OAuth2TokenIntrospectionTests.java

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@
6262
import org.springframework.security.oauth2.server.authorization.OAuth2AuthorizationService;
6363
import org.springframework.security.oauth2.server.authorization.TestOAuth2Authorizations;
6464
import org.springframework.security.oauth2.server.authorization.client.JdbcRegisteredClientRepository;
65+
import org.springframework.security.oauth2.server.authorization.client.JdbcRegisteredClientRepository.RegisteredClientParametersMapper;
6566
import org.springframework.security.oauth2.server.authorization.client.RegisteredClient;
6667
import org.springframework.security.oauth2.server.authorization.client.RegisteredClientRepository;
6768
import org.springframework.security.oauth2.server.authorization.client.TestRegisteredClients;
@@ -244,8 +245,12 @@ OAuth2AuthorizationService authorizationService(JdbcOperations jdbcOperations, R
244245
}
245246

246247
@Bean
247-
RegisteredClientRepository registeredClientRepository(JdbcOperations jdbcOperations) {
248-
return new JdbcRegisteredClientRepository(jdbcOperations);
248+
RegisteredClientRepository registeredClientRepository(JdbcOperations jdbcOperations, PasswordEncoder passwordEncoder) {
249+
JdbcRegisteredClientRepository jdbcRegisteredClientRepository = new JdbcRegisteredClientRepository(jdbcOperations);
250+
RegisteredClientParametersMapper registeredClientParametersMapper = new RegisteredClientParametersMapper();
251+
registeredClientParametersMapper.setPasswordEncoder(passwordEncoder);
252+
jdbcRegisteredClientRepository.setRegisteredClientParametersMapper(registeredClientParametersMapper);
253+
return jdbcRegisteredClientRepository;
249254
}
250255

251256
@Bean

oauth2-authorization-server/src/test/java/org/springframework/security/config/annotation/web/configurers/oauth2/server/authorization/OAuth2TokenRevocationTests.java

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@
5454
import org.springframework.security.oauth2.server.authorization.OAuth2AuthorizationService;
5555
import org.springframework.security.oauth2.server.authorization.TestOAuth2Authorizations;
5656
import org.springframework.security.oauth2.server.authorization.client.JdbcRegisteredClientRepository;
57+
import org.springframework.security.oauth2.server.authorization.client.JdbcRegisteredClientRepository.RegisteredClientParametersMapper;
5758
import org.springframework.security.oauth2.server.authorization.client.RegisteredClient;
5859
import org.springframework.security.oauth2.server.authorization.client.RegisteredClientRepository;
5960
import org.springframework.security.oauth2.server.authorization.client.TestRegisteredClients;
@@ -207,8 +208,12 @@ OAuth2AuthorizationService authorizationService(JdbcOperations jdbcOperations, R
207208
}
208209

209210
@Bean
210-
RegisteredClientRepository registeredClientRepository(JdbcOperations jdbcOperations) {
211-
return new JdbcRegisteredClientRepository(jdbcOperations);
211+
RegisteredClientRepository registeredClientRepository(JdbcOperations jdbcOperations, PasswordEncoder passwordEncoder) {
212+
JdbcRegisteredClientRepository jdbcRegisteredClientRepository = new JdbcRegisteredClientRepository(jdbcOperations);
213+
RegisteredClientParametersMapper registeredClientParametersMapper = new RegisteredClientParametersMapper();
214+
registeredClientParametersMapper.setPasswordEncoder(passwordEncoder);
215+
jdbcRegisteredClientRepository.setRegisteredClientParametersMapper(registeredClientParametersMapper);
216+
return jdbcRegisteredClientRepository;
212217
}
213218

214219
@Bean

oauth2-authorization-server/src/test/java/org/springframework/security/config/annotation/web/configurers/oauth2/server/authorization/OidcClientRegistrationTests.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@
6060
import org.springframework.security.oauth2.jose.TestJwks;
6161
import org.springframework.security.oauth2.jose.jws.SignatureAlgorithm;
6262
import org.springframework.security.oauth2.server.authorization.client.JdbcRegisteredClientRepository;
63+
import org.springframework.security.oauth2.server.authorization.client.JdbcRegisteredClientRepository.RegisteredClientParametersMapper;
6364
import org.springframework.security.oauth2.server.authorization.client.RegisteredClient;
6465
import org.springframework.security.oauth2.server.authorization.client.RegisteredClientRepository;
6566
import org.springframework.security.oauth2.server.authorization.client.TestRegisteredClients;
@@ -226,9 +227,12 @@ private static OidcClientRegistration readClientRegistrationResponse(MockHttpSer
226227
static class AuthorizationServerConfiguration {
227228

228229
@Bean
229-
RegisteredClientRepository registeredClientRepository(JdbcOperations jdbcOperations) {
230+
RegisteredClientRepository registeredClientRepository(JdbcOperations jdbcOperations, PasswordEncoder passwordEncoder) {
230231
RegisteredClient registeredClient = TestRegisteredClients.registeredClient().build();
232+
RegisteredClientParametersMapper registeredClientParametersMapper = new RegisteredClientParametersMapper();
233+
registeredClientParametersMapper.setPasswordEncoder(passwordEncoder);
231234
JdbcRegisteredClientRepository registeredClientRepository = new JdbcRegisteredClientRepository(jdbcOperations);
235+
registeredClientRepository.setRegisteredClientParametersMapper(registeredClientParametersMapper);
232236
registeredClientRepository.save(registeredClient);
233237
return registeredClientRepository;
234238
}

oauth2-authorization-server/src/test/java/org/springframework/security/config/annotation/web/configurers/oauth2/server/authorization/OidcTests.java

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@
7373
import org.springframework.security.oauth2.server.authorization.OAuth2AuthorizationService;
7474
import org.springframework.security.oauth2.server.authorization.OAuth2TokenCustomizer;
7575
import org.springframework.security.oauth2.server.authorization.client.JdbcRegisteredClientRepository;
76+
import org.springframework.security.oauth2.server.authorization.client.JdbcRegisteredClientRepository.RegisteredClientParametersMapper;
7677
import org.springframework.security.oauth2.server.authorization.client.RegisteredClient;
7778
import org.springframework.security.oauth2.server.authorization.client.RegisteredClientRepository;
7879
import org.springframework.security.oauth2.server.authorization.client.TestRegisteredClients;
@@ -275,8 +276,12 @@ OAuth2AuthorizationService authorizationService(JdbcOperations jdbcOperations, R
275276
}
276277

277278
@Bean
278-
RegisteredClientRepository registeredClientRepository(JdbcOperations jdbcOperations) {
279-
return new JdbcRegisteredClientRepository(jdbcOperations);
279+
RegisteredClientRepository registeredClientRepository(JdbcOperations jdbcOperations, PasswordEncoder passwordEncoder) {
280+
JdbcRegisteredClientRepository jdbcRegisteredClientRepository = new JdbcRegisteredClientRepository(jdbcOperations);
281+
RegisteredClientParametersMapper registeredClientParametersMapper = new RegisteredClientParametersMapper();
282+
registeredClientParametersMapper.setPasswordEncoder(passwordEncoder);
283+
jdbcRegisteredClientRepository.setRegisteredClientParametersMapper(registeredClientParametersMapper);
284+
return jdbcRegisteredClientRepository;
280285
}
281286

282287
@Bean

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

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,9 +40,13 @@
4040
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabase;
4141
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder;
4242
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType;
43+
import org.springframework.security.crypto.password.NoOpPasswordEncoder;
44+
import org.springframework.security.crypto.password.PasswordEncoder;
4345
import org.springframework.security.jackson2.SecurityJackson2Modules;
4446
import org.springframework.security.oauth2.core.AuthorizationGrantType;
4547
import org.springframework.security.oauth2.core.ClientAuthenticationMethod;
48+
import org.springframework.security.oauth2.server.authorization.client.JdbcRegisteredClientRepository.RegisteredClientParametersMapper;
49+
import org.springframework.security.oauth2.server.authorization.client.JdbcRegisteredClientRepository.RegisteredClientRowMapper;
4650
import org.springframework.security.oauth2.server.authorization.config.ClientSettings;
4751
import org.springframework.security.oauth2.server.authorization.config.TokenSettings;
4852
import org.springframework.security.oauth2.server.authorization.jackson2.OAuth2AuthorizationServerJackson2Module;
@@ -52,6 +56,7 @@
5256
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
5357
import static org.mockito.ArgumentMatchers.any;
5458
import static org.mockito.ArgumentMatchers.anyInt;
59+
import static org.mockito.ArgumentMatchers.anyString;
5560
import static org.mockito.Mockito.spy;
5661
import static org.mockito.Mockito.verify;
5762

@@ -69,12 +74,27 @@ public class JdbcRegisteredClientRepositoryTests {
6974
private EmbeddedDatabase db;
7075
private JdbcOperations jdbcOperations;
7176
private JdbcRegisteredClientRepository registeredClientRepository;
77+
private PasswordEncoder passwordEncoder;
7278

7379
@Before
7480
public void setUp() {
7581
this.db = createDb(OAUTH2_REGISTERED_CLIENT_SCHEMA_SQL_RESOURCE);
7682
this.jdbcOperations = new JdbcTemplate(this.db);
7783
this.registeredClientRepository = new JdbcRegisteredClientRepository(this.jdbcOperations);
84+
this.passwordEncoder = spy(new PasswordEncoder() {
85+
@Override
86+
public String encode(CharSequence rawPassword) {
87+
return NoOpPasswordEncoder.getInstance().encode(rawPassword);
88+
}
89+
90+
@Override
91+
public boolean matches(CharSequence rawPassword, String encodedPassword) {
92+
return NoOpPasswordEncoder.getInstance().matches(rawPassword, encodedPassword);
93+
}
94+
});
95+
RegisteredClientParametersMapper registeredClientParametersMapper = new RegisteredClientParametersMapper();
96+
registeredClientParametersMapper.setPasswordEncoder(this.passwordEncoder);
97+
this.registeredClientRepository.setRegisteredClientParametersMapper(registeredClientParametersMapper);
7898
}
7999

80100
@After
@@ -144,15 +164,18 @@ public void saveWhenNewThenSaved() {
144164
this.registeredClientRepository.save(expectedRegisteredClient);
145165
RegisteredClient registeredClient = this.registeredClientRepository.findById(expectedRegisteredClient.getId());
146166
assertThat(registeredClient).isEqualTo(expectedRegisteredClient);
167+
verify(this.passwordEncoder).encode(anyString());
147168
}
148169

149170
@Test
150171
public void saveLoadRegisteredClientWhenCustomStrategiesSetThenCalled() throws Exception {
151172
RowMapper<RegisteredClient> registeredClientRowMapper = spy(
152-
new JdbcRegisteredClientRepository.RegisteredClientRowMapper());
173+
new RegisteredClientRowMapper());
153174
this.registeredClientRepository.setRegisteredClientRowMapper(registeredClientRowMapper);
175+
RegisteredClientParametersMapper clientParametersMapper = new RegisteredClientParametersMapper();
176+
clientParametersMapper.setPasswordEncoder(this.passwordEncoder);
154177
Function<RegisteredClient, List<SqlParameterValue>> registeredClientParametersMapper = spy(
155-
new JdbcRegisteredClientRepository.RegisteredClientParametersMapper());
178+
clientParametersMapper);
156179
this.registeredClientRepository.setRegisteredClientParametersMapper(registeredClientParametersMapper);
157180

158181
RegisteredClient registeredClient = TestRegisteredClients.registeredClient().build();
@@ -161,6 +184,7 @@ public void saveLoadRegisteredClientWhenCustomStrategiesSetThenCalled() throws E
161184
assertThat(result).isEqualTo(registeredClient);
162185
verify(registeredClientRowMapper).mapRow(any(), anyInt());
163186
verify(registeredClientParametersMapper).apply(any());
187+
verify(this.passwordEncoder).encode(anyString());
164188
}
165189

166190
@Test
@@ -212,14 +236,17 @@ public void findByClientIdWhenNotExistsThenNotFound() {
212236
@Test
213237
public void tableDefinitionWhenCustomThenAbleToOverride() {
214238
EmbeddedDatabase db = createDb(OAUTH2_CUSTOM_REGISTERED_CLIENT_SCHEMA_SQL_RESOURCE);
215-
RegisteredClientRepository registeredClientRepository =
216-
new CustomJdbcRegisteredClientRepository(new JdbcTemplate(db));
239+
RegisteredClientParametersMapper registeredClientParametersMapper = new RegisteredClientParametersMapper();
240+
registeredClientParametersMapper.setPasswordEncoder(this.passwordEncoder);
241+
CustomJdbcRegisteredClientRepository registeredClientRepository = new CustomJdbcRegisteredClientRepository(new JdbcTemplate(db));
242+
registeredClientRepository.setRegisteredClientParametersMapper(registeredClientParametersMapper);
217243
RegisteredClient registeredClient = TestRegisteredClients.registeredClient().build();
218244
registeredClientRepository.save(registeredClient);
219245
RegisteredClient foundRegisteredClient1 = registeredClientRepository.findById(registeredClient.getId());
220246
assertThat(foundRegisteredClient1).isEqualTo(registeredClient);
221247
RegisteredClient foundRegisteredClient2 = registeredClientRepository.findByClientId(registeredClient.getClientId());
222248
assertThat(foundRegisteredClient2).isEqualTo(registeredClient);
249+
verify(this.passwordEncoder).encode(anyString());
223250
db.shutdown();
224251
}
225252

0 commit comments

Comments
 (0)