我們?cè)谑褂?code>spring sec的時(shí)候,一般會(huì)繼承WebSecurityConfigurerAdapter
類妖胀,然后選擇覆蓋protected void configure(AuthenticationManagerBuilder auth)
和protected void configure(HttpSecurity http)
方法
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(studentService).passwordEncoder(encoder);
auth.userDetailsService(teacherService).passwordEncoder(encoder);
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable()
.authorizeRequests()
.antMatchers("/**").authenticated()
.and()
.formLogin().loginPage("/login").permitAll()
.successHandler(new MySavedRequestAwareAuthenticationSuccessHandler())
.failureHandler(new SimpleUrlAuthenticationFailureHandler())
.and()
.logout().logoutSuccessHandler(new HttpStatusReturningLogoutSuccessHandler(HttpStatus.OK))
.and()
.exceptionHandling().authenticationEntryPoint(new Http401AuthenticationEntryPoint("login first"))
.accessDeniedHandler(new AccessDeniedHandlerImpl());
}
一般而言登錄的數(shù)據(jù)我們?cè)?code>protected void configure(AuthenticationManagerBuilder auth)中聚蝶,我們?cè)?code>studentService中配置一個(gè)
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
Student student = studentRepository.findByStudentId(username)
.orElseThrow(() -> new UsernameNotFoundException("Not found: " + username));
return new StudentDetails(student);
}
方法就好嘹叫。
但是遇到一個(gè)問題蓬痒,這樣的話用戶名和密碼都是定死的,我們拿不到form-data
數(shù)據(jù)闯睹,如果因?yàn)榍岸说膯栴}戏羽,這種密碼登錄方式以外,我們還要稍微修改提交給我們的form-data
中的密碼數(shù)據(jù)瞻坝,做一下處理蛛壳,自定義一個(gè)登錄呢。
這個(gè)時(shí)候就需要用到AuthenticationProvider
了所刀。
這是一個(gè)接口,提供了兩種方法
public interface AuthenticationProvider {
Authentication authenticate(Authentication authentication)
throws AuthenticationException;
boolean supports(Class<?> authentication);
}
通過第一個(gè)方法我們可以拿到form-data
的數(shù)據(jù)捞挥,并且返回一個(gè)UserDetails
如果登錄成功的話浮创,或者返回null
如果登錄失敗。
@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
String userName = (String) authentication.getPrincipal(); //拿到username
String password = (String) authentication.getCredentials(); //拿到password
UserDetails userDetails = studentService.loadUserByUsername(userName);
if (/*自定義的驗(yàn)證通過*/) {
return new UsernamePasswordAuthenticationToken(userDetails, null,userDetails.getAuthorities());
}
/*驗(yàn)證不通過*/
return null;
第二個(gè)方法是告訴spring sec
我們這個(gè)驗(yàn)證支持哪種驗(yàn)證砌函。
你可能疑惑這個(gè)還分?
其實(shí)是這樣斩披。
auth.userDetailsService(studentService).passwordEncoder(encoder);
這種嚴(yán)重屬于Dao
驗(yàn)證。
還有UsernamePasswordAuthentication
驗(yàn)證讹俊。
我們的是UsernamePassword
的驗(yàn)證方式垦沉,所以在第二個(gè)方法中一般會(huì)這么寫
@Override
public boolean supports(Class<?> authentication) {
return authentication.equals(UsernamePasswordAuthenticationToken.class);
}
下面就是注冊(cè)要configure
方法中了
只要加入
auth.authenticationProvider(new MyAuthenticationProvider());
就好了。仍劈。