2012-05-14 16 views
7

No puedo acceder a la información de Spring Security durante una publicación de varias partes de servlet. La información de seguridad de primavera está disponible durante los métodos habituales de obtención y publicación, pero no está disponible para un método de publicación de varias partes. Intenté sin éxito acceder a esta información de seguridad directamente a través de SecurityContextHolder.getContext(). GetAuthentication() y a través de un servicio inyectado que accede a SecurityContextHolder.getContext(). GetAuthentication().No se puede acceder a la información de Spring Security durante una publicación múltiple de servlet

También implementé un HttpRequestHandler y un ServletWrappingController. Una vez más, pude inyectar con éxito los frijoles primaverales y acceder a la información de Spring Security para los métodos habituales de obtención y publicación, pero no pude acceder a la información de Spring Security para las publicaciones de varias partes. Sé que hay nuevas capacidades MultiPart integradas en Spring 3.0, pero dado que nuestro sitio web requerirá acceso completo a la transmisión de carga de archivos, no podré usarlas. Por esa razón, me estoy enfocando en HttpServlet, HttpRequestHandler y ServletWrappingController.

El código que publico aquí es todo código de prueba escrito para resolver este problema específico al que me enfrento con información de seguridad que no está disponible durante una carga múltiple (no destinada a ser de calidad de producción). Es para un HttpServlet.

Háganme saber si hay algo que estoy haciendo mal. O si no, ¿hay una solución alternativa o una mejor manera de realizar una carga múltiple con acceso a la información de Spring Security mientras se mantiene el acceso al flujo de carga de archivos? ¡Cualquier ayuda que alguien pueda ofrecer con este problema será muy apreciada!

A continuación se muestra el código del servlet de prueba. Comentarios a continuación sobre lo que funciona y lo que no se basa en un usuario registrado para acceder a la página web usando 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{ 
      //... 
     } 


    } 

} 

Aquí está la parte pertinente de 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> 
+0

¿Puede agregar la porción de web.xml que muestra la configuración de Spring Security? – Ritesh

+0

¿Por qué está asignando solicitudes a 'UploadServlet' en web.xml en lugar de en las configuraciones de Spring? –

Respuesta

0

esto podría ayudarle, si usted está utilizando Spring MVC: detalles

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

Debe explicar cómo esto resuelve el problema. –

0

de seguridad conforme a lo dispuesto por SecurityContextHolder son (por defecto) almacenado en un ThreadLocal.

¿Cargar servlet crea un nuevo hilo para manejar las piezas múltiples? Intente cambiar el SecurityContextHolderStrategy a MODE_INHERITABLETHREADLOCAL

cuestiones similares: How to set up Spring Security SecurityContextHolder strategy?

0

Podría valer la pena comprobar cómo su cliente está realizando el cargo de varias partes, ¿está utilizando un mecanismo diferente/biblioteca para su posterior estándar?

Si tuviera que adivinar, diría que su código de cliente no se está autenticando correctamente para el caso de uso de varias partes.

E.g. Usando Java estándar para la publicación normal y libs de Apache para la publicación de varias partes y olvidando configurar los encabezados http apropiados cuando se utiliza el material de Apache.

2

Puedo confirmar que Spring 3.0.x y Spring Security 3.0.x trabajan juntos con publicaciones de varias partes y también funcionan con otros tipos de solicitudes. Me encontré con un comportamiento similar, y en nuestro caso, el filtro de seguridad no se aplicaba a la solicitud debido a nuestro error en las asignaciones de filtro.

¿Puede publicar las partes de su web.xml que define el filtro de seguridad y lo correlaciona con las rutas deseadas?

Cuestiones relacionadas