我們?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è)問(wèn)題,這樣的話用戶名和密碼都是定死的,我們拿不到form-data數(shù)據(jù),如果因?yàn)榍岸说膯?wèn)題,這種密碼登錄方式以外,我們還要稍微修改提交給我們的form-data中的密碼數(shù)據(jù),做一下處理,自定義一個(gè)登錄呢。
這個(gè)時(shí)候就需要用到AuthenticationProvider了。
這是一個(gè)接口,提供了兩種方法
public interface AuthenticationProvider {
Authentication authenticate(Authentication authentication)
throws AuthenticationException;
boolean supports(Class<?> authentication);
}
通過(guò)第一個(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)證通過(guò)*/) {
return new UsernamePasswordAuthenticationToken(userDetails, null,userDetails.getAuthorities());
}
/*驗(yàn)證不通過(guò)*/
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ì)這么寫(xiě)
@Override
public boolean supports(Class<?> authentication) {
return authentication.equals(UsernamePasswordAuthenticationToken.class);
}
下面就是注冊(cè)要configure方法中了
只要加入
auth.authenticationProvider(new MyAuthenticationProvider());
就好了。。