Spring Boot with session-based data source

后端 未结 1 844
無奈伤痛
無奈伤痛 2021-01-24 12:04

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

相关标签:
1条回答
  • 2021-01-24 12:11

    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.

    0 讨论(0)
提交回复
热议问题