[英]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.