Spring Security因CSRF导致访问被拒问题求助
Hey there, let's work through this CSRF issue you're hitting. Even though your /product/58 page is unprotected, once you log in, Spring Security's CSRF protection remains active across your application—here's how to diagnose and fix the problem:
1. Verify CSRF Token Rendering
First, check if the CSRF token is actually being rendered correctly in your form. Open your browser's page source and look at the hidden input field:
It should look something like
<input type="hidden" name="_csrf" value="d7a8f2e4-..." />instead of showing the raw EL expressions${_csrf.parameterName}and${_csrf.token}.
If the EL expressions aren't resolving, this could mean:
- Your JSP doesn't have EL enabled (add
<%@ page isELIgnored="false" %>at the top of your page if you're using JSPs). - You're using a view technology that doesn't automatically expose request attributes (Spring Security puts the CSRF token in request attributes by default).
Also, since you're using Spring's <form:form> tag, you can actually remove the manual hidden CSRF input—this tag automatically adds the CSRF token when Spring Security's CSRF protection is enabled. Try removing that line and see if the token is added correctly.
2. Check Spring Security CSRF Configuration
Spring Security's CSRF protection applies to all non-GET/HEAD/TRACE/OPTIONS requests by default, even for unprotected endpoints. Here's what to check:
- Ensure you haven't disabled CSRF in your security config (the default is enabled, but if you have
.csrf().disable()somewhere, that's an edge case). - If you really need to bypass CSRF for the
/product/make/offer/endpoint (not recommended for form submissions, as CSRF is a critical security measure), you can configure it to ignore the path:@Override protected void configure(HttpSecurity http) throws Exception { http .csrf(csrf -> csrf .ignoringAntMatchers("/product/make/offer/") ) // Add your other security configurations here } - But again, fixing the token delivery is better practice than disabling protection.
3. Validate Form Action Path & Token Submission
- Make sure your form's
actionpath is correct. If your app has a context path (e.g.,/my-app), your action should include it to avoid mismatched paths. Use Spring's context path variable to generate the correct URL:<form:form name="offerForm" id="offer" modelAttribute="offerProposal" action="${pageContext.request.contextPath}/product/make/offer/" method="post" enctype="multipart/form-data"> - Use your browser's DevTools (Network tab) to inspect the POST request when you submit the form. Check if the CSRF token is present in the Form Data. If it's missing, go back to step 1 to fix the token rendering.
4. Handle Multipart/form-data Correctly
Since your form uses enctype="multipart/form-data", you need to ensure Spring Security can read the CSRF token from the multipart request:
- Ensure multipart parsing is configured before CSRF validation in your security config. For example:
@Override protected void configure(HttpSecurity http) throws Exception { http .multipart(multipart -> multipart .maxFileSize(MaxSize.of(10, SizeUnit.MEGABYTES)) // Adjust as needed ) .csrf(csrf -> csrf // Your CSRF config here ) // Rest of your security setup } - If you're using Servlet 3.0+ multipart handling, Spring Security should automatically extract the token from the multipart request, but misconfiguration here can cause validation failures.
Start with the first two steps—those are the most common culprits for this scenario. Let me know if you hit any snags along the way!
内容的提问来源于stack exchange,提问作者amachado

