Spring MVC应用登录后异常重定向问题求助
Hey there, let's tackle that odd redirect behavior you're seeing with Spring Security in your Spring MVC app. It's super frustrating when the first login doesn't land on your homepage, but subsequent logins work fine—let's break down the most likely fixes:
1. Fix the defaultSuccessUrl Configuration (Most Common Cause)
The issue often boils down to how Spring Security handles the default success redirect when there's no "saved request" (i.e., the user didn't try to access a protected resource before logging in).
- By default,
defaultSuccessUrl("/your-homepage")only redirects to your homepage if the user was sent to the login page because they tried to access a secured resource. If the user navigates directly to the login page and logs in, Spring Security will default to redirecting to the application context root instead. - The fix is to add
alwaysUse = trueto yourdefaultSuccessUrlcall. This forces Spring Security to use your specified homepage as the redirect target every time login succeeds, regardless of how the user got to the login page:
@Override protected void configure(HttpSecurity http) throws Exception { http .authorizeRequests() .anyRequest().authenticated() .and() .formLogin() .loginPage("/login") .loginProcessingUrl("${loginUrl}") // Matches your form's action .defaultSuccessUrl("/home", true) // Add alwaysUse=true here .permitAll() .and() .logout() .permitAll(); }
2. Verify Saved Request & Logout Cleanup
Sometimes, after logging out, a cached "saved request" from a previous session might stick around, which is why subsequent logins work. To ensure consistency, make sure your logout configuration properly clears the session and cookies:
.logout() .logoutUrl("/logout") .invalidateHttpSession(true) .deleteCookies("JSESSIONID") .permitAll();
This ensures that each login session starts fresh, so you can reliably test the redirect behavior without leftover session data.
3. Double-Check Your Login Form
While you mentioned the form action uses ${loginUrl}, it's worth confirming a couple of details:
- Ensure the form uses
method="POST"(Spring Security's default login processing expects POST requests). - Don't forget the CSRF token (required by default in Spring Security) to avoid silent authentication failures that might cause unexpected redirects:
<form action="${loginUrl}" method="post"> <div> <label>Username: <input type="text" name="username"/></label> </div> <div> <label>Password: <input type="password" name="password"/></label> </div> <input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}"/> <button type="submit">Login</button> </form>
4. Debug with a Custom Authentication Success Handler
If the above fixes don't work, you can create a custom handler to explicitly control the redirect logic and debug what's happening during login:
public class CustomLoginSuccessHandler implements AuthenticationSuccessHandler { @Override public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication auth) throws IOException, ServletException { // Check if there's a saved request (from accessing a protected resource) SavedRequest savedRequest = new HttpSessionRequestCache().getRequest(request, response); if (savedRequest != null) { // Redirect to the originally requested page if it exists response.sendRedirect(savedRequest.getRedirectUrl()); } else { // Otherwise, force redirect to your homepage response.sendRedirect(request.getContextPath() + "/home"); } } }
Then register this handler in your security config:
.formLogin() .loginPage("/login") .loginProcessingUrl("${loginUrl}") .successHandler(new CustomLoginSuccessHandler()) .permitAll();
This lets you see exactly whether a saved request is present during the first login vs. subsequent logins, helping you pinpoint the issue.
内容的提问来源于stack exchange,提问作者Alberto

