Comment bien gérer upload de fichier MaxUploadSizeExceededException avec Ressort de Sécurité

Je suis à l'aide de Spring Web en php 4.0.5, le Printemps de Sécurité 3.2.4, Commons FileUpload 1.3.1, Tomcat 7 et je suis une vilaine MaxUploadSizeExceededException lors de l'upload de la taille limite est dépassée, ce qui résulte en une "500 Internal Server Error". Je l'ai manipuler avec un joli générique de pop-up, mais je préfère avoir mon Contrôleur de prendre soin d'elle en remontant à l'origine de la forme avec le bon message d'explication.

J'ai vu une question similaire a demandé à plusieurs reprises, avec quelques solutions qui pourraient fonctionner lorsque vous n'utilisez pas le Printemps de Sécurité; aucun de ceux que j'ai essayé de travaillé pour moi.

Le problème pourrait être que lors de l'utilisation de Spring Security, la CommonsMultipartResolver n'est pas ajouté comme un "multipartResolver" bean, mais comme un "filterMultipartResolver":

@Bean(name="filterMultipartResolver")
CommonsMultipartResolver filterMultipartResolver() {
    CommonsMultipartResolver filterMultipartResolver = new CommonsMultipartResolver();
    filterMultipartResolver.setMaxUploadSize(MAXSIZE);
    return filterMultipartResolver;
}

Si j'ai mis filterMultipartResolver.setResolveLazily(true); il ne fait aucune différence.

Si je sous-classe de la CommonsMultipartResolver avec mon propre et remplacer le parseRequest() méthode avec quelque chose que les pièges de la MaxUploadSizeExceededException et renvoie un vide MultipartParsingResult, je reçois un "403 Forbidden" erreur:

public class ExtendedCommonsMultipartResolver extends CommonsMultipartResolver {
    protected MultipartParsingResult parseRequest(HttpServletRequest request) throws MultipartException {
        String encoding = determineEncoding(request);
        try {
            return super.parseRequest(request);
        } catch (MaxUploadSizeExceededException e) {
            return parseFileItems(Collections.<FileItem> emptyList(), encoding);
        }
    }
}

Enfin, il n'y a aucun point dans la mise en œuvre de certains type de local ou global ExceptionHandler parce qu'il n'est jamais appelée.

Si je n'ai pas trouver une meilleure solution, je vais juste supprimer la taille limite de téléchargement et le gérer moi-même dans le contrôleur, avec l'inconvénient d'avoir à l'utilisateur d'attendre jusqu'à ce que le téléchargement est terminé avant de voir le message d'erreur sur la taille du fichier.
De je peut même ignorer tout cela parce que, étant une image dans ce cas, je pourrais juste redimensionner à la bonne valeurs.

Encore, j'aimerais voir une solution à ce problème.

Merci

EDIT:

- Je ajouter de la trace de la pile comme demandé. C'est le cas où une 500 est généré.

May 30, 2014 12:47:17 PM org.apache.catalina.core.StandardWrapperValve invoke
SEVERE: Servlet.service() for servlet [dispatcher] in context with path [/site] threw exception
org.springframework.web.multipart.MaxUploadSizeExceededException: Maximum upload size of 1000000 bytes exceeded; nested exception is org.apache.commons.fileupload.FileUploadBase$SizeLimitExceededException: the request was rejected because its size (3403852) exceeds the configured maximum (1000000)
at org.springframework.web.multipart.commons.CommonsMultipartResolver.parseRequest(CommonsMultipartResolver.java:162)
at org.springframework.web.multipart.commons.CommonsMultipartResolver.resolveMultipart(CommonsMultipartResolver.java:142)
at org.springframework.web.multipart.support.MultipartFilter.doFilterInternal(MultipartFilter.java:110)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:100)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:953)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:409)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1044)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:607)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:315)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
at java.lang.Thread.run(Thread.java:722)
Caused by: org.apache.commons.fileupload.FileUploadBase$SizeLimitExceededException: the request was rejected because its size (3403852) exceeds the configured maximum (1000000)
at org.apache.commons.fileupload.FileUploadBase$FileItemIteratorImpl.<init>(FileUploadBase.java:965)
at org.apache.commons.fileupload.FileUploadBase.getItemIterator(FileUploadBase.java:310)
at org.apache.commons.fileupload.FileUploadBase.parseRequest(FileUploadBase.java:334)
at org.apache.commons.fileupload.servlet.ServletFileUpload.parseRequest(ServletFileUpload.java:115)
at org.springframework.web.multipart.commons.CommonsMultipartResolver.parseRequest(CommonsMultipartResolver.java:158)
... 19 more
  • Merci de poster votre plein stacktraces
  • Certains complément d'enquête reveales que, lors de l'utilisation de la seule approche viable qui est le ExtendedCommonsMultipartResolver, le "403 Forbidden" est causée par le csrf fonction de Ressort de Sécurité. Si je désactive avec http.csrf().disable() dans mon WebSecurityConfigurerAdapter, la 403 est pas généré. Bien sûr, je préfère ne pas la désactiver, même partiellement avec un requireCsrfProtectionMatcher() car je ne voudrais pas que mes utilisateurs de télécharger quelqu'un d'autre données, à moins que le csrf truc ne peut pas être joué avec un multipart. La question d'origine tient toujours. Veuillez informer.
  • J'ai le sentiment que la question ne peut être résolu, à moins que A) j'ai mis le _csrf sur l'url, comme expliqué ici docs.printemps.io/printemps-sécurité/site/docs/3.2.0.CI-SNAPSHOT/... ou B) j'écris une ExtendedCommonsMultipartResolver que les pièges de la MaxUploadSizeExceededException et répète le parseRequest après la désactivation de la vérification de la taille et d'une certaine façon les drapeaux de l'excès. Option B serait encore charger la totalité du fichier de sorte qu'il est inutile. Je suppose que nous avons vraiment une option.
InformationsquelleAutor xtian | 2014-05-25