SpringSecurity(十):全局AuthenticationManager與局部AuthenticationManager


在之前的分析中我們已經知道了Spring Security是由AuthenticationManager(ProviderManager)把認證請求分發給多個認證器。

在Spring Security中存在全局AuthenticationManager與局部AuthenticationManager兩種

我們先來看下面代碼:

public class SecurityConfig extends WebSecurityConfigurerAdapter{
@Override
protected void configure(HttpSecurity http) throws Exception{

//簡單定義一個基於內存的UserDetailsService實例 作為示范
InMemoryUserDetailsManager users=new InMemoryUserDetailsManager();
users.createUser(User.withUsername("javaboy").password("{noop}123456").roles("admin").build());

http.authorizeRequests()
.anyRequest().authenticated()
.and()
.formLogin()
.permitAll()
.and()
.userDetailsService(users)
.csrf().disable();
}
}

此時我們雖然配置了UserDetailsService,但是我們發現使用 Spring Security生成的用戶 仍能登錄!

原因很簡單,因為此時我們注冊的是一個局部AuthenticationManager,系統仍會生成一個全局AuthenticationManager(AuthenticationConfiguration的getAuthenticationManager方法),全局AuthenticationManager會從Spring容器中尋找UserDetailsService實例,由於我們也沒有往容器中注入UserDetailsService實例,因此會使用系統提供的實例!

雖然在實際使用中對我們沒有太大的影響,因為Spring Security會先使用局部AuthenticationManager進行認證,再使用全局AuthenticationManager進行認證。但如果我們想要直接修改全局AuthenticationManager的話,有兩種思路:

(一)直接生成全局AuthenticationManager

(二)往Spring容器中注入UserDetailsService實例

先說第一種,生成全局AuthenticationManager只需要重寫configure(AuthenticationManagerBuilder auth)方法

@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter{
@Autowired
UserDateService userDateService;

//注意是參數為AuthenticationManagerBuilder的configure方法
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception{
auth.userDetailsService(userDateService);

}
....

}

往Spring容器中注入UserDetailsService實例更簡單,只需要加一個@Bean注解即可!

需要注意的是,一旦我們重寫了configure(AuthenticationManagerBuilder auth)方法,則使用的UserDetailsService實例 則是 方法中注入的實例,此時容器中的UserDetailsService實例將不起作用!(AuthenticationConfiguration的getAuthenticationManager方法沒有被調用!)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM