简体   繁体   中英

Trying to customize failed login with spring security

Im trying to add more information in the failure login response from Spring Security.

Here is my configuration:

@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    private final CustomAuthenticationProvider authProvider;
    private final CustomAuthEntryPoint customAuthEntryPoint;

    public SecurityConfig(CustomAuthenticationProvider authProvider, CustomAuthEntryPoint customAuthEntryPoint) {
        this.authProvider = authProvider;
        this.customAuthEntryPoint = customAuthEntryPoint;
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.authenticationProvider(authProvider);
    }

   @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .cors().and()
            .logout().deleteCookies("SESSION").and()
            .authorizeRequests()
                .antMatchers("/actuator/**").permitAll()
                .anyRequest().authenticated().and()         
            .httpBasic().authenticationEntryPoint(customAuthEntryPoint).and()
            .csrf().disable();
    }
}
@Component
public class CustomAuthEntryPoint implements AuthenticationEntryPoint {
    @Override
    public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) throws IOException, ServletException {
        System.out.println("entrypoint " + exception.getClass().getName());
        response.getOutputStream().print(exception.getClass().getName());
        response.sendError(401, exception.getClass().getName());
    }
}

When I try to login, it goes a first time in the custom entry point with the good exception ( BadCredentialsException ) but next I think Spring tries a request to /error and then it goes back in the entrypoint with InsufficientAuthenticationException (from ExceptionTranslationFilter.sendStartAuthentication ).

And In the response I have a 401 without any body, even the exception classname as defined in the entrypoint.

Any idea what is wrong with the configuration?

You are right, spring tries to redirect to "/error", because you called response.sendError in your CustomAuthEntryPoint and tries to authenticate again, thus you get another InsufficentAuthentication exception. One way to solve this is to use response.setStatus(401) instead of the response.sendError method. Like so:

@Component
public class CustomAuthEntryPoint implements AuthenticationEntryPoint {
  @Override
  public void commence(HttpServletRequest request, HttpServletResponse response,
      AuthenticationException exception) throws IOException, ServletException {
    System.out.println("entrypoint " + exception.getClass().getName());
    response.getOutputStream().print(exception.getClass().getName());
    response.setStatus(401);
  }
}

Alternatively, you could exclude "/error" url from authorization, but you have to be careful not to leak sensitive information on that error endpoint:

@Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .cors().and()
            .logout().deleteCookies("SESSION").and()
            .authorizeRequests()
                .antMatchers("/actuator/**","/error").permitAll()
                .anyRequest().authenticated().and()         
            .httpBasic().authenticationEntryPoint(customAuthEntryPoint).and()
            .csrf().disable();
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM