7

I have followed the spring boot security tutorial but the end result has an issue consisting in that after successful login the browser is redirect to /undefined.

I have even cloned the code referenced in the tutorial, thinking I have typed something wrong, or forgot to add a component or something. No, the same issue is there.

Searching on Stackoverflow I found out that you need to define the default success URL in the configure method of the WebSecurityConfigurerAdapter like so:

.defaultSuccessUrl("/")

but still no go. Accessing a protected resource leads to the login page and upon successful login I don't get redirected to the protected resource. I get to the '/undefined' page. Forcing the success works, however:

.defaultSuccessUrl("/", true)

... but this is not what I would need because after successful login the user should be redirected to secured resource (initially) requested.


Here's the relevant parts of the project:

WebSecurityConfig:

package ro.rinea.andrei.Security;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
                .antMatchers("/").permitAll()
                .anyRequest().authenticated()
                .and()
            .formLogin()
                .loginPage("/login")
                .defaultSuccessUrl("/")
                .permitAll()
                .and()
            .logout()
                .permitAll();
    }

    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        auth.inMemoryAuthentication()
            .withUser("user").password("password").roles("USER");
    }
}

Controller:

package ro.rinea.andrei.Controllers;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
public class WebController {

    @RequestMapping("/")
    public String index() {
        return "index";
    }

    @RequestMapping("/salut")
    public String salut() {
        return "salut";
    }

    @RequestMapping("/login")
    public String login() {
        return "login";
    }
}

There are views defined for index, login and salut (if needed I will add their contents)

and the build.gradle file:

buildscript {
    ext {
        springBootVersion = '1.4.0.RELEASE'
    }
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
    }
}

apply plugin: 'java'
apply plugin: 'idea'
apply plugin: 'spring-boot'

jar {
    baseName = 'tstBut'
    version = '0.0.1-SNAPSHOT'
}
sourceCompatibility = 1.8
targetCompatibility = 1.8

repositories {
    mavenCentral()
}


dependencies {
    compile('org.springframework.boot:spring-boot-devtools')
    compile('org.springframework.boot:spring-boot-starter-jdbc')
    compile('org.springframework.boot:spring-boot-starter-jersey')
    compile('org.springframework.boot:spring-boot-starter-mobile')
    compile('org.springframework.boot:spring-boot-starter-thymeleaf')
    compile('org.springframework.boot:spring-boot-starter-validation')
    compile('org.springframework.boot:spring-boot-starter-web')
    compile('org.springframework.boot:spring-boot-starter-web-services')
    compile('org.springframework.boot:spring-boot-starter-security')
    runtime('org.postgresql:postgresql')
    testCompile('org.springframework.boot:spring-boot-starter-test')
    testCompile('org.springframework.restdocs:spring-restdocs-mockmvc')
}
2
  • Have you found an answer to your issue? If yes please accept the answer that helped you so other people (e.g. me) can find a solution. Commented Jun 25, 2018 at 19:14
  • Why isn't there an answer to the question? just work arounds! Commented Oct 30, 2023 at 7:14

3 Answers 3

18

You can add a successHandler to redirect like this:

private RedirectStrategy redirectStrategy = new DefaultRedirectStrategy();
   ...
   .formLogin()
   .loginPage("/login")
   .successHandler(new AuthenticationSuccessHandler() {
    @Override
    public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,
            Authentication authentication) throws IOException, ServletException {
        redirectStrategy.sendRedirect(request, response, "/");
    }
})
Sign up to request clarification or add additional context in comments.

Comments

2

I had the same issue and this is a workaround that I used. First have a mapping for your root "/" that is unprotected

@RequestMapping(value = { "/" }, method = RequestMethod.GET)
public ModelAndView projectBase() {
    return new ModelAndView("redirect:/home");
}

Have it redirect to where you want the user to go initially like home for example

@RequestMapping(value = { "/home" }, method = RequestMethod.GET)
public ModelAndView getHome() {
    ModelAndView model = new ModelAndView("account/home");
    model.addObject("user", userFacade.getJsonForUser(userFacade.getUserForClient()));
    return model;
}

Make sure the root url is open in your security configuration like...

 http.
    authorizeRequests()
    .antMatchers("/").permitAll()

What will happen is now it will hit the root /, and redirect to home which is restricted and send them to the loginpage with a return url of home. it will then write correctly as /home when they first login

For some reason spring security is not respecting the default success url, and it could be a configuration issue with your web server causing it. On my local machine I don't have this issue, but on some other machines I do. The workaround works in both places, since you always end up with a returnUrl.

Comments

0

2024 method

Use defaultSuccessUrl to redirect users after successfull login. You could add a second argument (boolean alwaysUse), but I would not recommand it, it will always redirect users after success login.

.formLogin((form) -> form
    .loginPage("/login")
    .defaultSuccessUrl("/home")
    .permitAll())
.logout((logout) -> logout.permitAll());

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.