Spring Security集成Spring Boot 1.5.3后请求URI异常问题咨询
Hey there, let's tackle this URI issue you're facing after integrating Spring Security into your Spring Boot 1.5.3.RELEASE project. The root cause here is likely that after adding Spring Security, your requests are going through an internal forward (either for authentication redirects or view resolution), which makes your HandlerInterceptor pick up the forwarded JSP path instead of the original request URI. Here are the most effective fixes:
1. Grab the Original Request URI (Quickest Fix)
When a request is forwarded internally by the servlet container, it stores the original URI in a request attribute. You can retrieve this in your preHandle method instead of relying on getRequestURI() directly:
@Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { // Get original URI if the request was forwarded String originalUri = (String) request.getAttribute("javax.servlet.forward.request_uri"); // Fallback to current URI if no forward happened String requestUri = originalUri != null ? originalUri : request.getRequestURI(); // Use this requestUri for your redirect logic now System.out.println("Original Request URI: " + requestUri); return super.preHandle(request, response, handler); }
This will ensure you always get the initial path the user requested (like /admin/login) instead of the forwarded JSP path.
2. Verify Your Spring Security Login Page Configuration
If you’ve configured your login page directly to a JSP path instead of a logical controller endpoint, that could be causing an immediate forward. Make sure your WebSecurityConfigurerAdapter uses a controller path, not the physical JSP location:
Bad (direct JSP path - causes immediate forward):
@Override protected void configure(HttpSecurity http) throws Exception { http.formLogin() .loginPage("/WEB-INF/jsp/admin/login.jsp"); }
Good (controller endpoint - preserves original URI):
@Override protected void configure(HttpSecurity http) throws Exception { http.formLogin() .loginPage("/admin/login") // Maps to your controller endpoint .permitAll(); }
Then add a controller to handle this endpoint and return the logical view name (your view resolver will map this to the JSP):
@Controller @RequestMapping("/admin") public class AdminAuthController { @GetMapping("/login") public String showLoginPage() { return "admin/login"; // Resolves to /WEB-INF/jsp/admin/login.jsp } }
This way, the initial request hits /admin/login first (which your interceptor will pick up correctly) before being forwarded to the JSP.
3. Adjust Interceptor vs. Security Filter Order
Spring Security filters run before Spring MVC’s DispatcherServlet, while HandlerInterceptors run after it. If your interceptor is meant to handle authentication-related checks, consider moving that logic to a Spring Security Filter instead—this will let you process the original request URI before any forwards happen.
For example, create a custom filter:
public class CustomAuthFilter extends OncePerRequestFilter { @Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { String requestUri = request.getRequestURI(); // Your redirect/validation logic here filterChain.doFilter(request, response); } }
Then register it in your security config:
@Override protected void configure(HttpSecurity http) throws Exception { http.addFilterBefore(new CustomAuthFilter(), UsernamePasswordAuthenticationFilter.class); // Rest of your security configuration... }
4. Rule Out ContextUtil Interference
Since you mentioned registering ContextUtil to ConfigurableApplicationContext, double-check that this class isn’t modifying the request object or altering request attributes related to URI handling. It’s unlikely to be the cause, but it’s worth a quick scan to eliminate variables.
内容的提问来源于stack exchange,提问作者Benjamin Steiner

