Printemps de Sécurité & Multipart demandes
J'ai un @Contrôleur protégé avec Ressort de Sécurité et OAuth2 dans lequel je suis en train de permettre aux utilisateurs de télécharger un fichier:
@Controller
@RequestMapping(value = "/api/image")
public class ImageController {
@PreAuthorize("hasAuthority('ROLE_USER')")
@RequestMapping(value = "/upload", method = RequestMethod.PUT)
public @ResponseBody Account putImage(@RequestParam("title") String title, MultipartHttpServletRequest request, Principal principal){
//Some type of file processing...
System.out.println("-------------------------------------------");
System.out.println("Test upload: " + title);
System.out.println("Test upload: " + request.getFile("file").getOriginalFilename());
System.out.println("-------------------------------------------");
return ((Account) ((OAuth2Authentication) principal).getPrincipal());
}
}
Lorsque j'essaie de télécharger un fichier et le titre, j'obtiens l'exception suivante. Je suis en train de le header Content-Type pour multipart/form-data.
java.lang.IllegalStateException: Current request is not of type [org.springframework.web.multipart.MultipartHttpServletRequest]: SecurityContextHolderAwareRequestWrapper[ FirewalledRequest[ org.apache.catalina.connector.RequestFacade@1aee75b7]]
at org.springframework.web.servlet.mvc.method.annotation.ServletRequestMethodArgumentResolver.resolveArgument(ServletRequestMethodArgumentResolver.java:84)
at org.springframework.web.method.support.HandlerMethodArgumentResolverComposite.resolveArgument(HandlerMethodArgumentResolverComposite.java:75)
at org.springframework.web.method.support.InvocableHandlerMethod.getMethodArgumentValues(InvocableHandlerMethod.java:156)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:117)
Comment puis-je faire de l'upload de fichiers derrière Printemps de Sécurité? Il semble que la demande n'est jamais transformé en un MultiPartHttpServerRequest et donc il ne fonctionne pas?
Si je change de signature de la méthode de prendre un @RequestParam MultipartFile, puis-je obtenir une exception comme:
DEBUG DefaultListableBeanFactory - Returning cached instance of singleton bean 'imageController'
DEBUG ExceptionHandlerExceptionResolver - Resolving exception from handler [public com.tinsel.server.model.Account com.tinsel.server.controller.ImageController.putImage(java.lang.String,org.springframework.web.multipart.MultipartFile,java.security.Principal)]: java.lang.IllegalArgumentException: Expected MultipartHttpServletRequest: is a MultipartResolver configured?
DEBUG ResponseStatusExceptionResolver - Resolving exception from handler [public com.tinsel.server.model.Account com.tinsel.server.controller.ImageController.putImage(java.lang.String,org.springframework.web.multipart.MultipartFile,java.security.Principal)]: java.lang.IllegalArgumentException: Expected MultipartHttpServletRequest: is a MultipartResolver configured?
DEBUG DefaultHandlerExceptionResolver - Resolving exception from handler [public com.tinsel.server.model.Account com.tinsel.server.controller.ImageController.putImage(java.lang.String,org.springframework.web.multipart.MultipartFile,java.security.Principal)]: java.lang.IllegalArgumentException: Expected MultipartHttpServletRequest: is a MultipartResolver configured?
DEBUG DispatcherServlet - Could not complete request
java.lang.IllegalArgumentException: Expected MultipartHttpServletRequest: is a MultipartResolver configured?
at org.springframework.util.Assert.notNull(Assert.java:112)
...mais j'ai un MultipartResolver configuré dans mon XML:
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="maxUploadSize" value="268435456"/> <!-- 256 megs -->
</bean>
Je ne vois ce blog à propos de l'obtention de ce travail, en vertu de Printemps 3.0 - mais je vais essayer d'être plus à jour et je suis en utilisant 3.1 actuellement. Est-il peut-être une mise à jour de correctif?
Vous devez vous connecter pour publier un commentaire.
Le problème est que je suis en utilisant un METTRE à la place d'un POSTE. Commons FileUpload est codé en dur à accepter les requêtes POST pour les fichiers.
Vérifier la isMultipartContent méthode là. Pour résoudre ce problème, soit l'utilisation d'un POST ou d'étendre cette classe et de remplacer cette méthode de travail comme vous le souhaitez.
J'ai ouvert FILEUPLOAD-214 pour cette question.
PUT
ne doit pas être utilisé avecMultipart
PUT
, et peut être ignoré en toute sécurité ici), et pourtant... les gens insistent sur le fait pas. Pour... une raison quelconque. Génial de voir la bêtise est bel et bien partout.Pour résoudre le problème, n'utilisez pas le printemps MultiPartHttpServerRequest, au lieu de prendre la demande en tant que HttpServletRequest, à l'aide de l'apache commons fileupload bibliothèque pour analyser la demande de METTRE la méthode, et le traitement du fichier. Voici un exemple de code:
Dans La Configuration.groovy
Assurez-vous que multipart est activé,
Dans le contrôleur ajouter de la méthode Post
avec ces derniers, j'ai pu télécharger le fichier, rien de Printemps de Sécurité.
vous pouvez prendre un coup d'oeil à https://github.com/joshlong/the-spring-tutorial qui a un exemple montrant comment la poste à Spring MVC, Spring Security OAuth activé. J'ai même utiliser HTML5 glisser-déposer pour déplacer l'image sur l'écran puis de le soumettre via ajax vers le serveur.