diff --git a/oauth2-authorization-server/src/test/java/org/springframework/security/config/annotation/web/configurers/oauth2/server/authorization/JwkSetTests.java b/oauth2-authorization-server/src/test/java/org/springframework/security/config/annotation/web/configurers/oauth2/server/authorization/JwkSetTests.java index 2cdf451a..580fce9c 100644 --- a/oauth2-authorization-server/src/test/java/org/springframework/security/config/annotation/web/configurers/oauth2/server/authorization/JwkSetTests.java +++ b/oauth2-authorization-server/src/test/java/org/springframework/security/config/annotation/web/configurers/oauth2/server/authorization/JwkSetTests.java @@ -18,6 +18,8 @@ package org.springframework.security.config.annotation.web.configurers.oauth2.se import com.nimbusds.jose.jwk.JWKSet; import com.nimbusds.jose.jwk.source.JWKSource; import com.nimbusds.jose.proc.SecurityContext; +import org.junit.After; +import org.junit.AfterClass; import org.junit.BeforeClass; import org.junit.Rule; import org.junit.Test; @@ -26,16 +28,19 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Import; import org.springframework.http.HttpHeaders; +import org.springframework.jdbc.core.JdbcOperations; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.jdbc.datasource.embedded.EmbeddedDatabase; +import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder; +import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.OAuth2AuthorizationServerConfiguration; import org.springframework.security.config.test.SpringTestRule; import org.springframework.security.oauth2.jose.TestJwks; -import org.springframework.security.oauth2.server.authorization.InMemoryOAuth2AuthorizationService; +import org.springframework.security.oauth2.server.authorization.JdbcOAuth2AuthorizationService; import org.springframework.security.oauth2.server.authorization.OAuth2AuthorizationService; -import org.springframework.security.oauth2.server.authorization.client.InMemoryRegisteredClientRepository; -import org.springframework.security.oauth2.server.authorization.client.RegisteredClient; +import org.springframework.security.oauth2.server.authorization.client.JdbcRegisteredClientRepository; import org.springframework.security.oauth2.server.authorization.client.RegisteredClientRepository; -import org.springframework.security.oauth2.server.authorization.client.TestRegisteredClients; import org.springframework.security.oauth2.server.authorization.config.ProviderSettings; import org.springframework.security.oauth2.server.authorization.web.NimbusJwkSetEndpointFilter; import org.springframework.test.web.servlet.MockMvc; @@ -52,6 +57,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers. * @author Florian Berthe */ public class JwkSetTests { + private static EmbeddedDatabase db; private static JWKSource jwkSource; private static ProviderSettings providerSettings; @@ -61,11 +67,32 @@ public class JwkSetTests { @Autowired private MockMvc mvc; + @Autowired + private JdbcOperations jdbcOperations; + @BeforeClass public static void init() { JWKSet jwkSet = new JWKSet(TestJwks.DEFAULT_RSA_JWK); jwkSource = (jwkSelector, securityContext) -> jwkSelector.select(jwkSet); providerSettings = new ProviderSettings().jwkSetEndpoint("/test/jwks"); + db = new EmbeddedDatabaseBuilder() + .generateUniqueName(true) + .setType(EmbeddedDatabaseType.HSQL) + .setScriptEncoding("UTF-8") + .addScript("org/springframework/security/oauth2/server/authorization/oauth2-authorization-schema.sql") + .addScript("org/springframework/security/oauth2/server/authorization/client/oauth2-registered-client-schema.sql") + .build(); + } + + @After + public void tearDown() { + jdbcOperations.update("truncate table oauth2_authorization"); + jdbcOperations.update("truncate table oauth2_registered_client"); + } + + @AfterClass + public static void destroy() { + db.shutdown(); } @Test @@ -96,20 +123,21 @@ public class JwkSetTests { static class AuthorizationServerConfiguration { @Bean - OAuth2AuthorizationService authorizationService() { - return new InMemoryOAuth2AuthorizationService(); + OAuth2AuthorizationService authorizationService(JdbcOperations jdbcOperations, RegisteredClientRepository registeredClientRepository) { + JdbcOAuth2AuthorizationService authorizationService = new JdbcOAuth2AuthorizationService(jdbcOperations, registeredClientRepository); + authorizationService.setAuthorizationRowMapper(new OAuth2ClientCredentialsGrantTests.AuthorizationServerConfiguration.RowMapper(registeredClientRepository)); + authorizationService.setAuthorizationParametersMapper(new OAuth2ClientCredentialsGrantTests.AuthorizationServerConfiguration.ParametersMapper()); + return authorizationService; } @Bean - RegisteredClientRepository registeredClientRepository() { - // @formatter:off - RegisteredClient dummyClient = TestRegisteredClients.registeredClient() - .id("dummy-client") - .clientId("dummy-client") - .clientSecret("dummy-secret") - .build(); - // @formatter:on - return new InMemoryRegisteredClientRepository(dummyClient); + RegisteredClientRepository registeredClientRepository(JdbcOperations jdbcOperations) { + return new JdbcRegisteredClientRepository(jdbcOperations); + } + + @Bean + JdbcOperations jdbcOperations() { + return new JdbcTemplate(db); } @Bean diff --git a/oauth2-authorization-server/src/test/java/org/springframework/security/config/annotation/web/configurers/oauth2/server/authorization/OAuth2AuthorizationCodeGrantTests.java b/oauth2-authorization-server/src/test/java/org/springframework/security/config/annotation/web/configurers/oauth2/server/authorization/OAuth2AuthorizationCodeGrantTests.java index 8f9d602c..0562338a 100644 --- a/oauth2-authorization-server/src/test/java/org/springframework/security/config/annotation/web/configurers/oauth2/server/authorization/OAuth2AuthorizationCodeGrantTests.java +++ b/oauth2-authorization-server/src/test/java/org/springframework/security/config/annotation/web/configurers/oauth2/server/authorization/OAuth2AuthorizationCodeGrantTests.java @@ -29,6 +29,8 @@ import java.util.stream.Collectors; import com.nimbusds.jose.jwk.JWKSet; import com.nimbusds.jose.jwk.source.JWKSource; import com.nimbusds.jose.proc.SecurityContext; +import org.junit.After; +import org.junit.AfterClass; import org.junit.BeforeClass; import org.junit.Rule; import org.junit.Test; @@ -39,8 +41,14 @@ import org.springframework.context.annotation.Import; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.http.converter.HttpMessageConverter; +import org.springframework.jdbc.core.JdbcOperations; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.jdbc.datasource.embedded.EmbeddedDatabase; +import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder; +import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType; import org.springframework.mock.http.client.MockClientHttpResponse; import org.springframework.mock.web.MockHttpServletResponse; +import org.springframework.security.authentication.TestingAuthenticationToken; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.OAuth2AuthorizationServerConfiguration; @@ -61,8 +69,8 @@ import org.springframework.security.oauth2.jwt.Jwt; import org.springframework.security.oauth2.jwt.JwtDecoder; import org.springframework.security.oauth2.jwt.JwtEncoder; import org.springframework.security.oauth2.jwt.NimbusJwsEncoder; -import org.springframework.security.oauth2.server.authorization.InMemoryOAuth2AuthorizationConsentService; -import org.springframework.security.oauth2.server.authorization.InMemoryOAuth2AuthorizationService; +import org.springframework.security.oauth2.server.authorization.JdbcOAuth2AuthorizationConsentService; +import org.springframework.security.oauth2.server.authorization.JdbcOAuth2AuthorizationService; import org.springframework.security.oauth2.server.authorization.JwtEncodingContext; import org.springframework.security.oauth2.server.authorization.OAuth2Authorization; import org.springframework.security.oauth2.server.authorization.OAuth2AuthorizationCode; @@ -70,11 +78,12 @@ import org.springframework.security.oauth2.server.authorization.OAuth2Authorizat import org.springframework.security.oauth2.server.authorization.OAuth2AuthorizationService; import org.springframework.security.oauth2.server.authorization.OAuth2TokenCustomizer; import org.springframework.security.oauth2.server.authorization.TestOAuth2Authorizations; -import org.springframework.security.oauth2.server.authorization.client.InMemoryRegisteredClientRepository; +import org.springframework.security.oauth2.server.authorization.client.JdbcRegisteredClientRepository; import org.springframework.security.oauth2.server.authorization.client.RegisteredClient; import org.springframework.security.oauth2.server.authorization.client.RegisteredClientRepository; import org.springframework.security.oauth2.server.authorization.client.TestRegisteredClients; import org.springframework.security.oauth2.server.authorization.config.ProviderSettings; +import org.springframework.security.oauth2.server.authorization.jackson2.TestingAuthenticationTokenMixin; import org.springframework.security.oauth2.server.authorization.web.OAuth2AuthorizationEndpointFilter; import org.springframework.security.oauth2.server.authorization.web.OAuth2TokenEndpointFilter; import org.springframework.security.web.SecurityFilterChain; @@ -111,6 +120,7 @@ public class OAuth2AuthorizationCodeGrantTests { private static final OAuth2TokenType AUTHORIZATION_CODE_TOKEN_TYPE = new OAuth2TokenType(OAuth2ParameterNames.CODE); private static final OAuth2TokenType STATE_TOKEN_TYPE = new OAuth2TokenType(OAuth2ParameterNames.STATE); + private static EmbeddedDatabase db; private static JWKSource jwkSource; private static NimbusJwsEncoder jwtEncoder; private static ProviderSettings providerSettings; @@ -124,6 +134,9 @@ public class OAuth2AuthorizationCodeGrantTests { @Autowired private MockMvc mvc; + @Autowired + private JdbcOperations jdbcOperations; + @Autowired private RegisteredClientRepository registeredClientRepository; @@ -141,6 +154,26 @@ public class OAuth2AuthorizationCodeGrantTests { providerSettings = new ProviderSettings() .authorizationEndpoint("/test/authorize") .tokenEndpoint("/test/token"); + db = new EmbeddedDatabaseBuilder() + .generateUniqueName(true) + .setType(EmbeddedDatabaseType.HSQL) + .setScriptEncoding("UTF-8") + .addScript("org/springframework/security/oauth2/server/authorization/oauth2-authorization-schema.sql") + .addScript("org/springframework/security/oauth2/server/authorization/oauth2-authorization-consent-schema.sql") + .addScript("org/springframework/security/oauth2/server/authorization/client/oauth2-registered-client-schema.sql") + .build(); + } + + @After + public void tearDown() { + jdbcOperations.update("truncate table oauth2_authorization"); + jdbcOperations.update("truncate table oauth2_authorization_consent"); + jdbcOperations.update("truncate table oauth2_registered_client"); + } + + @AfterClass + public static void destroy() { + db.shutdown(); } @Test @@ -485,25 +518,26 @@ public class OAuth2AuthorizationCodeGrantTests { static class AuthorizationServerConfiguration { @Bean - OAuth2AuthorizationService authorizationService() { - return new InMemoryOAuth2AuthorizationService(); + OAuth2AuthorizationService authorizationService(JdbcOperations jdbcOperations, RegisteredClientRepository registeredClientRepository) { + JdbcOAuth2AuthorizationService authorizationService = new JdbcOAuth2AuthorizationService(jdbcOperations, registeredClientRepository); + authorizationService.setAuthorizationRowMapper(new RowMapper(registeredClientRepository)); + authorizationService.setAuthorizationParametersMapper(new ParametersMapper()); + return authorizationService; } @Bean - OAuth2AuthorizationConsentService authorizationConsentService() { - return new InMemoryOAuth2AuthorizationConsentService(); + OAuth2AuthorizationConsentService authorizationConsentService(JdbcOperations jdbcOperations, RegisteredClientRepository registeredClientRepository) { + return new JdbcOAuth2AuthorizationConsentService(jdbcOperations, registeredClientRepository); } @Bean - RegisteredClientRepository registeredClientRepository() { - // @formatter:off - RegisteredClient dummyClient = TestRegisteredClients.registeredClient() - .id("dummy-client") - .clientId("dummy-client") - .clientSecret("dummy-secret") - .build(); - // @formatter:on - return new InMemoryRegisteredClientRepository(dummyClient); + RegisteredClientRepository registeredClientRepository(JdbcOperations jdbcOperations) { + return new JdbcRegisteredClientRepository(jdbcOperations); + } + + @Bean + JdbcOperations jdbcOperations() { + return new JdbcTemplate(db); } @Bean @@ -530,6 +564,24 @@ public class OAuth2AuthorizationCodeGrantTests { return NoOpPasswordEncoder.getInstance(); } + static class RowMapper extends JdbcOAuth2AuthorizationService.OAuth2AuthorizationRowMapper { + + RowMapper(RegisteredClientRepository registeredClientRepository) { + super(registeredClientRepository); + getObjectMapper().addMixIn(TestingAuthenticationToken.class, TestingAuthenticationTokenMixin.class); + } + + } + + static class ParametersMapper extends JdbcOAuth2AuthorizationService.OAuth2AuthorizationParametersMapper { + + ParametersMapper() { + super(); + getObjectMapper().addMixIn(TestingAuthenticationToken.class, TestingAuthenticationTokenMixin.class); + } + + } + } @EnableWebSecurity diff --git a/oauth2-authorization-server/src/test/java/org/springframework/security/config/annotation/web/configurers/oauth2/server/authorization/OAuth2AuthorizationServerMetadataTests.java b/oauth2-authorization-server/src/test/java/org/springframework/security/config/annotation/web/configurers/oauth2/server/authorization/OAuth2AuthorizationServerMetadataTests.java index 9073dfd5..4aa41ebd 100644 --- a/oauth2-authorization-server/src/test/java/org/springframework/security/config/annotation/web/configurers/oauth2/server/authorization/OAuth2AuthorizationServerMetadataTests.java +++ b/oauth2-authorization-server/src/test/java/org/springframework/security/config/annotation/web/configurers/oauth2/server/authorization/OAuth2AuthorizationServerMetadataTests.java @@ -18,6 +18,8 @@ package org.springframework.security.config.annotation.web.configurers.oauth2.se import com.nimbusds.jose.jwk.JWKSet; import com.nimbusds.jose.jwk.source.JWKSource; import com.nimbusds.jose.proc.SecurityContext; +import org.junit.After; +import org.junit.AfterClass; import org.junit.BeforeClass; import org.junit.Rule; import org.junit.Test; @@ -25,11 +27,16 @@ import org.junit.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Import; +import org.springframework.jdbc.core.JdbcOperations; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.jdbc.datasource.embedded.EmbeddedDatabase; +import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder; +import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.OAuth2AuthorizationServerConfiguration; import org.springframework.security.config.test.SpringTestRule; import org.springframework.security.oauth2.jose.TestJwks; -import org.springframework.security.oauth2.server.authorization.client.InMemoryRegisteredClientRepository; +import org.springframework.security.oauth2.server.authorization.client.JdbcRegisteredClientRepository; import org.springframework.security.oauth2.server.authorization.client.RegisteredClient; import org.springframework.security.oauth2.server.authorization.client.RegisteredClientRepository; import org.springframework.security.oauth2.server.authorization.client.TestRegisteredClients; @@ -48,6 +55,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers. */ public class OAuth2AuthorizationServerMetadataTests { private static final String issuerUrl = "https://example.com/issuer1"; + private static EmbeddedDatabase db; private static JWKSource jwkSource; @Rule @@ -56,10 +64,31 @@ public class OAuth2AuthorizationServerMetadataTests { @Autowired private MockMvc mvc; + @Autowired + private JdbcOperations jdbcOperations; + @BeforeClass public static void setupClass() { JWKSet jwkSet = new JWKSet(TestJwks.DEFAULT_RSA_JWK); jwkSource = (jwkSelector, securityContext) -> jwkSelector.select(jwkSet); + db = new EmbeddedDatabaseBuilder() + .generateUniqueName(true) + .setType(EmbeddedDatabaseType.HSQL) + .setScriptEncoding("UTF-8") + .addScript("org/springframework/security/oauth2/server/authorization/oauth2-authorization-schema.sql") + .addScript("org/springframework/security/oauth2/server/authorization/client/oauth2-registered-client-schema.sql") + .build(); + } + + @After + public void tearDown() { + jdbcOperations.update("truncate table oauth2_authorization"); + jdbcOperations.update("truncate table oauth2_registered_client"); + } + + @AfterClass + public static void destroy() { + db.shutdown(); } @Test @@ -77,9 +106,16 @@ public class OAuth2AuthorizationServerMetadataTests { static class AuthorizationServerConfiguration { @Bean - RegisteredClientRepository registeredClientRepository() { + RegisteredClientRepository registeredClientRepository(JdbcOperations jdbcOperations) { RegisteredClient registeredClient = TestRegisteredClients.registeredClient().build(); - return new InMemoryRegisteredClientRepository(registeredClient); + JdbcRegisteredClientRepository registeredClientRepository = new JdbcRegisteredClientRepository(jdbcOperations); + registeredClientRepository.save(registeredClient); + return registeredClientRepository; + } + + @Bean + JdbcOperations jdbcOperations() { + return new JdbcTemplate(db); } @Bean diff --git a/oauth2-authorization-server/src/test/java/org/springframework/security/config/annotation/web/configurers/oauth2/server/authorization/OAuth2ClientCredentialsGrantTests.java b/oauth2-authorization-server/src/test/java/org/springframework/security/config/annotation/web/configurers/oauth2/server/authorization/OAuth2ClientCredentialsGrantTests.java index 4ec2e23a..983fc4da 100644 --- a/oauth2-authorization-server/src/test/java/org/springframework/security/config/annotation/web/configurers/oauth2/server/authorization/OAuth2ClientCredentialsGrantTests.java +++ b/oauth2-authorization-server/src/test/java/org/springframework/security/config/annotation/web/configurers/oauth2/server/authorization/OAuth2ClientCredentialsGrantTests.java @@ -24,6 +24,8 @@ import java.util.Base64; import com.nimbusds.jose.jwk.JWKSet; import com.nimbusds.jose.jwk.source.JWKSource; import com.nimbusds.jose.proc.SecurityContext; +import org.junit.After; +import org.junit.AfterClass; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Rule; @@ -33,7 +35,13 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Import; import org.springframework.http.HttpHeaders; +import org.springframework.jdbc.core.JdbcOperations; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.jdbc.datasource.embedded.EmbeddedDatabase; +import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder; +import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType; import org.springframework.security.authentication.AuthenticationProvider; +import org.springframework.security.authentication.TestingAuthenticationToken; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.OAuth2AuthorizationServerConfiguration; @@ -44,19 +52,18 @@ import org.springframework.security.oauth2.core.AuthorizationGrantType; import org.springframework.security.oauth2.core.OAuth2AccessToken; import org.springframework.security.oauth2.core.endpoint.OAuth2ParameterNames; import org.springframework.security.oauth2.jose.TestJwks; -import org.springframework.security.oauth2.server.authorization.InMemoryOAuth2AuthorizationConsentService; -import org.springframework.security.oauth2.server.authorization.InMemoryOAuth2AuthorizationService; +import org.springframework.security.oauth2.server.authorization.JdbcOAuth2AuthorizationService; import org.springframework.security.oauth2.server.authorization.JwtEncodingContext; -import org.springframework.security.oauth2.server.authorization.OAuth2AuthorizationConsentService; import org.springframework.security.oauth2.server.authorization.OAuth2AuthorizationService; import org.springframework.security.oauth2.server.authorization.OAuth2TokenCustomizer; import org.springframework.security.oauth2.server.authorization.authentication.OAuth2AccessTokenAuthenticationToken; import org.springframework.security.oauth2.server.authorization.authentication.OAuth2ClientAuthenticationToken; import org.springframework.security.oauth2.server.authorization.authentication.OAuth2ClientCredentialsAuthenticationToken; -import org.springframework.security.oauth2.server.authorization.client.InMemoryRegisteredClientRepository; +import org.springframework.security.oauth2.server.authorization.client.JdbcRegisteredClientRepository; import org.springframework.security.oauth2.server.authorization.client.RegisteredClient; import org.springframework.security.oauth2.server.authorization.client.RegisteredClientRepository; import org.springframework.security.oauth2.server.authorization.client.TestRegisteredClients; +import org.springframework.security.oauth2.server.authorization.jackson2.TestingAuthenticationTokenMixin; import org.springframework.security.oauth2.server.authorization.web.OAuth2TokenEndpointFilter; import org.springframework.security.web.SecurityFilterChain; import org.springframework.security.web.authentication.AuthenticationConverter; @@ -83,6 +90,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers. * @author Joe Grandja */ public class OAuth2ClientCredentialsGrantTests { + private static EmbeddedDatabase db; private static JWKSource jwkSource; private static OAuth2TokenCustomizer jwtCustomizer; private static AuthenticationConverter accessTokenRequestConverter; @@ -96,6 +104,9 @@ public class OAuth2ClientCredentialsGrantTests { @Autowired private MockMvc mvc; + @Autowired + private JdbcOperations jdbcOperations; + @Autowired private RegisteredClientRepository registeredClientRepository; @@ -108,6 +119,13 @@ public class OAuth2ClientCredentialsGrantTests { authenticationProvider = mock(AuthenticationProvider.class); accessTokenResponseHandler = mock(AuthenticationSuccessHandler.class); errorResponseHandler = mock(AuthenticationFailureHandler.class); + db = new EmbeddedDatabaseBuilder() + .generateUniqueName(true) + .setType(EmbeddedDatabaseType.HSQL) + .setScriptEncoding("UTF-8") + .addScript("org/springframework/security/oauth2/server/authorization/oauth2-authorization-schema.sql") + .addScript("org/springframework/security/oauth2/server/authorization/client/oauth2-registered-client-schema.sql") + .build(); } @SuppressWarnings("unchecked") @@ -116,6 +134,17 @@ public class OAuth2ClientCredentialsGrantTests { reset(jwtCustomizer); } + @After + public void tearDown() { + jdbcOperations.update("truncate table oauth2_authorization"); + jdbcOperations.update("truncate table oauth2_registered_client"); + } + + @AfterClass + public static void destroy() { + db.shutdown(); + } + @Test public void requestWhenTokenRequestNotAuthenticatedThenUnauthorized() throws Exception { this.spring.register(AuthorizationServerConfiguration.class).autowire(); @@ -207,25 +236,21 @@ public class OAuth2ClientCredentialsGrantTests { static class AuthorizationServerConfiguration { @Bean - OAuth2AuthorizationService authorizationService() { - return new InMemoryOAuth2AuthorizationService(); + OAuth2AuthorizationService authorizationService(JdbcOperations jdbcOperations, RegisteredClientRepository registeredClientRepository) { + JdbcOAuth2AuthorizationService authorizationService = new JdbcOAuth2AuthorizationService(jdbcOperations, registeredClientRepository); + authorizationService.setAuthorizationRowMapper(new RowMapper(registeredClientRepository)); + authorizationService.setAuthorizationParametersMapper(new ParametersMapper()); + return authorizationService; } @Bean - OAuth2AuthorizationConsentService authorizationConsentService() { - return new InMemoryOAuth2AuthorizationConsentService(); + RegisteredClientRepository registeredClientRepository(JdbcOperations jdbcOperations) { + return new JdbcRegisteredClientRepository(jdbcOperations); } @Bean - RegisteredClientRepository registeredClientRepository() { - // @formatter:off - RegisteredClient dummyClient = TestRegisteredClients.registeredClient() - .id("dummy-client") - .clientId("dummy-client") - .clientSecret("dummy-secret") - .build(); - // @formatter:on - return new InMemoryRegisteredClientRepository(dummyClient); + JdbcOperations jdbcOperations() { + return new JdbcTemplate(db); } @Bean @@ -243,6 +268,24 @@ public class OAuth2ClientCredentialsGrantTests { return NoOpPasswordEncoder.getInstance(); } + static class RowMapper extends JdbcOAuth2AuthorizationService.OAuth2AuthorizationRowMapper { + + RowMapper(RegisteredClientRepository registeredClientRepository) { + super(registeredClientRepository); + getObjectMapper().addMixIn(TestingAuthenticationToken.class, TestingAuthenticationTokenMixin.class); + } + + } + + static class ParametersMapper extends JdbcOAuth2AuthorizationService.OAuth2AuthorizationParametersMapper { + + ParametersMapper() { + super(); + getObjectMapper().addMixIn(TestingAuthenticationToken.class, TestingAuthenticationTokenMixin.class); + } + + } + } @EnableWebSecurity diff --git a/oauth2-authorization-server/src/test/java/org/springframework/security/config/annotation/web/configurers/oauth2/server/authorization/OAuth2RefreshTokenGrantTests.java b/oauth2-authorization-server/src/test/java/org/springframework/security/config/annotation/web/configurers/oauth2/server/authorization/OAuth2RefreshTokenGrantTests.java index f3247b07..d9188c7d 100644 --- a/oauth2-authorization-server/src/test/java/org/springframework/security/config/annotation/web/configurers/oauth2/server/authorization/OAuth2RefreshTokenGrantTests.java +++ b/oauth2-authorization-server/src/test/java/org/springframework/security/config/annotation/web/configurers/oauth2/server/authorization/OAuth2RefreshTokenGrantTests.java @@ -26,6 +26,8 @@ import java.util.stream.Collectors; import com.nimbusds.jose.jwk.JWKSet; import com.nimbusds.jose.jwk.source.JWKSource; import com.nimbusds.jose.proc.SecurityContext; +import org.junit.After; +import org.junit.AfterClass; import org.junit.BeforeClass; import org.junit.Rule; import org.junit.Test; @@ -36,8 +38,14 @@ import org.springframework.context.annotation.Import; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.http.converter.HttpMessageConverter; +import org.springframework.jdbc.core.JdbcOperations; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.jdbc.datasource.embedded.EmbeddedDatabase; +import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder; +import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType; import org.springframework.mock.http.client.MockClientHttpResponse; import org.springframework.mock.web.MockHttpServletResponse; +import org.springframework.security.authentication.TestingAuthenticationToken; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.OAuth2AuthorizationServerConfiguration; import org.springframework.security.config.test.SpringTestRule; @@ -53,18 +61,17 @@ import org.springframework.security.oauth2.jose.TestJwks; import org.springframework.security.oauth2.jose.TestKeys; import org.springframework.security.oauth2.jwt.Jwt; import org.springframework.security.oauth2.jwt.NimbusJwtDecoder; -import org.springframework.security.oauth2.server.authorization.InMemoryOAuth2AuthorizationConsentService; -import org.springframework.security.oauth2.server.authorization.InMemoryOAuth2AuthorizationService; +import org.springframework.security.oauth2.server.authorization.JdbcOAuth2AuthorizationService; import org.springframework.security.oauth2.server.authorization.JwtEncodingContext; import org.springframework.security.oauth2.server.authorization.OAuth2Authorization; -import org.springframework.security.oauth2.server.authorization.OAuth2AuthorizationConsentService; import org.springframework.security.oauth2.server.authorization.OAuth2AuthorizationService; import org.springframework.security.oauth2.server.authorization.OAuth2TokenCustomizer; import org.springframework.security.oauth2.server.authorization.TestOAuth2Authorizations; -import org.springframework.security.oauth2.server.authorization.client.InMemoryRegisteredClientRepository; +import org.springframework.security.oauth2.server.authorization.client.JdbcRegisteredClientRepository; import org.springframework.security.oauth2.server.authorization.client.RegisteredClient; import org.springframework.security.oauth2.server.authorization.client.RegisteredClientRepository; import org.springframework.security.oauth2.server.authorization.client.TestRegisteredClients; +import org.springframework.security.oauth2.server.authorization.jackson2.TestingAuthenticationTokenMixin; import org.springframework.security.oauth2.server.authorization.web.OAuth2TokenEndpointFilter; import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.MvcResult; @@ -86,6 +93,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers. */ public class OAuth2RefreshTokenGrantTests { private static final String AUTHORITIES_CLAIM = "authorities"; + private static EmbeddedDatabase db; private static JWKSource jwkSource; private static NimbusJwtDecoder jwtDecoder; private static HttpMessageConverter accessTokenHttpResponseConverter = @@ -97,6 +105,9 @@ public class OAuth2RefreshTokenGrantTests { @Autowired private MockMvc mvc; + @Autowired + private JdbcOperations jdbcOperations; + @Autowired private RegisteredClientRepository registeredClientRepository; @@ -108,6 +119,24 @@ public class OAuth2RefreshTokenGrantTests { JWKSet jwkSet = new JWKSet(TestJwks.DEFAULT_RSA_JWK); jwkSource = (jwkSelector, securityContext) -> jwkSelector.select(jwkSet); jwtDecoder = NimbusJwtDecoder.withPublicKey(TestKeys.DEFAULT_PUBLIC_KEY).build(); + db = new EmbeddedDatabaseBuilder() + .generateUniqueName(true) + .setType(EmbeddedDatabaseType.HSQL) + .setScriptEncoding("UTF-8") + .addScript("org/springframework/security/oauth2/server/authorization/oauth2-authorization-schema.sql") + .addScript("org/springframework/security/oauth2/server/authorization/client/oauth2-registered-client-schema.sql") + .build(); + } + + @After + public void tearDown() { + jdbcOperations.update("truncate table oauth2_authorization"); + jdbcOperations.update("truncate table oauth2_registered_client"); + } + + @AfterClass + public static void destroy() { + db.shutdown(); } @Test @@ -170,25 +199,21 @@ public class OAuth2RefreshTokenGrantTests { static class AuthorizationServerConfiguration { @Bean - OAuth2AuthorizationService authorizationService() { - return new InMemoryOAuth2AuthorizationService(); + OAuth2AuthorizationService authorizationService(JdbcOperations jdbcOperations, RegisteredClientRepository registeredClientRepository) { + JdbcOAuth2AuthorizationService authorizationService = new JdbcOAuth2AuthorizationService(jdbcOperations, registeredClientRepository); + authorizationService.setAuthorizationRowMapper(new RowMapper(registeredClientRepository)); + authorizationService.setAuthorizationParametersMapper(new ParametersMapper()); + return authorizationService; } @Bean - OAuth2AuthorizationConsentService authorizationConsentService() { - return new InMemoryOAuth2AuthorizationConsentService(); + RegisteredClientRepository registeredClientRepository(JdbcOperations jdbcOperations) { + return new JdbcRegisteredClientRepository(jdbcOperations); } @Bean - RegisteredClientRepository registeredClientRepository() { - // @formatter:off - RegisteredClient dummyClient = TestRegisteredClients.registeredClient() - .id("dummy-client") - .clientId("dummy-client") - .clientSecret("dummy-secret") - .build(); - // @formatter:on - return new InMemoryRegisteredClientRepository(dummyClient); + JdbcOperations jdbcOperations() { + return new JdbcTemplate(db); } @Bean @@ -214,5 +239,23 @@ public class OAuth2RefreshTokenGrantTests { return NoOpPasswordEncoder.getInstance(); } + static class RowMapper extends JdbcOAuth2AuthorizationService.OAuth2AuthorizationRowMapper { + + RowMapper(RegisteredClientRepository registeredClientRepository) { + super(registeredClientRepository); + getObjectMapper().addMixIn(TestingAuthenticationToken.class, TestingAuthenticationTokenMixin.class); + } + + } + + static class ParametersMapper extends JdbcOAuth2AuthorizationService.OAuth2AuthorizationParametersMapper { + + ParametersMapper() { + super(); + getObjectMapper().addMixIn(TestingAuthenticationToken.class, TestingAuthenticationTokenMixin.class); + } + + } + } } diff --git a/oauth2-authorization-server/src/test/java/org/springframework/security/config/annotation/web/configurers/oauth2/server/authorization/OAuth2TokenIntrospectionTests.java b/oauth2-authorization-server/src/test/java/org/springframework/security/config/annotation/web/configurers/oauth2/server/authorization/OAuth2TokenIntrospectionTests.java index f454e02a..2c0a61de 100644 --- a/oauth2-authorization-server/src/test/java/org/springframework/security/config/annotation/web/configurers/oauth2/server/authorization/OAuth2TokenIntrospectionTests.java +++ b/oauth2-authorization-server/src/test/java/org/springframework/security/config/annotation/web/configurers/oauth2/server/authorization/OAuth2TokenIntrospectionTests.java @@ -23,6 +23,8 @@ import java.util.HashSet; import com.nimbusds.jose.jwk.JWKSet; import com.nimbusds.jose.jwk.source.JWKSource; import com.nimbusds.jose.proc.SecurityContext; +import org.junit.After; +import org.junit.AfterClass; import org.junit.BeforeClass; import org.junit.Rule; import org.junit.Test; @@ -32,8 +34,14 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Import; import org.springframework.http.HttpStatus; import org.springframework.http.converter.HttpMessageConverter; +import org.springframework.jdbc.core.JdbcOperations; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.jdbc.datasource.embedded.EmbeddedDatabase; +import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder; +import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType; import org.springframework.mock.http.client.MockClientHttpResponse; import org.springframework.mock.web.MockHttpServletResponse; +import org.springframework.security.authentication.TestingAuthenticationToken; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.OAuth2AuthorizationServerConfiguration; import org.springframework.security.config.test.SpringTestRule; @@ -49,17 +57,16 @@ import org.springframework.security.oauth2.core.http.converter.OAuth2TokenIntros import org.springframework.security.oauth2.jose.TestJwks; import org.springframework.security.oauth2.jwt.JwtClaimsSet; import org.springframework.security.oauth2.jwt.TestJwtClaimsSets; -import org.springframework.security.oauth2.server.authorization.InMemoryOAuth2AuthorizationConsentService; -import org.springframework.security.oauth2.server.authorization.InMemoryOAuth2AuthorizationService; +import org.springframework.security.oauth2.server.authorization.JdbcOAuth2AuthorizationService; import org.springframework.security.oauth2.server.authorization.OAuth2Authorization; -import org.springframework.security.oauth2.server.authorization.OAuth2AuthorizationConsentService; import org.springframework.security.oauth2.server.authorization.OAuth2AuthorizationService; import org.springframework.security.oauth2.server.authorization.TestOAuth2Authorizations; -import org.springframework.security.oauth2.server.authorization.client.InMemoryRegisteredClientRepository; +import org.springframework.security.oauth2.server.authorization.client.JdbcRegisteredClientRepository; import org.springframework.security.oauth2.server.authorization.client.RegisteredClient; import org.springframework.security.oauth2.server.authorization.client.RegisteredClientRepository; import org.springframework.security.oauth2.server.authorization.client.TestRegisteredClients; import org.springframework.security.oauth2.server.authorization.config.ProviderSettings; +import org.springframework.security.oauth2.server.authorization.jackson2.TestingAuthenticationTokenMixin; import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.MvcResult; import org.springframework.util.LinkedMultiValueMap; @@ -77,6 +84,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers. * @author Joe Grandja */ public class OAuth2TokenIntrospectionTests { + private static EmbeddedDatabase db; private static JWKSource jwkSource; private static ProviderSettings providerSettings; private final HttpMessageConverter tokenIntrospectionHttpResponseConverter = @@ -88,6 +96,9 @@ public class OAuth2TokenIntrospectionTests { @Autowired private MockMvc mvc; + @Autowired + private JdbcOperations jdbcOperations; + @Autowired private RegisteredClientRepository registeredClientRepository; @@ -99,6 +110,24 @@ public class OAuth2TokenIntrospectionTests { JWKSet jwkSet = new JWKSet(TestJwks.DEFAULT_RSA_JWK); jwkSource = (jwkSelector, securityContext) -> jwkSelector.select(jwkSet); providerSettings = new ProviderSettings().tokenIntrospectionEndpoint("/test/introspect"); + db = new EmbeddedDatabaseBuilder() + .generateUniqueName(true) + .setType(EmbeddedDatabaseType.HSQL) + .setScriptEncoding("UTF-8") + .addScript("org/springframework/security/oauth2/server/authorization/oauth2-authorization-schema.sql") + .addScript("org/springframework/security/oauth2/server/authorization/client/oauth2-registered-client-schema.sql") + .build(); + } + + @After + public void tearDown() { + jdbcOperations.update("truncate table oauth2_authorization"); + jdbcOperations.update("truncate table oauth2_registered_client"); + } + + @AfterClass + public static void destroy() { + db.shutdown(); } @Test @@ -207,25 +236,21 @@ public class OAuth2TokenIntrospectionTests { static class AuthorizationServerConfiguration { @Bean - OAuth2AuthorizationService authorizationService() { - return new InMemoryOAuth2AuthorizationService(); + OAuth2AuthorizationService authorizationService(JdbcOperations jdbcOperations, RegisteredClientRepository registeredClientRepository) { + JdbcOAuth2AuthorizationService authorizationService = new JdbcOAuth2AuthorizationService(jdbcOperations, registeredClientRepository); + authorizationService.setAuthorizationRowMapper(new RowMapper(registeredClientRepository)); + authorizationService.setAuthorizationParametersMapper(new ParametersMapper()); + return authorizationService; } @Bean - OAuth2AuthorizationConsentService authorizationConsentService() { - return new InMemoryOAuth2AuthorizationConsentService(); + RegisteredClientRepository registeredClientRepository(JdbcOperations jdbcOperations) { + return new JdbcRegisteredClientRepository(jdbcOperations); } @Bean - RegisteredClientRepository registeredClientRepository() { - // @formatter:off - RegisteredClient dummyClient = TestRegisteredClients.registeredClient() - .id("dummy-client") - .clientId("dummy-client") - .clientSecret("dummy-secret") - .build(); - // @formatter:on - return new InMemoryRegisteredClientRepository(dummyClient); + JdbcOperations jdbcOperations() { + return new JdbcTemplate(db); } @Bean @@ -243,5 +268,23 @@ public class OAuth2TokenIntrospectionTests { return NoOpPasswordEncoder.getInstance(); } + static class RowMapper extends JdbcOAuth2AuthorizationService.OAuth2AuthorizationRowMapper { + + RowMapper(RegisteredClientRepository registeredClientRepository) { + super(registeredClientRepository); + getObjectMapper().addMixIn(TestingAuthenticationToken.class, TestingAuthenticationTokenMixin.class); + } + + } + + static class ParametersMapper extends JdbcOAuth2AuthorizationService.OAuth2AuthorizationParametersMapper { + + ParametersMapper() { + super(); + getObjectMapper().addMixIn(TestingAuthenticationToken.class, TestingAuthenticationTokenMixin.class); + } + + } + } } diff --git a/oauth2-authorization-server/src/test/java/org/springframework/security/config/annotation/web/configurers/oauth2/server/authorization/OAuth2TokenRevocationTests.java b/oauth2-authorization-server/src/test/java/org/springframework/security/config/annotation/web/configurers/oauth2/server/authorization/OAuth2TokenRevocationTests.java index cb7dd0ed..437b3fae 100644 --- a/oauth2-authorization-server/src/test/java/org/springframework/security/config/annotation/web/configurers/oauth2/server/authorization/OAuth2TokenRevocationTests.java +++ b/oauth2-authorization-server/src/test/java/org/springframework/security/config/annotation/web/configurers/oauth2/server/authorization/OAuth2TokenRevocationTests.java @@ -22,6 +22,8 @@ import java.util.Base64; import com.nimbusds.jose.jwk.JWKSet; import com.nimbusds.jose.jwk.source.JWKSource; import com.nimbusds.jose.proc.SecurityContext; +import org.junit.After; +import org.junit.AfterClass; import org.junit.BeforeClass; import org.junit.Rule; import org.junit.Test; @@ -30,6 +32,12 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Import; import org.springframework.http.HttpHeaders; +import org.springframework.jdbc.core.JdbcOperations; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.jdbc.datasource.embedded.EmbeddedDatabase; +import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder; +import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType; +import org.springframework.security.authentication.TestingAuthenticationToken; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.OAuth2AuthorizationServerConfiguration; import org.springframework.security.config.test.SpringTestRule; @@ -41,17 +49,16 @@ import org.springframework.security.oauth2.core.OAuth2RefreshToken; import org.springframework.security.oauth2.core.OAuth2TokenType; import org.springframework.security.oauth2.core.endpoint.OAuth2ParameterNames2; import org.springframework.security.oauth2.jose.TestJwks; -import org.springframework.security.oauth2.server.authorization.InMemoryOAuth2AuthorizationConsentService; -import org.springframework.security.oauth2.server.authorization.InMemoryOAuth2AuthorizationService; +import org.springframework.security.oauth2.server.authorization.JdbcOAuth2AuthorizationService; import org.springframework.security.oauth2.server.authorization.OAuth2Authorization; -import org.springframework.security.oauth2.server.authorization.OAuth2AuthorizationConsentService; import org.springframework.security.oauth2.server.authorization.OAuth2AuthorizationService; import org.springframework.security.oauth2.server.authorization.TestOAuth2Authorizations; -import org.springframework.security.oauth2.server.authorization.client.InMemoryRegisteredClientRepository; +import org.springframework.security.oauth2.server.authorization.client.JdbcRegisteredClientRepository; import org.springframework.security.oauth2.server.authorization.client.RegisteredClient; import org.springframework.security.oauth2.server.authorization.client.RegisteredClientRepository; import org.springframework.security.oauth2.server.authorization.client.TestRegisteredClients; import org.springframework.security.oauth2.server.authorization.config.ProviderSettings; +import org.springframework.security.oauth2.server.authorization.jackson2.TestingAuthenticationTokenMixin; import org.springframework.security.oauth2.server.authorization.web.OAuth2TokenRevocationEndpointFilter; import org.springframework.test.web.servlet.MockMvc; import org.springframework.util.LinkedMultiValueMap; @@ -67,6 +74,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers. * @author Joe Grandja */ public class OAuth2TokenRevocationTests { + private static EmbeddedDatabase db; private static JWKSource jwkSource; private static ProviderSettings providerSettings; @@ -76,6 +84,9 @@ public class OAuth2TokenRevocationTests { @Autowired private MockMvc mvc; + @Autowired + private JdbcOperations jdbcOperations; + @Autowired private RegisteredClientRepository registeredClientRepository; @@ -87,6 +98,24 @@ public class OAuth2TokenRevocationTests { JWKSet jwkSet = new JWKSet(TestJwks.DEFAULT_RSA_JWK); jwkSource = (jwkSelector, securityContext) -> jwkSelector.select(jwkSet); providerSettings = new ProviderSettings().tokenRevocationEndpoint("/test/revoke"); + db = new EmbeddedDatabaseBuilder() + .generateUniqueName(true) + .setType(EmbeddedDatabaseType.HSQL) + .setScriptEncoding("UTF-8") + .addScript("org/springframework/security/oauth2/server/authorization/oauth2-authorization-schema.sql") + .addScript("org/springframework/security/oauth2/server/authorization/client/oauth2-registered-client-schema.sql") + .build(); + } + + @After + public void tearDown() { + jdbcOperations.update("truncate table oauth2_authorization"); + jdbcOperations.update("truncate table oauth2_registered_client"); + } + + @AfterClass + public static void destroy() { + db.shutdown(); } @Test @@ -170,25 +199,21 @@ public class OAuth2TokenRevocationTests { static class AuthorizationServerConfiguration { @Bean - OAuth2AuthorizationService authorizationService() { - return new InMemoryOAuth2AuthorizationService(); + OAuth2AuthorizationService authorizationService(JdbcOperations jdbcOperations, RegisteredClientRepository registeredClientRepository) { + JdbcOAuth2AuthorizationService authorizationService = new JdbcOAuth2AuthorizationService(jdbcOperations, registeredClientRepository); + authorizationService.setAuthorizationRowMapper(new RowMapper(registeredClientRepository)); + authorizationService.setAuthorizationParametersMapper(new ParametersMapper()); + return authorizationService; } @Bean - OAuth2AuthorizationConsentService authorizationConsentService() { - return new InMemoryOAuth2AuthorizationConsentService(); + RegisteredClientRepository registeredClientRepository(JdbcOperations jdbcOperations) { + return new JdbcRegisteredClientRepository(jdbcOperations); } @Bean - RegisteredClientRepository registeredClientRepository() { - // @formatter:off - RegisteredClient dummyClient = TestRegisteredClients.registeredClient() - .id("dummy-client") - .clientId("dummy-client") - .clientSecret("dummy-secret") - .build(); - // @formatter:on - return new InMemoryRegisteredClientRepository(dummyClient); + JdbcOperations jdbcOperations() { + return new JdbcTemplate(db); } @Bean @@ -201,6 +226,24 @@ public class OAuth2TokenRevocationTests { return NoOpPasswordEncoder.getInstance(); } + static class RowMapper extends JdbcOAuth2AuthorizationService.OAuth2AuthorizationRowMapper { + + RowMapper(RegisteredClientRepository registeredClientRepository) { + super(registeredClientRepository); + getObjectMapper().addMixIn(TestingAuthenticationToken.class, TestingAuthenticationTokenMixin.class); + } + + } + + static class ParametersMapper extends JdbcOAuth2AuthorizationService.OAuth2AuthorizationParametersMapper { + + ParametersMapper() { + super(); + getObjectMapper().addMixIn(TestingAuthenticationToken.class, TestingAuthenticationTokenMixin.class); + } + + } + } @EnableWebSecurity diff --git a/oauth2-authorization-server/src/test/java/org/springframework/security/config/annotation/web/configurers/oauth2/server/authorization/OidcClientRegistrationTests.java b/oauth2-authorization-server/src/test/java/org/springframework/security/config/annotation/web/configurers/oauth2/server/authorization/OidcClientRegistrationTests.java index 4049cc2f..f480efd5 100644 --- a/oauth2-authorization-server/src/test/java/org/springframework/security/config/annotation/web/configurers/oauth2/server/authorization/OidcClientRegistrationTests.java +++ b/oauth2-authorization-server/src/test/java/org/springframework/security/config/annotation/web/configurers/oauth2/server/authorization/OidcClientRegistrationTests.java @@ -22,6 +22,8 @@ import java.util.Base64; import com.nimbusds.jose.jwk.JWKSet; import com.nimbusds.jose.jwk.source.JWKSource; import com.nimbusds.jose.proc.SecurityContext; +import org.junit.After; +import org.junit.AfterClass; import org.junit.BeforeClass; import org.junit.Rule; import org.junit.Test; @@ -33,6 +35,11 @@ import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.http.converter.HttpMessageConverter; +import org.springframework.jdbc.core.JdbcOperations; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.jdbc.datasource.embedded.EmbeddedDatabase; +import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder; +import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType; import org.springframework.mock.http.MockHttpOutputMessage; import org.springframework.mock.http.client.MockClientHttpResponse; import org.springframework.mock.web.MockHttpServletResponse; @@ -52,11 +59,7 @@ import org.springframework.security.oauth2.core.oidc.OidcClientRegistration; import org.springframework.security.oauth2.core.oidc.http.converter.OidcClientRegistrationHttpMessageConverter; import org.springframework.security.oauth2.jose.TestJwks; import org.springframework.security.oauth2.jose.jws.SignatureAlgorithm; -import org.springframework.security.oauth2.server.authorization.InMemoryOAuth2AuthorizationConsentService; -import org.springframework.security.oauth2.server.authorization.InMemoryOAuth2AuthorizationService; -import org.springframework.security.oauth2.server.authorization.OAuth2AuthorizationConsentService; -import org.springframework.security.oauth2.server.authorization.OAuth2AuthorizationService; -import org.springframework.security.oauth2.server.authorization.client.InMemoryRegisteredClientRepository; +import org.springframework.security.oauth2.server.authorization.client.JdbcRegisteredClientRepository; import org.springframework.security.oauth2.server.authorization.client.RegisteredClient; import org.springframework.security.oauth2.server.authorization.client.RegisteredClientRepository; import org.springframework.security.oauth2.server.authorization.client.TestRegisteredClients; @@ -83,6 +86,7 @@ public class OidcClientRegistrationTests { new OAuth2AccessTokenResponseHttpMessageConverter(); private static final HttpMessageConverter clientRegistrationHttpMessageConverter = new OidcClientRegistrationHttpMessageConverter(); + private static EmbeddedDatabase db; private static JWKSource jwkSource; @Rule @@ -92,15 +96,33 @@ public class OidcClientRegistrationTests { private MockMvc mvc; @Autowired - private RegisteredClientRepository registeredClientRepository; + private JdbcOperations jdbcOperations; @Autowired - private OAuth2AuthorizationService authorizationService; + private RegisteredClientRepository registeredClientRepository; @BeforeClass public static void init() { JWKSet jwkSet = new JWKSet(TestJwks.DEFAULT_RSA_JWK); jwkSource = (jwkSelector, securityContext) -> jwkSelector.select(jwkSet); + db = new EmbeddedDatabaseBuilder() + .generateUniqueName(true) + .setType(EmbeddedDatabaseType.HSQL) + .setScriptEncoding("UTF-8") + .addScript("org/springframework/security/oauth2/server/authorization/oauth2-authorization-schema.sql") + .addScript("org/springframework/security/oauth2/server/authorization/client/oauth2-registered-client-schema.sql") + .build(); + } + + @After + public void tearDown() { + jdbcOperations.update("truncate table oauth2_authorization"); + jdbcOperations.update("truncate table oauth2_registered_client"); + } + + @AfterClass + public static void destroy() { + db.shutdown(); } @Test @@ -204,25 +226,16 @@ public class OidcClientRegistrationTests { static class AuthorizationServerConfiguration { @Bean - OAuth2AuthorizationService authorizationService() { - return new InMemoryOAuth2AuthorizationService(); + RegisteredClientRepository registeredClientRepository(JdbcOperations jdbcOperations) { + RegisteredClient registeredClient = TestRegisteredClients.registeredClient().build(); + JdbcRegisteredClientRepository registeredClientRepository = new JdbcRegisteredClientRepository(jdbcOperations); + registeredClientRepository.save(registeredClient); + return registeredClientRepository; } @Bean - OAuth2AuthorizationConsentService authorizationConsentService() { - return new InMemoryOAuth2AuthorizationConsentService(); - } - - @Bean - RegisteredClientRepository registeredClientRepository() { - // @formatter:off - RegisteredClient dummyClient = TestRegisteredClients.registeredClient() - .id("dummy-client") - .clientId("dummy-client") - .clientSecret("dummy-secret") - .build(); - // @formatter:on - return new InMemoryRegisteredClientRepository(dummyClient); + JdbcOperations jdbcOperations() { + return new JdbcTemplate(db); } @Bean diff --git a/oauth2-authorization-server/src/test/java/org/springframework/security/config/annotation/web/configurers/oauth2/server/authorization/OidcTests.java b/oauth2-authorization-server/src/test/java/org/springframework/security/config/annotation/web/configurers/oauth2/server/authorization/OidcTests.java index 88db0de7..ac35d71f 100644 --- a/oauth2-authorization-server/src/test/java/org/springframework/security/config/annotation/web/configurers/oauth2/server/authorization/OidcTests.java +++ b/oauth2-authorization-server/src/test/java/org/springframework/security/config/annotation/web/configurers/oauth2/server/authorization/OidcTests.java @@ -28,6 +28,8 @@ import java.util.stream.Collectors; import com.nimbusds.jose.jwk.JWKSet; import com.nimbusds.jose.jwk.source.JWKSource; import com.nimbusds.jose.proc.SecurityContext; +import org.junit.After; +import org.junit.AfterClass; import org.junit.BeforeClass; import org.junit.Rule; import org.junit.Test; @@ -38,8 +40,14 @@ import org.springframework.context.annotation.Import; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.http.converter.HttpMessageConverter; +import org.springframework.jdbc.core.JdbcOperations; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.jdbc.datasource.embedded.EmbeddedDatabase; +import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder; +import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType; import org.springframework.mock.http.client.MockClientHttpResponse; import org.springframework.mock.web.MockHttpServletResponse; +import org.springframework.security.authentication.TestingAuthenticationToken; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.OAuth2AuthorizationServerConfiguration; import org.springframework.security.config.test.SpringTestRule; @@ -58,19 +66,18 @@ import org.springframework.security.oauth2.core.oidc.endpoint.OidcParameterNames import org.springframework.security.oauth2.jose.TestJwks; import org.springframework.security.oauth2.jwt.Jwt; import org.springframework.security.oauth2.jwt.JwtDecoder; -import org.springframework.security.oauth2.server.authorization.InMemoryOAuth2AuthorizationConsentService; -import org.springframework.security.oauth2.server.authorization.InMemoryOAuth2AuthorizationService; +import org.springframework.security.oauth2.server.authorization.JdbcOAuth2AuthorizationService; import org.springframework.security.oauth2.server.authorization.JwtEncodingContext; import org.springframework.security.oauth2.server.authorization.OAuth2Authorization; import org.springframework.security.oauth2.server.authorization.OAuth2AuthorizationCode; -import org.springframework.security.oauth2.server.authorization.OAuth2AuthorizationConsentService; import org.springframework.security.oauth2.server.authorization.OAuth2AuthorizationService; import org.springframework.security.oauth2.server.authorization.OAuth2TokenCustomizer; -import org.springframework.security.oauth2.server.authorization.client.InMemoryRegisteredClientRepository; +import org.springframework.security.oauth2.server.authorization.client.JdbcRegisteredClientRepository; import org.springframework.security.oauth2.server.authorization.client.RegisteredClient; import org.springframework.security.oauth2.server.authorization.client.RegisteredClientRepository; import org.springframework.security.oauth2.server.authorization.client.TestRegisteredClients; import org.springframework.security.oauth2.server.authorization.config.ProviderSettings; +import org.springframework.security.oauth2.server.authorization.jackson2.TestingAuthenticationTokenMixin; import org.springframework.security.oauth2.server.authorization.oidc.web.OidcProviderConfigurationEndpointFilter; import org.springframework.security.oauth2.server.authorization.web.OAuth2AuthorizationEndpointFilter; import org.springframework.security.oauth2.server.authorization.web.OAuth2TokenEndpointFilter; @@ -101,6 +108,7 @@ public class OidcTests { private static final String ISSUER_URL = "https://example.com/issuer1"; private static final String AUTHORITIES_CLAIM = "authorities"; private static final OAuth2TokenType AUTHORIZATION_CODE_TOKEN_TYPE = new OAuth2TokenType(OAuth2ParameterNames.CODE); + private static EmbeddedDatabase db; private static JWKSource jwkSource; private static HttpMessageConverter accessTokenHttpResponseConverter = new OAuth2AccessTokenResponseHttpMessageConverter(); @@ -111,6 +119,9 @@ public class OidcTests { @Autowired private MockMvc mvc; + @Autowired + private JdbcOperations jdbcOperations; + @Autowired private RegisteredClientRepository registeredClientRepository; @@ -124,6 +135,26 @@ public class OidcTests { public static void init() { JWKSet jwkSet = new JWKSet(TestJwks.DEFAULT_RSA_JWK); jwkSource = (jwkSelector, securityContext) -> jwkSelector.select(jwkSet); + db = new EmbeddedDatabaseBuilder() + .generateUniqueName(true) + .setType(EmbeddedDatabaseType.HSQL) + .setScriptEncoding("UTF-8") + .addScript("org/springframework/security/oauth2/server/authorization/oauth2-authorization-schema.sql") + .addScript("org/springframework/security/oauth2/server/authorization/client/oauth2-registered-client-schema.sql") + .build(); + } + + @After + public void tearDown() { + if (jdbcOperations != null) { + jdbcOperations.update("truncate table oauth2_authorization"); + jdbcOperations.update("truncate table oauth2_registered_client"); + } + } + + @AfterClass + public static void destroy() { + db.shutdown(); } @Test @@ -236,25 +267,21 @@ public class OidcTests { static class AuthorizationServerConfiguration { @Bean - OAuth2AuthorizationService authorizationService() { - return new InMemoryOAuth2AuthorizationService(); + OAuth2AuthorizationService authorizationService(JdbcOperations jdbcOperations, RegisteredClientRepository registeredClientRepository) { + JdbcOAuth2AuthorizationService authorizationService = new JdbcOAuth2AuthorizationService(jdbcOperations, registeredClientRepository); + authorizationService.setAuthorizationRowMapper(new RowMapper(registeredClientRepository)); + authorizationService.setAuthorizationParametersMapper(new ParametersMapper()); + return authorizationService; } @Bean - OAuth2AuthorizationConsentService authorizationConsentService() { - return new InMemoryOAuth2AuthorizationConsentService(); + RegisteredClientRepository registeredClientRepository(JdbcOperations jdbcOperations) { + return new JdbcRegisteredClientRepository(jdbcOperations); } @Bean - RegisteredClientRepository registeredClientRepository() { - // @formatter:off - RegisteredClient dummyClient = TestRegisteredClients.registeredClient() - .id("dummy-client") - .clientId("dummy-client") - .clientSecret("dummy-secret") - .build(); - // @formatter:on - return new InMemoryRegisteredClientRepository(dummyClient); + JdbcOperations jdbcOperations() { + return new JdbcTemplate(db); } @Bean @@ -280,6 +307,24 @@ public class OidcTests { return NoOpPasswordEncoder.getInstance(); } + static class RowMapper extends JdbcOAuth2AuthorizationService.OAuth2AuthorizationRowMapper { + + RowMapper(RegisteredClientRepository registeredClientRepository) { + super(registeredClientRepository); + getObjectMapper().addMixIn(TestingAuthenticationToken.class, TestingAuthenticationTokenMixin.class); + } + + } + + static class ParametersMapper extends JdbcOAuth2AuthorizationService.OAuth2AuthorizationParametersMapper { + + ParametersMapper() { + super(); + getObjectMapper().addMixIn(TestingAuthenticationToken.class, TestingAuthenticationTokenMixin.class); + } + + } + } @EnableWebSecurity