在Spring Security with Hibernate中使用jdbcAuthentication

时间:2014-03-30 20:56:37

标签: spring hibernate spring-mvc jdbc spring-security

我刚刚完成了一个基于inMemoryAuthentication()的Spring应用程序,现在,在验证完所有工作完成之后,我想使用JDBC身份验证。

我有三种类来处理与数据库的连接:

  1. HibernateConfig,基于此博客文章中提供的代码。

  2. DAO和Entity类,我的数据库中每个表一个(在当前状态下,我有三个:User,Role和User_Role)

  3. UserService类,实现UserDetailsService

  4. 我在互联网上阅读了一些文章,实际上所有这些文章都使用SecurityConfig类的以下配置:

    public class SecurityConfig extends WebSecurityConfigurerAdapter {
    
        @Autowired
        private DataSource dataSource;
    
        @Autowired
        public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
            auth
              .jdbcAuthentication()
                  .dataSource(dataSource)
                  .usersByUsernameQuery(getUserQuery())
                  .authoritiesByUsernameQuery(getAuthoritiesQuery());
        }
    

    对我来说有什么问题,因为我的项目中没有Datasource类。我目前的SecurityConfig是这样的:

    @Configuration
    @EnableWebSecurity
    public class SecurityConfig extends WebSecurityConfigurerAdapter {
    
        @Autowired
        public void configure(AuthenticationManagerBuilder auth) throws Exception {
            auth
                .jdbcAuthentication()
                .usersByUsernameQuery(getUserQuery())
                .authoritiesByUsernameQuery(getAuthoritiesQuery());
        }
    
        protected void configure(HttpSecurity http) throws Exception {
            http
                .csrf()
                    .disable()
                .authorizeRequests()
                    .antMatchers("/css/**", "/fonts/**", "/image/**", "/js/**").permitAll()
                    .anyRequest().authenticated()
                    .and()
                .formLogin()
                    .loginPage("/spring/index").permitAll()
                    .loginProcessingUrl("/spring/login").permitAll()
                    .usernameParameter("login")
                    .passwordParameter("senha")
                    .successHandler(new CustomAuthenticationSuccessHandler())
                    .failureHandler(new CustomAuthenticationFailureHandler())
                    .and()
                .logout()
                    .logoutUrl("/spring/logout")
                    .logoutSuccessUrl("/spring/index").permitAll();
        }
    
        private String getUserQuery() {
            return "SELECT login as username, senha as password "
                    + "FROM usuario "
                    + "WHERE login = ?";
        }
    
        private String getAuthoritiesQuery() {
            return "SELECT DISTINCT usuario.login as username, autorizacao.descricao as authority "
                    + "FROM usuario, autorizacao_usuario, autorizacao "
                    + "WHERE usuario.id = autorizacao_usuario.fk_usuario "
                    + "AND autorizacao.id = autorizacao_usuario.fk_autorizacao "
                    + "AND usuario.login = ? ";
        }
    
    }
    

    正如您所看到的,我已经对使用JDBC身份验证做了一些调整,但我仍然缺少将此类链接到Hibernate类的部分。

    有人对如何制作这个有什么建议吗?

    我的HibernateConfig就是这个

    @Configuration
    @EnableTransactionManagement
    @PropertySource({ "classpath:persistence.properties" })
    @ComponentScan({ "org.webapp.persistence" })
    public class HibernateConfig {
    
       @Autowired
       private Environment env;
    
       @Bean
       public LocalSessionFactoryBean sessionFactory() {
          LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean();
          sessionFactory.setDataSource(restDataSource());
          sessionFactory.setPackagesToScan(new String[] { "org.webapp.persistence.model" });
          sessionFactory.setHibernateProperties(hibernateProperties());
    
          return sessionFactory;
       }
    
       @Bean
       public DataSource restDataSource() {
          BasicDataSource dataSource = new BasicDataSource();
          dataSource.setDriverClassName(env.getProperty("jdbc.driverClassname"));
          dataSource.setUrl(env.getProperty("jdbc.url"));
          dataSource.setUsername(env.getProperty("jdbc.user"));
          dataSource.setPassword(env.getProperty("jdbc.pass"));
    
          return dataSource;
       }
    
       @Bean
       @Autowired
       public HibernateTransactionManager transactionManager(SessionFactory sessionFactory) {
          HibernateTransactionManager txManager = new HibernateTransactionManager();
          txManager.setSessionFactory(sessionFactory);
    
          return txManager;
       }
    
       @Bean
       public PersistenceExceptionTranslationPostProcessor exceptionTranslation() {
          return new PersistenceExceptionTranslationPostProcessor();
       }
    
       Properties hibernateProperties() {
          return new Properties() {
             /**
             * 
             */
            private static final long serialVersionUID = 1L;
    
            {
                setProperty("hibernate.hbm2ddl.auto", env.getProperty("hibernate.hbm2ddl.auto"));
                setProperty("hibernate.dialect", env.getProperty("hibernate.dialect"));
                setProperty("hibernate.globally_quoted_identifiers", "true");
             }
          };
       }
    }
    

1 个答案:

答案 0 :(得分:13)

好的,我解决了。我需要做的就是在我的班级SecurityConfig中插入以下注释:

@ComponentScan(value="org.webapp")

现在,我可以在此课程中自动DataSource

@Autowired
private DataSource restDataSource;

@Autowired
public void configure(AuthenticationManagerBuilder auth) throws Exception {
    auth
        .jdbcAuthentication()
        .dataSource(restDataSource)
        .usersByUsernameQuery(getUserQuery())
        .authoritiesByUsernameQuery(getAuthoritiesQuery());
}