2012-05-14 2 views
7

Ich kann während eines Servlet-Multipart-Posts nicht auf Spring Security-Informationen zugreifen. Die Informationen zur Federsicherheit stehen während der regulären Methoden zum Abrufen und Senden zur Verfügung, sind jedoch für eine mehrteilige Postmethode nicht verfügbar. Ich habe erfolglos versucht, auf diese Sicherheitsinformationen direkt über SecurityContextHolder.getContext(). GetAuthentication() und über einen injizierten Dienst zuzugreifen, der auf SecurityContextHolder.getContext(). GetAuthentication() zugreift.Auf Spring-Sicherheitsinformationen während eines Servlet-Multipart-Posts kann nicht zugegriffen werden

Ich habe auch einen HttpRequestHandler und einen ServletWrappingController implementiert. Wieder einmal konnte ich Spring Beans erfolgreich in sie injizieren und auf die Spring Security-Informationen für reguläre Methoden zum Abrufen und Posten zugreifen. Ich konnte jedoch nicht auf Spring Security-Informationen für mehrteilige Posts zugreifen. Ich weiß, dass es in Spring 3.0 neue MultiPart-Funktionen gibt, aber da unsere Website vollen Zugriff auf den Datei-Upload-Stream benötigt, kann ich sie nicht verwenden. Aus diesem Grund konzentriere ich mich auf das HttpServlet, den HttpRequestHandler und den ServletWrappingController.

Der Code, den ich hier veröffentliche alle Testcode geschrieben dieses spezielle Problem mit Ich bin vor zu lösen Sicherheitsinformationen nicht während einer mehrteiligen Upload zur Verfügung steht (nicht zu der Produktionsqualität gemeint). Es ist für ein HttpServlet.

Bitte lassen Sie mich wissen, wenn etwas falsch ist. Oder wenn nicht, wenn es einen Workaround oder eine bessere Möglichkeit gibt, einen mehrteiligen Upload mit Zugriff auf Spring Security-Informationen durchzuführen, während der Zugriff auf den Datei-Upload-Stream erhalten bleibt? Jede Hilfe, die jemand mit diesem Problem anbieten kann, wird sehr geschätzt!

Unten ist der Test-Servlet-Code. Kommentare unten, was funktioniert und was nicht auf einem Benutzer basierend angemeldet auf die Website mit 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{ 
      //... 
     } 


    } 

} 

Hier ist der relevante Teil der 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

Können Sie den Teil von web.xml hinzufügen, der die Spring Security-Konfiguration anzeigt? – Ritesh

+0

Warum ordnen Sie in web.xml und nicht in der Spring-Konfiguration Anforderungen an UploadServlet an? –

Antwort

0

Dies könnte Ihnen helfen, wenn Sie Spring MVC verwenden:

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

Sie sollten erklären, wie dies das Problem löst. –

0

Sicherheitsdetails wie SecurityContextHolder sind vorgesehen (standardmäßig) in einem Thread gespeichert.

Erstellt das Upload-Servlet einen neuen Thread für Multiparts? Versuchen Sie, die SecurityContextHolderStrategy zu MODE_INHERITABLETHREADLOCAL

Ähnliche Probleme: How to set up Spring Security SecurityContextHolder strategy?

0

Es könnte sich lohnen überprüfen, wie Ihr Kunde die Durchführung der mehrteiligen Beitrag, verwenden Sie einen anderen Mechanismus/Bibliothek zu Ihrem Standard-Post?

Wenn ich raten müsste, würde ich sagen, dass Ihr Client-Code für den mehrteiligen Anwendungsfall nicht korrekt authentifiziert.

z. Verwenden von Standard-Java für die normalen Post- und Apache-Bibliotheken für den Multipart-Post und Vergessen, die entsprechenden http-Header bei Verwendung des Apache-Krams zu setzen.

2

Ich kann bestätigen, dass Spring 3.0.x und Spring Security 3.0.x zusammen arbeiten mit Multipart-Posts sowie sie mit anderen Arten von Anfragen arbeiten. Ich bin auf ein ähnliches Verhalten gestoßen, und in unserem Fall wurde der Sicherheitsfilter aufgrund unseres Fehlers in den Filterzuordnungen nicht auf die Anfrage angewendet.

Können Sie die Teile Ihres Webs posten.XML, die den Sicherheitsfilter definieren und den gewünschten Pfaden zuordnen?

Verwandte Themen