首页 > 解决方案 > Spring Security 阻止 js 发布查询以进行文件上传

问题描述

我创建了类似于https://www.callicoder.com/spring-boot-file-upload-download-rest-api-example/的应用程序, 但我使用 Spring Security,这是错误的原因(如果我全部删除 Spring Security正常工作): {"timestamp":"2018-08-20T09:26:44.223+0000","status":403,"error":"Forbidden","message":"Forbidden","path":"/uploadFile"}

为了避免这个问题,我必须改变什么?

文件控制器:

@RestController
public class FileController {

    private final FileStorageService fileStorageService;

    @Autowired
    public FileController(FileStorageService fileStorageService) {
        this.fileStorageService = fileStorageService;
    }

    @PostMapping("/uploadFile")
    public UploadFileResponse uploadFile(@RequestParam("file") MultipartFile file) {
        String filename = fileStorageService.storeFile(file);
        String fileDownloadUri = ServletUriComponentsBuilder.fromCurrentContextPath()
            .path("/downloadFile/")
            .path(filename)
            .toUriString();
        return new UploadFileResponse(
            filename,
            fileDownloadUri,
            file.getContentType(),
            file.getSize()
        );
    }
//...
}

upload-files.html 带有发送帖子查询的 vanila js 脚本:

<!DOCTYPE html>
<html>
<head>
    <meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0">
    <title>Spring Boot File Upload / Download Rest API Example</title>
    <link rel="stylesheet" href="/css/main.css" />
</head>
<body>
<div class="upload-container">
    <div class="upload-header">
        <h2>File Upload</h2>
    </div>
    <div class="upload-content">
        <div class="single-upload">
            <h3>Upload Single File</h3>
            <form id="singleUploadForm" name="singleUploadForm">
                <input id="singleFileUploadInput" type="file" name="file" class="file-input" required />
                <button type="submit" class="primary submit-btn">Submit</button>
            </form>
            <div class="upload-response">
                <div id="singleFileUploadError"></div>
                <div id="singleFileUploadSuccess"></div>
            </div>
        </div>
    </div>
</div>
</body>
<script>
    'use strict';

    var singleUploadForm = document.querySelector('#singleUploadForm');
    var singleFileUploadInput = document.querySelector('#singleFileUploadInput');
    var singleFileUploadError = document.querySelector('#singleFileUploadError');
    var singleFileUploadSuccess = document.querySelector('#singleFileUploadSuccess');

    function uploadSingleFile(file) {
        var formData = new FormData();
        formData.append("file", file);

        var xhr = new XMLHttpRequest();
        xhr.open("POST", "/uploadFile");

        xhr.onload = function() {
            console.log(xhr.responseText);
            var response = JSON.parse(xhr.responseText);
            if(xhr.status == 200) {
                singleFileUploadError.style.display = "none";
                singleFileUploadSuccess.innerHTML = "<p>File Uploaded Successfully.</p><p>DownloadUrl : <a href='" + response.fileDownloadUri + "' target='_blank'>" + response.fileDownloadUri + "</a></p>";
                singleFileUploadSuccess.style.display = "block";
            } else {
                singleFileUploadSuccess.style.display = "none";
                singleFileUploadError.innerHTML = (response && response.message) || "Some Error Occurred";
            }
        }

        xhr.send(formData);
    }

    singleUploadForm.addEventListener('submit', function(event){
        var files = singleFileUploadInput.files;
        if(files.length === 0) {
            singleFileUploadError.innerHTML = "Please select a file";
            singleFileUploadError.style.display = "block";
        }
        uploadSingleFile(files[0]);
        event.preventDefault();
    }, true);
</script>
</html>

更新

网络安全配置:

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    private static final String USER_NOT_FOUND_PASSWORD = "userNotFoundPassword";

    private final CustomUserDetailsService userDetailsService;

    @Autowired
    public WebSecurityConfig(CustomUserDetailsService userDetailsService) {
        this.userDetailsService = userDetailsService;
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userDetailsService)
            .passwordEncoder(getPasswordEncoder());
    }

    private PasswordEncoder getPasswordEncoder() {
        return new PasswordEncoder() {
            @Override
            public String encode(CharSequence charSequence) {
                return charSequence.toString();
            }

            @Override
            public boolean matches(CharSequence charSequence, String encoded) {
                return !encoded.equals(USER_NOT_FOUND_PASSWORD)
                    && BCrypt.checkpw(charSequence.toString(), encoded);
            }
        };
    }
}

标签: javascriptjavaspringspring-security

解决方案


 @Override
 public void configure(WebSecurity web) throws Exception {
                web.ignoring()
                // Spring Security should completely ignore URLs starting with /resources/
                                .antMatchers("/resources/**");
 }

  @Override
  protected void configure(HttpSecurity http) throws Exception {
                    http.authorizeRequests().antMatchers("/public/**").permitAll().anyRequest()
                                    .hasRole("USER").and()
                                    // Possibly more configuration ...
                                    .formLogin() // enable form based log in
                                    // set permitAll for all URLs associated with Form Login
                                    .permitAll();
 }

您应该向 url 添加访问权限,否则 spring security 将不允许访问。


推荐阅读