javascript - 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);
}
};
}
}
解决方案
@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 将不允许访问。
推荐阅读
- python - 如何在熊猫中编写迭代公式?
- variables - 菜单变量不在 Haskell 范围内
- image - 如何在 Flutter MultiImagePicker 中指定照片的质量?
- angular - Angular Firestore adding rules how to send request.auth value
- curl - 在 C++ 中使用 Curl 时出现错误:“http 代码 501:未实现”
- categories - 将 Outlook 类别分配给带有按钮的 RibbonMenu
- c# - 如何使用 xamarin 表单在 WKWebview 中设置 cookie
- tensorflow - 如何在 Tensorflow 2 中实现稀疏嵌入,如 Pytorch Embedding(sparse=True)?
- android - 自定义 AndroidJUnitRunner 依赖注入
- javascript - 一段时间后,Javascript 函数执行时间增加 10 倍