Home > Software engineering >  Spring Boot - Issues redirecting to external URL with AuthenticationSuccessHandler
Spring Boot - Issues redirecting to external URL with AuthenticationSuccessHandler

Time:11-05

I am using Spring Boot for the first time to setup a user login system for a REACT web-app. As of now I am trying to redirect the user to another page in my REACT-app after a successful authentication. I am using a custom AuthenticationSuccessHandler to handle the actual redirection.

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        CustomAuthenticationFilter customAuthenticationFilter = new CustomAuthenticationFilter(authenticationManagerBean());
        customAuthenticationFilter.setFilterProcessesUrl("/api/v*/login/**");
        http.cors().configurationSource(request -> new CorsConfiguration().applyPermitDefaultValues());
        http.csrf().disable();
        http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
        http.authorizeRequests().antMatchers("/api/v*/login/**").permitAll();
        http.authorizeRequests().antMatchers(HttpMethod.GET, "api/v*/users/**").hasAnyAuthority("PRODUCER");
        http.authorizeRequests().antMatchers("/api/v*/registration/**").permitAll();
        http.authorizeRequests().anyRequest().authenticated();
        http.formLogin().loginPage("http://localhost:3000/login").successHandler(myAuthenticationSuccessHandler());
 @Bean
    public AuthenticationSuccessHandler myAuthenticationSuccessHandler(){
        return new RedirectLoginSuccessHandler();
    }
public class RedirectLoginSuccessHandler implements AuthenticationSuccessHandler {

    @Override
    public void onAuthenticationSuccess(HttpServletRequest httpServletRequest,
                                        HttpServletResponse httpServletResponse,
                                        Authentication authentication) throws IOException {

        httpServletResponse.sendRedirect("http://localhost:3000");
    }

}

The API runs on port :8080 and the react login form runs on :3000/login, authentication is done by sending a POST-request to localhost:8080/api/v1/login (getting a JWT access token in return), after that is attempted I want the user to get redirected to the homepage at localhost:3000, but the redirect is being ignored unless I use the login form that you get from Spring with the loginForm() method.

I also tried sending a redirect along with the JWT token as a response to the POST-request to api/v1/login, but ran into problems with CORS doing that. What am I doing wrong here? The tutorials i've seen on redirecting after successful authentication refer to html files such as home.html to redirect, and I am assuming they are able to do this by having bundled together the REACT and Spring boot project into one mono-repository.

Cors issues

CodePudding user response:

Maybe try something like this ...

@EnableWebSecurity
public class SecSecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(final HttpSecurity http) throws Exception {
        http
            .authorizeRequests()
            // ... endpoints
            .formLogin()
                ... config
                .defaultSuccessUrl("http://localhost:3000l", true)
            // ... other configuration       
    }
}

CodePudding user response:

With formLogin, Spring Security basically provides you these steps (simplified):

  1. When you call an API need to authenticate the user, if AccessDeniedException happens, a AuthenticationEntryPoint will redirect you to formLogin().loginPage("http://localhost:3000/login").
  2. After the user fill out the username and the password, you need to POST them to formLogin().loginProcessingUrl("/login123") (default value if you don't specicify should be "/login").
  3. The UsernamePasswordAuthenticationFilter, after that, bases on the matcher on "/login123" will intercept your POST, and validate your user with username and password.
  4. If they are validated successfully, your .successHandler(myAuthenticationSuccessHandler()) will be called to do its job.

...


Here, because

authentication is done by sending a POST-request to localhost:8080/api/v1/login (getting a JWT access token in return)

You didn't follow the flow from step 2 (you didn't POST username/password to "/login123"), you couldn't get features supported by Spring Security after that (this.rememberMeServices.loginSuccess, this.successHandler.onAuthenticationSuccess,... for example).


For your case, after you get JWT from a POST-request to localhost:8080/api/v1/login, you could redirect by yourself, you don't need to depend on .successHandler(myAuthenticationSuccessHandler()).

  • Related