java - Spring Security 的 AJAX 请求给出 403 Forbidden

标签 java ajax spring spring-boot spring-security

我有一个基于spring boot、spring-security、thymeleaf的网站,在某些情况下我也使用ajax。

问题:

我在 Spring Security 中使用表单登录安全性。在浏览器中,登录后我可以使用 REST API (GET),但使用 ajax 时,即使我的 ajax 请求在 cookie 中包含 session ID,它也会返回 403

安全配置:

@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("/");

}

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);
}

}

-我的ajax代码:

$('.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);
              }
        })
    })

编辑 [GET] 请求工作正常,但 [PUT、POST、DELETE] 不起作用。

最佳答案

为什么.csrf().disable().cors()有效?

CSRF 代表跨站请求伪造

简单来说,它是一种随请求发送的 token ,用于防止攻击。为了使用 Spring Security CSRF 保护,我们首先需要确保对任何修改状态的内容使用正确的 HTTP 方法(PATCHPOSTPUTDELETE - 而不是 GET)。

一些框架通过使用户 session 无效来处理无效的 CSRF token ,但这会导致其自身的问题。相反,默认情况下 Spring Security 的 CSRF 保护将生成 HTTP 403 访问被拒绝

Ajax and JSON Requests

如果您使用 JSON,则无法在 HTTP 参数内提交 CSRF token 。相反,您可以在 HTTP header 中提交 token 。典型的模式是将 CSRF token 包含在元标记中

<meta name="_csrf" content="${_csrf.token}"/>
<meta name="_csrf_header" content="${_csrf.headerName}"/>

//jQuery
var token = $("meta[name='_csrf']").attr("content");
var header = $("meta[name='_csrf_header']").attr("content");

$(document).ajaxSend(function(e, xhr, options) {
    xhr.setRequestHeader(header, token);
});

关于java - Spring Security 的 AJAX 请求给出 403 Forbidden,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57994953/

相关文章:

java - 客户端服务器通信问题

asp.net-mvc - 带有 ASP.NET MVC Ajax 调用的全局 "Loading"通知

javascript - UI 开发 - JavaScript 与 Ajax

java - 关于线程安全的困惑 - SimpleDateFormat 示例

java - 在 Spring 中替换类别的标签系统 - Hibernate java 项目

java - 如何检测不明确的 DST 重叠?

java - 用什么代替 Class.newInstance()?

java - 检查一个单词是否在文本文件中

javascript - 更好地理解 AJAX

java - Spring 集成 : copy one inbound message to multiple outbound