You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Security双角色实现问题:登录后无法正确跳转对应页面

Hey there! Let's work through your Spring Security role-based redirect issue together. I’ve helped tons of new developers sort out exactly this problem, so let’s break down what’s likely going wrong and how to fix it.

First: The Core Issue

Your setup with @Order is a good start, but the missing piece is custom logic to redirect users based on their role after login. By default, Spring Security just redirects to the last page the user tried to access (or a default URL), which isn’t what you want here.

Step 1: Create a Custom Login Success Handler

This component will check the authenticated user’s roles and send them to the right page.

@Component
public class RoleBasedRedirectHandler implements AuthenticationSuccessHandler {

    @Override
    public void onAuthenticationSuccess(
            HttpServletRequest request,
            HttpServletResponse response,
            Authentication authentication
    ) throws IOException {

        // Loop through the user's granted authorities (roles)
        for (GrantedAuthority auth : authentication.getAuthorities()) {
            String role = auth.getAuthority();
            
            if (role.equals("ROLE_ADMIN")) {
                response.sendRedirect("/admin/dashboard"); // Adjust to your actual admin landing page
                return;
            } else if (role.equals("ROLE_USER")) {
                response.sendRedirect("/user/profile"); // Adjust to your actual user landing page
                return;
            }
        }

        // Fallback if no matching role is found
        response.sendRedirect("/");
    }
}

Step 2: Fix Your Security Configuration Classes

Make sure your @Ordered configs use the success handler, and properly scope their path matching so they don’t override each other.

For Spring Security 6+ (Using SecurityFilterChain)

// Admin-specific config - higher priority (smaller @Order number)
@Configuration
@Order(1)
public class AdminSecurityConfig {

    private final RoleBasedRedirectHandler redirectHandler;

    // Inject the custom handler via constructor
    public AdminSecurityConfig(RoleBasedRedirectHandler redirectHandler) {
        this.redirectHandler = redirectHandler;
    }

    @Bean
    public SecurityFilterChain adminFilterChain(HttpSecurity http) throws Exception {
        http
                // Only apply this config to /admin/** paths
                .securityMatcher("/admin/**")
                .authorizeHttpRequests(auth -> auth
                        .anyRequest().hasRole("ADMIN")
                )
                .formLogin(form -> form
                        // Use our custom redirect logic
                        .successHandler(redirectHandler)
                        // Optional: Set your login page URL if you have a custom one
                        .loginPage("/login")
                        .permitAll()
                );
        return http.build();
    }
}

// User-specific config - lower priority
@Configuration
@Order(2)
public class UserSecurityConfig {

    private final RoleBasedRedirectHandler redirectHandler;

    public UserSecurityConfig(RoleBasedRedirectHandler redirectHandler) {
        this.redirectHandler = redirectHandler;
    }

    @Bean
    public SecurityFilterChain userFilterChain(HttpSecurity http) throws Exception {
        http
                // Only apply this config to /user/** paths
                .securityMatcher("/user/**")
                .authorizeHttpRequests(auth -> auth
                        .anyRequest().hasRole("USER")
                )
                .formLogin(form -> form
                        .successHandler(redirectHandler)
                        .loginPage("/login")
                        .permitAll()
                );
        return http.build();
    }
}

// Bonus: Public paths (login page, static assets) - highest priority
@Configuration
@Order(0)
public class PublicSecurityConfig {
    @Bean
    public SecurityFilterChain publicFilterChain(HttpSecurity http) throws Exception {
        http
                .securityMatcher("/login", "/css/**", "/js/**")
                .authorizeHttpRequests(auth -> auth
                        .anyRequest().permitAll()
                );
        return http.build();
    }
}

For Older Spring Security (Using WebSecurityConfigurerAdapter)

@Configuration
@Order(1)
public class AdminSecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private RoleBasedRedirectHandler redirectHandler;

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                .antMatcher("/admin/**")
                .authorizeRequests()
                .anyRequest().hasRole("ADMIN")
                .and()
                .formLogin()
                .successHandler(redirectHandler)
                .loginPage("/login")
                .permitAll();
    }
}

@Configuration
@Order(2)
public class UserSecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private RoleBasedRedirectHandler redirectHandler;

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                .antMatcher("/user/**")
                .authorizeRequests()
                .anyRequest().hasRole("USER")
                .and()
                .formLogin()
                .successHandler(redirectHandler)
                .loginPage("/login")
                .permitAll();
    }
}

Key Things to Double-Check

  • Role Naming: Make sure your user roles are stored with the ROLE_ prefix (e.g., ROLE_ADMIN in your database/user details service). The hasRole() method automatically adds this prefix, so if your roles are stored without it, use hasAuthority() instead.
  • Path Matching: Always use securityMatcher (or antMatcher for older versions) to scope each config to its intended path. Without this, one config will override the other.
  • Login Page Access: Ensure your /login page is accessible to unauthenticated users (we added .permitAll() in the examples for this).

Once you implement this, when a user logs in, the success handler will check their role and send them straight to the correct admin or user dashboard.

内容的提问来源于stack exchange,提问作者Tiborsio_

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 08:50:16