SprngBootを使用してWebアプリケーションを作成しています。
ファイルアップロード機能を実装したいのですが、SpringSecurityを使用していることで403エラーとなってしまいます。
エラーメッセージ:
There was an unexpected error (type=Forbidden, status=403).
MultipartFilterを登録することで解決できるとドキュメントにはあるのですが解決できませんでした…
https://spring.pleiades.io/spring-security/site/docs/current/reference/html5/#servlet-csrf-considerations-multipart
問題解決のためにサンプルアプリを作成しなおして動作を確認してみましたが、SpringSecurityを導入するとやはりエラーになります。
わかるかたいらっしゃれば回答よろしくお願いいたします。
index
1<!DOCTYPE html> 2<html xmlns:th="http://www.thymeleaf.org/"> 3<head> 4<meta charset="UTF-8"> 5<title>ファイルアップロードのサンプル</title> 6</head> 7<body> 8<p th:if="${error}" th:text="${error}">エラーメッセージ</p> 9<form action="/upload" method="post" enctype="multipart/form-data"> 10 アップロードするJPEGファイルを選択してください<br> 11 <input type="file" name="file" accept="image/jpeg"> 12 <input type="submit"> 13</form> 14<p> 15 <img src="/images/picture.jpg"> 16</p> 17<p><a href="/test">テストページへ</a></p> 18</body> 19</html>
Sample05Application
1package com.example.demo; 2 3import java.io.File; 4 5import org.springframework.boot.SpringApplication; 6import org.springframework.boot.autoconfigure.SpringBootApplication; 7import org.springframework.context.annotation.Bean; 8 9@SpringBootApplication.java 10public class Sample05Application { 11 12 public static void main(String[] args) { 13 SpringApplication.run(Sample05Application.class, args); 14 } 15 16 @Bean 17 public AppConfig appConfig() { 18 // Webアプリケーションはアプリケーション実行ディレクトリとは別のディレクトリで実行される 19 // 起動時のディレクトリをAppConfigのimageDirフィールドに保持しておく 20 File imageDir = new File("images"); 21 imageDir = imageDir.getAbsoluteFile(); 22 23 // imagesフォルダがなかったら作成する 24 if (!imageDir.exists()) { 25 imageDir.mkdir(); 26 } 27 28 AppConfig appConfig = new AppConfig(); 29 appConfig.setImageDir(imageDir); 30 return appConfig; 31 } 32} 33
Sample05Controller
1package com.example.demo; 2 3import java.io.File; 4import java.io.IOException; 5 6import org.springframework.beans.factory.annotation.Autowired; 7import org.springframework.stereotype.Controller; 8import org.springframework.ui.Model; 9import org.springframework.web.bind.annotation.GetMapping; 10import org.springframework.web.bind.annotation.PostMapping; 11import org.springframework.web.bind.annotation.RequestParam; 12import org.springframework.web.multipart.MultipartFile; 13 14@Controller 15public class Sample05Controller { 16 17 @Autowired 18 private AppConfig appConfig; 19 20 @GetMapping("/") 21 public String index() { 22 return "index"; 23 } 24 25 @PostMapping("/upload") 26 public String upload(@RequestParam MultipartFile file, Model model) { 27 // ファイルを選択せずにフォームを送信したかの確認 28 if (file.isEmpty()) { 29 model.addAttribute("error", "ファイルを指定してください"); 30 return "index"; 31 } 32 33 // アップロードされたファイルを指定の名前で保存 34 File dest = new File(appConfig.getImageDir(), "picture.jpg"); 35 try { 36 file.transferTo(dest); 37 } catch (IllegalStateException e) { 38 // TODO 自動生成された catch ブロック 39 e.printStackTrace(); 40 } catch (IOException e) { 41 // TODO 自動生成された catch ブロック 42 e.printStackTrace(); 43 } 44 return "index"; 45 } 46 47 @GetMapping("/test") 48 public String test() { 49 return "testpage"; 50 } 51 52} 53
AppConfig
1package com.example.demo; 2 3import java.io.File; 4 5import lombok.Data; 6 7@Data 8public class AppConfig { 9 private File imageDir; 10}
WebSecurityConfig
1package com.example.demo; 2 3import org.springframework.security.config.annotation.web.builders.HttpSecurity; 4import org.springframework.security.config.annotation.web.builders.WebSecurity; 5import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; 6import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; 7 8@EnableWebSecurity 9public class WebSecurityConfig extends WebSecurityConfigurerAdapter { 10 11 @Override 12 public void configure(WebSecurity web) { 13 web.ignoring().antMatchers("/css/**", "/html/**", "/images/**"); 14 } 15 16 @Override 17 protected void configure(HttpSecurity http) throws Exception { 18 19 http.authorizeRequests().antMatchers("/").permitAll(); 20 } 21}
■以下、multipartfilter設定。
②も試しましたがダメでした…
SecurityWebApplicationInitializer
1package com.example.demo; 2 3import java.util.EnumSet; 4 5import javax.servlet.DispatcherType; 6import javax.servlet.ServletContext; 7 8import org.springframework.core.annotation.Order; 9import org.springframework.security.web.context.AbstractSecurityWebApplicationInitializer; 10import org.springframework.web.multipart.support.MultipartFilter; 11 12public class SecurityWebApplicationInitializer extends AbstractSecurityWebApplicationInitializer{ 13// @Override …⓶ 14// protected void beforeSpringSecurityFilterChain(ServletContext servletContext) { 15// System.out.println("secチェック"); 16// final MultipartFilter multipartFilter = new MultipartFilter(); 17// servletContext.addFilter("multipartFilter", multipartFilter) 18// .addMappingForUrlPatterns( 19// EnumSet.allOf(DispatcherType.class), false, "/*"); 20// } 21 @Override 22 protected void beforeSpringSecurityFilterChain(ServletContext servletContext) { 23 insertFilters(servletContext, new MultipartFilter()); 24 } 25} 26
■spring.web を使用しているためweb.xmlがないので以下を記述
参考:http://taktos.hatenablog.com/entry/2014/05/16/Spring_Security%E3%81%AECSRF%E5%AF%BE%E7%AD%96%E3%81%A8Servlet_3.0%E3%81%AEMultipart%E3%82%92Java_Config%E3%81%A7%E8%A8%AD%E5%AE%9A%E3%81%99%E3%82%8B
WebAppInitializer
1package com.example.demo; 2 3import javax.servlet.MultipartConfigElement; 4import javax.servlet.ServletRegistration.Dynamic; 5 6import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer; 7 8public class WebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer { 9 10 @Override 11 protected void customizeRegistration(Dynamic registration) { 12 System.out.println("webチェック"); 13 registration.setMultipartConfig(new MultipartConfigElement( 14 System.getProperty("java.io.tmpdir"), -1, -1, 1024 * 1024)); 15 } 16 17 @Override 18 protected Class<?>[] getRootConfigClasses() { 19 return new Class[] {AppConfig.class}; 20 } 21 22 @Override 23 protected Class<?>[] getServletConfigClasses() { 24 return new Class[] {WebConfig.class}; 25 } 26 27 @Override 28 protected String[] getServletMappings() { 29 return new String[] {"/"}; 30 } 31}
回答2件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2020/09/28 13:07
2020/09/28 15:00
2020/09/28 15:44
2020/09/30 13:54