我想用Spring-Security 4.0.0.M1與Spring-Boot 1.0.2.RELEASE與H2和Spring-data-jpa.1.5.2。我能夠在SecurityConfig.configure方法中創建一個用戶,但是當我將它提取到它自己的類中時,我得到一個空指針異常。我進入JdbcDaoSupport.java,看到getJdbcTemplate()返回一個空的jdbcTemplate。春季安全jdbc拋出空指針
這裏是我的配置:
@Configuration
@EnableWebMvcSecurity
@EnableGlobalMethodSecurity(prePostEnabled = false)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private DataSource dataSource;
@Autowired
UserService userService;
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/resources/**").permitAll()
.antMatchers("/css/**").permitAll();
http
.formLogin().failureUrl("/login?error")
.defaultSuccessUrl("/")
.loginPage("/login")
.permitAll()
.and()
.logout().logoutRequestMatcher(new AntPathRequestMatcher("/logout")).logoutSuccessUrl("/login")
.permitAll();
http
.authorizeRequests().anyRequest().authenticated();
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth
.jdbcAuthentication()
.dataSource(dataSource);
}
@Bean
@Override
public AuthenticationManager authenticationManager() throws Exception {
return super.authenticationManagerBean();
}
}
我的主要配置類有數據源定義,這是我知道的工作:
@Bean
public DataSource dataSource() {
return new EmbeddedDatabaseBuilder().setType(EmbeddedDatabaseType.H2).setName("ofac")
.addScript("classpath:h2.sql").build();
}
我有一個用戶服務添加用戶這樣:
@Component
public class UserService {
@Autowired
private AuthenticationManagerBuilder authenticationManagerBuilder;
@Autowired
private javax.sql.DataSource dataSource;
@PostConstruct()
public void initUsers() throws Exception {
addNewUser("admin", "password", "ADMIN");
}
public void addNewUser(String username, String plainPassword, String role) {
List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
authorities.add(new SimpleGrantedAuthority(role));
PasswordEncoder encoder = new BCryptPasswordEncoder();
UserDetails hashedUser = new User(username, encoder.encode(plainPassword), authorities);
JdbcUserDetailsManager userDetailsService = (JdbcUserDetailsManager) authenticationManagerBuilder.getDefaultUserDetailsService();
try {
if (userDetailsService.userExists(hashedUser.getUsername())) {
userDetailsService.deleteUser(hashedUser.getUsername());
}
// and finally, create the user
userDetailsService.createUser(hashedUser);
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
我在UserService.initUsers上有一個斷點,當行:
authenticationManagerBuilder.jdbcAuthentication().getUserDetailsService().userExists(hashedUser.getUsername())
被調用,我可以看到authenticationManagerBuilder.jdbcAuthentication()
返回一個空的jdbcTemplate。所有的在線文檔似乎都表明這會起作用,但它似乎並沒有像我期望的那樣連接所有的東西。
有誰知道什麼可能是錯的?
UPDATE: 我改變了項目,所以我不再有SecurityConfig,而是有:
@Order(SecurityProperties.ACCESS_OVERRIDE_ORDER)
@Configuration
public class ApplicationSecurity extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/resources/**").permitAll()
.antMatchers("/css/**").permitAll();
http
.formLogin().failureUrl("/login?error")
.defaultSuccessUrl("/")
.loginPage("/login")
.permitAll()
.and()
.logout().logoutRequestMatcher(new AntPathRequestMatcher("/logout")).logoutSuccessUrl("/login")
.permitAll();
http
.authorizeRequests().anyRequest().authenticated();
}
}
和:
@Order(Ordered.HIGHEST_PRECEDENCE)
@Configuration
public class AuthenticationSecurity extends GlobalAuthenticationConfigurerAdapter {
@Autowired
private DataSource dataSource;
@Override
public void init(AuthenticationManagerBuilder auth) throws Exception {
auth
.jdbcAuthentication()
.dataSource(dataSource);
}
}
但在我UserService,我在此處獲取null userDetailsService:
JdbcUserDetailsManager userDetailsService = (JdbcUserDetailsManager) authenticationManagerBuilder.getDefaultUserDetailsService();
我還沒有想出如何在啓動後實際創建用戶。我認爲這是用UserDetailsService,但是不提供這些功能。我想也許需要一個JdbcUserDetailsManager,但到目前爲止,我還沒有能夠聯繫起來。
我想如果你想在兩個地方共享用戶細節服務,你應該將它定義爲一個bean。注入auth mgr構建器不打算以這種方式工作。 –