spring-security 使用AuthenticationProvider配置自定义登录选项

我们在使用spring sec的时候,一般会继承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());
  }

一般而言登录的数据我们在protected void configure(AuthenticationManagerBuilder auth)中,我们在studentService中配置一个

  @Override
  public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
    Student student = studentRepository.findByStudentId(username)
                                       .orElseThrow(() -> new UsernameNotFoundException("Not found: " + username));
    return new StudentDetails(student);
  }

方法就好。

但是遇到一个问题,这样的话用户名和密码都是定死的,我们拿不到form-data数据,如果因为前端的问题,这种密码登录方式以外,我们还要稍微修改提交给我们的form-data中的密码数据,做一下处理,自定义一个登录呢。

这个时候就需要用到AuthenticationProvider了。
这是一个接口,提供了两种方法


public interface AuthenticationProvider {
  
  Authentication authenticate(Authentication authentication)
          throws AuthenticationException;

  boolean supports(Class authentication);
}

通过第一个方法我们可以拿到form-data的数据,并且返回一个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 (/*自定义的验证通过*/) {
            return new UsernamePasswordAuthenticationToken(userDetails, null,userDetails.getAuthorities());
        }
        /*验证不通过*/
        return null;

第二个方法是告诉spring sec我们这个验证支持哪种验证。
你可能疑惑这个还分?
其实是这样。

 auth.userDetailsService(studentService).passwordEncoder(encoder);

这种严重属于Dao验证。

还有UsernamePasswordAuthentication验证。
我们的是UsernamePassword的验证方式,所以在第二个方法中一般会这么写

   @Override
    public boolean supports(Class authentication) {
        return authentication.equals(UsernamePasswordAuthenticationToken.class);
    }

下面就是注册要configure方法中了
只要加入

auth.authenticationProvider(new MyAuthenticationProvider());

就好了。。

你可能感兴趣的:(spring-security 使用AuthenticationProvider配置自定义登录选项)