spring-security 使用AuthenticationProvider配置自定義登錄選項(xiàng)

我們?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());

就好了。。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容