Spring Security的AJAX请求给出403禁止 [英] AJAX request with Spring Security gives 403 Forbidden

查看:130
本文介绍了Spring Security的AJAX请求给出403禁止的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a website based on spring boot, spring-security, thymeleaf, I also use ajax in some cases.

问题:

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

I am using form login security in spring security. In the browser, after I login I can consume rest API (GET), but using ajax it returns 403 even if my ajax request contains session id in cookies.

安全配置:

@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我对其进行了正确的测试.

REST API I test it correctly.

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

  • 我的ajax请求标头如下: ajax请求标头
  • 编辑[GET]请求正常工作,[PUT,POST,DELETE]不起作用.

    EDIT The [GET] requests are working correctley put [PUT,POST,DELETE] Not work.

    推荐答案

    .csrf().disable().cors()为什么起作用?

    CSRF 代表跨站点请求伪造

    简单来说,它是一种与请求一起发送以防止攻击的令牌.为了使用Spring Security CSRF保护,我们首先需要确保对修改状态的任何内容使用正确的HTTP方法( PATCH POST PUT DELETE –不是 GET ).

    In simple words, it is one kind of token which is sent with the request to prevent the attacks. In order to use the Spring Security CSRF protection, we'll first need to make sure we use the proper HTTP methods for anything that modifies the state (PATCH, POST, PUT, and DELETE – not GET).

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

    Some frameworks handle invalid CSRF tokens by invaliding the user’s session, but this causes its own problems. Instead by default Spring Security’s CSRF protection will produce an HTTP 403 access denied.

    Ajax和JSON请求

    如果使用的是JSON,则无法在HTTP参数内提交CSRF令牌.相反,您可以在HTTP标头中提交令牌.一种典型的模式是将CSRF令牌包含在您的元标记中

    If you are using JSON, then it is not possible to submit the CSRF token within an HTTP parameter. Instead, you can submit the token within an HTTP header. A typical pattern would be to include the CSRF token within your meta tags

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

    这篇关于Spring Security的AJAX请求给出403禁止的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆