Unable to Access Spring Security Information During Servlet Multipage Posting

I cannot access Spring security information during a multi-page servlet message. Spring security information is available during regular receive and publish methods, but is not available for the multipart post method. I tried unsuccessfully to access this security information directly through SecurityContextHolder.getContext (). GetAuthentication () and through an embedded service that accesses SecurityContextHolder.getContext (). GetAuthentication ().

I also implemented the HttpRequestHandler and ServletWrappingController. Once again, I was able to successfully inject Spring beans into them and access Spring security information for regular retrieval and publishing methods, but I was not able to access Spring security information for multi-page posts. I know that there are new MultiPart features built into Spring 3.0, but since our website will require full access to the file download stream, I will not be able to use them. For this reason, I focus on the HttpServlet, HttpRequestHandler and ServletWrappingController.

The code that I post here is all the test codes written to solve this particular problem that I am facing, and the security information is not available during multi-page downloads (not to ensure product quality). This is for the HttpServlet.

Please let me know if I am doing something wrong. Or, if not, if there is a workaround or a better way to do multi-page downloads with access to Spring security information while maintaining access to the file download stream? Any help anyone with this problem can offer would be greatly appreciated!

The following is the code for the test servlet. The comments below about what works and what doesn't are based on the user logged in to the website using Spring Security 3.1:

//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("<h1>Guide Info</h1><br/>"); Guide guide = guideService.findById(2l); out.write(guide.getName() + "<br/>"); out.write(guide.getDescription() + "<br/>"); out.write("UserName: " + customUserService.getCurrentUser().getUsername() + "<br/>"); } else{ PrintWriter out = resp.getWriter(); out.write("<h1>You're not authorized</h1><br/>"); } } //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{ //... } } } 

Here is the relevant part of web.xml:

 <servlet> <servlet-name>fgm</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>WEB-INF/spring/webmvc-config.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>fgm</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> <servlet> <servlet-name>UploadServlet</servlet-name> <servlet-class>com.guides.servlet.UploadServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>UploadServlet</servlet-name> <url-pattern>/upload</url-pattern> </servlet-mapping> 
+7
source share
4 answers

I can confirm that Spring 3.0.x and Spring Security 3.0.x work together with multi-page messages and also work with other types of requests. I encountered a similar behavior, and in our case, the security filter was not applied to the request due to our error in the filters.

Can you place the parts of your web.xml that define the security filter and map it to the paths you need?

+2
source

This may help you if you are using Spring MVC:

 { @RequestMapping(method = RequestMethod.POST, value = "/some/post/url") public void postFile(MultipartHttpServletRequest request) { MultipartFile multipartFile = request.getFileMap().get("fileControlName"); ... } } 
0
source

Security information provided by SecurityContextHolder is stored by default in ThreadLocal.

Loads a servlet creates a new thread to handle multiparts? Try changing SecurityContextHolderStrategy to MODE_INHERITABLETHREADLOCAL

Related issues: How to configure Spring Security Strategy SecurityContextHolder?

0
source

Perhaps it is worth checking how your client performs multi-page recording, are you using a different mechanism / library for your standard message?

If I had to guess, I would say that your client code is not authenticated correctly for the multipart case.

eg. Using standard Java for regular mail and Apache libs for multi-page communication and forgetting to set the appropriate HTTP headers when using Apache stuff.

0
source

All Articles