I\'ve been tearing my hair out with what should be a pretty common use case for a web application. I have a Spring-Boot application which uses REST Repositories, JPA, etc. The
Your problem is with the authentication manager configuration. All the samples and guides set this up in a GlobalAuthenticationConfigurerAdapter
, e.g. it would look like this as an inner class of your SimpleEmbeddedSecurityConfiguration
:
@Configuration
public static class AuthenticationConfiguration extends GlobalAuthenticationConfigurerAdapter
{
@Bean(name = Global.AUTHENTICATION_DATA_QUALIFIER + "DataSource")
public DataSource dataSource()
{
return new EmbeddedDatabaseBuilder().setName("authdb").setType(EmbeddedDatabaseType.H2).addScripts("security/schema.sql", "security/data.sql").build();
}
@Override
public void init(AuthenticationManagerBuilder auth) throws Exception
{
auth.jdbcAuthentication().dataSource(dataSource()).passwordEncoder(passwordEncoder());
}
}
If you don't use GlobalAuthenticationConfigurerAdapter
then the DataSource
gets picked up by Spring Data REST during the creation of the Security filters (before the @Primary
DataSource
bean has even been registered) and the whole JPA initialization starts super early (bad idea).
UPDATE: the authentication manager is not the only problem. If you need to have a session-scoped @Primary
DataSource
(pretty unusual I'd say), you need to switch off everything that wants access to the database on startup (Hibernate and Spring Boot in various places). Example:
spring.datasource.initialize: false
spring.jpa.hibernate.ddlAuto: none
spring.jpa.properties.hibernate.temp.use_jdbc_metadata_defaults: false
spring.jpa.properties.hibernate.dialect: H2
FURTHER UPDATE: if you're using the Actuator it also wants to use the primary data source on startup for a health indicator. You can override that by prividing a bean of the same type, e.g.
@Bean
@Scope(value="session", proxyMode=ScopedProxyMode.TARGET_CLASS)
@Lazy
public DataSourcePublicMetrics dataSourcePublicMetrics() {
return new DataSourcePublicMetrics();
}
P.S. I believe the GlobalAuthenticationConfigurerAdapter
might not be necessary in Spring Boot 1.2.2, but it is in 1.2.1 or 1.1.10.