一.背景:spring基于数据库表认证,spring实战第4版,第九章(以下是正确的配置代码,验证通过)
@Configuration
@EnableWebMvcSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private DataSource dataSource;
@Override
protected void configure(HttpSecurity http) throws Exception {
http.formLogin().loginPage("/login").and().logout().logoutSuccessUrl("/").and().rememberMe()
.tokenRepository(new InMemoryTokenRepositoryImpl()).tokenValiditySeconds(2419200).key("shopKey").and()
.httpBasic().realmName("shop").and().authorizeRequests().antMatchers("/user/myOrder").authenticated()
.anyRequest().permitAll().and().csrf().disable();
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.jdbcAuthentication().dataSource(dataSource)
.usersByUsernameQuery("select username,password,enabled from user WHERE username=?")
.authoritiesByUsernameQuery("select username,role from user where username=?");
}
}
二.出现的问题:刚开始是用的基于内存的认证,后来改成基于数据库认证,发现登录不了,无法认证。
三.思考过程:刚开始认为是DataSource没有配置成功,无法自动装配,然后自己就试着debug,结果还是没找到问题所在,接着试试junit单元测试,由于都不熟悉,所以还是没找到,接着在网上找资料,查出来的都比较复杂,大多数是基于xml配置的,而我的是基于Java类配置的。。。。。。。。接下来,试着看下源码,看下自己的方法是否用错。果然是自己sql语句没写好,里面enabled 需要一个Boolean值,自己数据库没写对。
四.注意点
1.mysql数据类型没有Boolean,用TINYINT替代,1代码true,0代码false.
2.
auth.jdbcAuthentication().dataSource(dataSource)
.usersByUsernameQuery("select username,password,enabled from user WHERE username=?")
.authoritiesByUsernameQuery("select username,role from user where username=?");
dataSource在DateConfig.java里面配置好就可以全项目用,不需要再次Important到SecurityConfig.javal里
3.
auth.jdbcAuthentication().dataSource(dataSource)
.usersByUsernameQuery("select username,password,enabled from user WHERE username=?")
.authoritiesByUsernameQuery("select username,role from user where username=?");
usersByUsernameQuery()方法里的参数一定要有一个true的查询结果,这里用的是enabled在数据库里,数据类型是TINYINT,默认值设置的1,即默认为true.
4.
auth.jdbcAuthentication().dataSource(dataSource)
.usersByUsernameQuery("select username,password,enabled from user WHERE username=?")
.authoritiesByUsernameQuery("select username,role from user where username=?");
必须要有 .authoritiesByUsernameQuery("select username,role from user where username=?")这个犯法。