[英]how to configure both in memory authentication and jdbc authentication in spring security
我可以通过以下配置在内存身份验证中实现
@Configuration
@EnableWebSecurity
public class SpringSecurityConfig extends WebSecurityConfigurerAdapter
{
@Autowired
public void configureInMemoryAuthentication(AuthenticationManagerBuilder auth) throws Exception
{
auth.inMemoryAuthentication().withUser("praveen").password("{noop}praveen@123#").roles("ADMIN");
auth.inMemoryAuthentication().withUser("vedanta").password("{noop}vedanta@123#").roles("USER");
}
@Override
protected void configure(final HttpSecurity http) throws Exception
{
http
.authorizeRequests()
.antMatchers("/resources/**", "/", "/login", "/api/**").permitAll()
.antMatchers("/app/admin/*").hasRole("ADMIN").antMatchers("/app/user/*")
.hasAnyRole("ADMIN", "USER")
.and().exceptionHandling().accessDeniedPage("/403")
.and().formLogin()
.loginPage("/login").usernameParameter("userName")
.passwordParameter("password")
.defaultSuccessUrl("/app/user/dashboard")
.failureUrl("/login?error=true")
.and().logout()
.logoutSuccessHandler(new CustomLogoutSuccessHandler())
.invalidateHttpSession(true)
.and().csrf().disable();
http.sessionManagement().maximumSessions(1).expiredUrl("/login?expired=true");
}
}
和jdbc身份验证通过以下配置(在不同的项目中)
@Configuration
@EnableWebSecurity
public class SpringSecurityConfig extends WebSecurityConfigurerAdapter
{
@Autowired
DataSource dataSource;
@Autowired
public void configureJdbcAuthentication(AuthenticationManagerBuilder auth) throws Exception
{
auth.jdbcAuthentication().dataSource(dataSource).passwordEncoder(passwordEncoder())
.usersByUsernameQuery("select username, password, enabled from userdetails where userName=?")
.authoritiesByUsernameQuery(
"select ud.username as username, rm.name as role from userdetails ud INNER JOIN rolemaster rm ON rm.id = ud.roleId where username = ?");
}
@Override
protected void configure(final HttpSecurity http) throws Exception
{
http
.authorizeRequests()
.antMatchers("/resources/**", "/", "/login")
.permitAll()
.antMatchers("/config/*", "/app/admin/*")
.hasRole("ADMIN")
.antMatchers("/app/user/*")
.hasAnyRole("ADMIN", "USER")
.antMatchers("/api/**")
.hasRole("APIUSER")
.and().exceptionHandling()
.accessDeniedPage("/403")
.and().formLogin()
.loginPage("/login")
.usernameParameter("userName").passwordParameter("password")
.defaultSuccessUrl("/app/user/dashboard")
.failureUrl("/login?error=true")
.and().logout()
.logoutSuccessHandler(new CustomLogoutSuccessHandler())
.invalidateHttpSession(true)
.and().httpBasic()
.and().csrf()
.disable();
http.sessionManagement().maximumSessions(1).expiredUrl("/login?expired=true");
}
@Bean
public PasswordEncoder passwordEncoder()
{
return new BCryptPasswordEncoder();
}
}
当我试图在同一个项目中实现两者时(我在SpringSecurityConfig中仅添加了configureInMemoryAuthentication和configureJdbcAuthentication方法,如下所示)
@Configuration
@EnableWebSecurity
public class SpringSecurityConfig extends WebSecurityConfigurerAdapter
{
...
@Autowired
public void configureInMemoryAuthentication(AuthenticationManagerBuilder auth) throws Exception
{
auth.inMemoryAuthentication()
.withUser("restapiuser")
.password("restapiuser@123#")
.roles("APIUSER");
}
@Autowired
public void configureJdbcAuthentication(AuthenticationManagerBuilder auth) throws Exception
{
auth.jdbcAuthentication().dataSource(dataSource).passwordEncoder(passwordEncoder())
.usersByUsernameQuery("select username, password, enabled from userdetails where userName=?")
.authoritiesByUsernameQuery(
"select ud.username as username, rm.name as role from userdetails ud INNER JOIN rolemaster rm ON rm.id = ud.roleId where username = ?");
}
...
}
但是我无法成功使用inMemoryAuthentication凭据登录,我已被重定向到“ / login?error = true”页面。
但是我能够使用jdbcAuthentication凭据成功登录。
但两者都无法实现。
我做错什么了吗?
是否可以结合两个身份验证?
错误的是,身份验证管理器试图解码我的普通密码并发出此警告。
WARN - Encoded password does not look like BCrypt
看到日志后,我尝试了password("{noop}restapiuser@123#")
也不起作用,可能是因为jdbcAuthentication已为passwordEncoder注册,身份验证管理器每次都会尝试解密/解码密码。 因此,无需跳过密码解码即可提供编码后的密码。
由于我未保留编码后的密码,因此它尝试对其进行解码并重定向到failureUrl。
参考解决方案
@Autowired
public void configureInMemoryAuthentication(AuthenticationManagerBuilder auth) throws Exception
{
auth.inMemoryAuthentication()
.withUser("restapiuser")
.password(new BCryptPasswordEncoder().encode("restapiuser@123#"))
.roles("APIUSER");
}
或者,最佳做法是保留编码密码而不是普通密码
.password("$2a$10$GRoNCbeVoBYMcZH7QLX2O.wWxkMtB4qiBY8y.XzvRN/mvktS9GWc6")
另类。 只有一种configureAuthentication方法,但同时在内存和jdbc身份验证中进行如下配置
@Autowired
public void configureBothAuthentication(AuthenticationManagerBuilder auth) throws Exception
{
auth.inMemoryAuthentication()
.withUser("restapiuser")
.password(new BCryptPasswordEncoder().encode("restapiuser@123#"))
.roles("ADMIN");
auth.jdbcAuthentication().dataSource(dataSource).passwordEncoder(passwordEncoder())
.usersByUsernameQuery("select username, password, enabled from userdetails where userName=?")
.authoritiesByUsernameQuery(
"select ud.username as username, rm.name as role from userdetails ud INNER JOIN rolemaster rm ON rm.id = ud.roleId where username = ?");
}
所以,
在Spring项目中可以同时实现InMemoryAuthentication和jdbcAuthentication。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.