Muh*_*edH 5 java ajax spring spring-security spring-boot
我有一个基于spring boot、spring-security、thymeleaf的网站,在某些情况下我也使用ajax。
问题:我在 Spring Security 中使用表单登录安全性。在浏览器中,登录后我可以使用rest API (GET),但是使用Ajax,它会返回http 403错误,即使我的Ajax请求在cookie中包含会话id。
安全配置:
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/admin/**").hasRole("ADMIN")
.antMatchers("/rest/**").hasRole("ADMIN")
.anyRequest().permitAll()
.and()
.formLogin().loginPage("/sign-in-up")
.loginProcessingUrl("/signInProcess").usernameParameter("phone").and().logout()
.logoutRequestMatcher(new AntPathRequestMatcher("/logout")).logoutSuccessUrl("/");
}
Run Code Online (Sandbox Code Playgroud)
REST API 我测试正确:
@RestController
@RequestMapping("rest/categories")
public class CategoriesRest {
@Autowired
private CategoryService categoryService;
@GetMapping("/")
public ResponseEntity<List<Category>> findAll() {
List<Category> all = categoryService.getAll();
if (all.isEmpty()) {
return new ResponseEntity<>(HttpStatus.NO_CONTENT);
}
return new ResponseEntity<>(all, HttpStatus.OK);
}
@GetMapping("/{id}")
public ResponseEntity<Category> findById(@PathVariable int id) {
Category obj = categoryService.get(id);
if (obj == null) {
return new ResponseEntity<>(HttpStatus.NO_CONTENT);
}
return new ResponseEntity<>(obj, HttpStatus.OK);
}
@PostMapping("/")
public ResponseEntity<Category> createMainSlider(@RequestBody Category obj) {
System.out.println("-------rest Post");
return new ResponseEntity<>(categoryService.add(obj), HttpStatus.CREATED);
}
@PutMapping("/{id}")
public ResponseEntity<Category> update(@RequestBody Category obj, @PathVariable int id) {
Category obj1 = categoryService.update(obj);
System.out.println(obj);
return new ResponseEntity<>(obj1, HttpStatus.OK);
}
@DeleteMapping("/{id}")
public ResponseEntity<Category> deleteEmp(@PathVariable int id) {
categoryService.delete(id);
return new ResponseEntity<>(HttpStatus.NO_CONTENT);
}
}
Run Code Online (Sandbox Code Playgroud)
我的阿贾克斯代码:
$('.deleteBtn').bind('click',function(e){
e.preventDefault();
$.ajax({
type:'DELETE',
url : "/rest/categories/"+$(e.currentTarget).data('id'),
xhrFields: {
withCredentials: true
},
success : function(result) {
location.reload();
console.log(result);
},
error : function(e) {
alert("Error!")
console.log("ERROR: ", e);
}
})
})
Run Code Online (Sandbox Code Playgroud)
我的ajax请求头是这样的:
编辑:[GET]请求正常工作,但[PUT,POST,DELETE]不起作用。
为什么.csrf().disable().cors()有效?
CSRF代表跨站请求伪造
\n\n简单来说,它是一种随请求发送的令牌,用于防止攻击。为了使用 Spring Security CSRF 保护,我们首先需要确保对任何修改状态的内容使用正确的 HTTP 方法(PATCH、POST、PUT和DELETE\xe2\x80\x93 不是GET)。
某些框架通过使 user\xe2\x80\x99s 会话无效来处理无效的 CSRF 令牌,但这会导致其自身的问题。相反,默认情况下 Spring Security\xe2\x80\x99s CSRF 保护将产生HTTP 403 accessied。
\n\n\n\n如果您使用 JSON,则无法在 HTTP 参数中提交 CSRF 令牌。相反,您可以在 HTTP 标头中提交令牌。典型的模式是将 CSRF 令牌包含在元标记中
\n\n<meta name="_csrf" content="${_csrf.token}"/>\n<meta name="_csrf_header" content="${_csrf.headerName}"/>\n\n//jQuery\nvar token = $("meta[name=\'_csrf\']").attr("content");\nvar header = $("meta[name=\'_csrf_header\']").attr("content");\n\n$(document).ajaxSend(function(e, xhr, options) {\n xhr.setRequestHeader(header, token);\n});\nRun Code Online (Sandbox Code Playgroud)\n
| 归档时间: |
|
| 查看次数: |
8589 次 |
| 最近记录: |