自定义Spring Security Filter时出现过多重定向错误求助
Hey there! Let's tackle that annoying infinite redirect loop you're hitting when trying to enforce a post-login flow with your custom UserDetails filter. I’ve dealt with similar Spring Security headaches before, so let’s break this down step by step.
Common Causes of the Loop
Since you mentioned commenting out the successHandler redirect didn’t fix it, the issue is likely rooted in your filter’s logic or how it integrates with Spring Security. Here are the most probable culprits:
- Your filter isn’t skipping already-authenticated users or the target post-login page, causing it to re-trigger the redirect on every request.
- The logic checking if the user completed the required flow is broken (e.g., always returning
falseeven after the user finishes the process). - The filter is registered in the wrong order, running before authentication is fully completed.
- You’re not excluding static resources or the post-login endpoint from the filter’s scope.
Step-by-Step Fixes
1. Fix the Filter’s Core Logic
First, make sure your filter only acts on authenticated users who haven’t completed the flow, and skips the target endpoint to avoid looping. Here’s a revised example:
@Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletRequest req = (HttpServletRequest) request; HttpServletResponse res = (HttpServletResponse) response; // Skip the post-login flow endpoint to prevent immediate re-redirect String targetPath = "/complete-onboarding"; // Replace with your actual path if (req.getRequestURI().equals(targetPath) || req.getRequestURI().startsWith("/static/")) { chain.doFilter(request, response); return; } // Check if user is authenticated (and not anonymous) Authentication auth = SecurityContextHolder.getContext().getAuthentication(); if (auth != null && auth.isAuthenticated() && !(auth instanceof AnonymousAuthenticationToken)) { CustomUserDetails user = (CustomUserDetails) auth.getPrincipal(); // Only redirect if the user hasn't completed the required flow if (!user.isFlowCompleted()) { // Double-check this method's logic! res.sendRedirect(targetPath); return; } } // Pass through all other requests chain.doFilter(request, response); }
Critical check: Verify that isFlowCompleted() (or whatever your status-check method is called) correctly returns true once the user finishes the flow. It’s easy to accidentally reverse the condition here!
2. Ensure Correct Filter Order
Your filter needs to run after Spring Security’s authentication filters (like UsernamePasswordAuthenticationFilter), otherwise it’ll check the user’s status before they’re fully logged in.
In your Security Config:
@Override protected void configure(HttpSecurity http) throws Exception { http .authorizeRequests() // ... your authorization rules .anyRequest().authenticated() .formLogin() // ... your login config // Add your filter AFTER the authentication filter .addFilterAfter(new CustomUserCheckFilter(), UsernamePasswordAuthenticationFilter.class); }
3. Verify Exclusions in Security Config
Make sure the post-login endpoint is accessible without triggering the filter. Explicitly allow access to it:
@Override protected void configure(HttpSecurity http) throws Exception { http .authorizeRequests() .antMatchers("/complete-onboarding").permitAll() // Allow access to the flow page .anyRequest().authenticated() // ... rest of your config }
4. Debug with Browser Dev Tools
Open your browser’s Network tab and watch the redirects. You’ll see exactly which two URLs are looping between each other—this will confirm if your filter is targeting the right endpoint or if another rule is interfering.
If You’re Still Stuck
If none of these fixes work, share the full code of your custom filter and your Spring Security configuration. That’ll help spot edge cases like incorrect authentication checks or conflicting filter rules.
内容的提问来源于stack exchange,提问作者lcgsrick

