Note that there are some explanatory texts on larger screens.

plurals
  1. POUnable to access Spring Security information during a servlet multipart post
    text
    copied!<p>I'm unable to access Spring Security information during a servlet multipart post. The spring security information is available during regular get and post methods, but is not available for a multipart post method. I tried unsuccessfully to access this security information directly through SecurityContextHolder.getContext().getAuthentication() and through an injected service that accesses SecurityContextHolder.getContext().getAuthentication().</p> <p>I also implemented an HttpRequestHandler and a ServletWrappingController. Once again, I was able to successuly inject spring beans into them and access Spring Security info for regular get and post methods, but I was not able access Spring Security info for a multipart posts. I know that there are new MultiPart capabilities built into Spring 3.0 but because our website will require full access to the file upload stream I won't be able to use them. For that reason, I am focusing on the HttpServlet, HttpRequestHandler and the ServletWrappingController. </p> <p>The code I'm posting here is all test code written to solve this specific problem I'm facing with security information not being available during a multipart upload (not meant to be of production quality). It is for an HttpServlet. </p> <p>Please let me know if there's something I'm doing wrong. Or if not, if there's a workaround or a better way to accomplish a multipart upload with access to Spring Security info while maintaining access to the file upload stream? Any assistance that someone can offer with this problem will be greatly appreciated!</p> <p>Below is the test servlet code. Comments below as to what works and what doesn't is based on a user logged in to the website using Spring Security 3.1:</p> <pre><code>//many import statements not displayed import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.context.support.SpringBeanAutowiringSupport; import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.context.SecurityContextHolder; public class UploadServlet extends HttpServlet { public void service(HttpServletRequest req, HttpServletResponse res) throws IOException, ServletException { super.service(req, res); } public void init(ServletConfig config) throws ServletException { super.init(config); SpringBeanAutowiringSupport.processInjectionBasedOnServletContext(this, config.getServletContext()); } //The following is always injected and available //however, it only returns valid security information for regular get and post methods, //not for multipart post methods @Autowired private CustomUserService customUserService; //The following is always injected and available and always returns the expected data @Autowired private GuideService guideService; //the following does not work when the client issues a multipart post, it does work for non-multipart public boolean getAuthenticated(){ boolean authorized = false; for (GrantedAuthority authority : SecurityContextHolder.getContext().getAuthentication().getAuthorities()) { if(authority.getAuthority().equals("ROLE_USER") || authority.getAuthority().equals("ROLE_ADMIN")) { authorized = true; break; } } return authorized; } //The following test get method works fine protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { if(getAuthenticated()){ PrintWriter out = resp.getWriter(); out.write("&lt;h1&gt;Guide Info&lt;/h1&gt;&lt;br/&gt;"); Guide guide = guideService.findById(2l); out.write(guide.getName() + "&lt;br/&gt;"); out.write(guide.getDescription() + "&lt;br/&gt;"); out.write("UserName: " + customUserService.getCurrentUser().getUsername() + "&lt;br/&gt;"); } else{ PrintWriter out = resp.getWriter(); out.write("&lt;h1&gt;You're not authorized&lt;/h1&gt;&lt;br/&gt;"); } } //This post method protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //the following always works, whether the clients posts using multipart or not String guideName = guideService.findById(2l).getName(); //the following does not work when the client issues a multipart post, it does work for non-multipart String userName = customUserService.getCurrentUser().getUsername(); //the following does not work when the client issues a multipart post, it does work for non-multipart if(getAuthenticated()){ String responseString = RESP_SUCCESS; boolean isMultipart = ServletFileUpload.isMultipartContent(req); if (isMultipart) { ServletFileUpload upload = new ServletFileUpload(); //commmons fileupload code // Not a multi-part MIME request. else { //... } //... } else{ //... } } } </code></pre> <p>Here is the relevant portion of web.xml:</p> <pre><code>&lt;servlet&gt; &lt;servlet-name&gt;fgm&lt;/servlet-name&gt; &lt;servlet-class&gt;org.springframework.web.servlet.DispatcherServlet&lt;/servlet-class&gt; &lt;init-param&gt; &lt;param-name&gt;contextConfigLocation&lt;/param-name&gt; &lt;param-value&gt;WEB-INF/spring/webmvc-config.xml&lt;/param-value&gt; &lt;/init-param&gt; &lt;load-on-startup&gt;1&lt;/load-on-startup&gt; &lt;/servlet&gt; &lt;servlet-mapping&gt; &lt;servlet-name&gt;fgm&lt;/servlet-name&gt; &lt;url-pattern&gt;/&lt;/url-pattern&gt; &lt;/servlet-mapping&gt; &lt;servlet&gt; &lt;servlet-name&gt;UploadServlet&lt;/servlet-name&gt; &lt;servlet-class&gt;com.guides.servlet.UploadServlet&lt;/servlet-class&gt; &lt;/servlet&gt; &lt;servlet-mapping&gt; &lt;servlet-name&gt;UploadServlet&lt;/servlet-name&gt; &lt;url-pattern&gt;/upload&lt;/url-pattern&gt; &lt;/servlet-mapping&gt; </code></pre>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload