簡體   English   中英

Spring Security的AJAX請求給出403禁止

[英]AJAX request with Spring Security gives 403 Forbidden

我有一個基於spring boot,spring-security,thymeleaf的網站,在某些情況下,我還使用ajax。

問題:

我在Spring Security中使用表單登錄安全性。 在瀏覽器中,登錄后我可以使用rest API(GET),但即使我的ajax請求在cookie中包含會話ID,也可以使用ajax返回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解決了這個問題,我添加了這個

.csrf()。disable()。cors()

所以在我的春季安全配置中:

        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("/")
            .and()
            .csrf().disable().cors();

======編輯:
@Patel回答了一個有用的解釋...感謝他

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

CSRF代表跨站點請求偽造

簡而言之,它是與請求一起發送以防止攻擊的令牌。 為了使用Spring Security CSRF保護,我們首先需要確保對更改狀態的任何內容使用正確的HTTP方法( PATCHPOSTPUTDELETE ,而不是GET )。

一些框架通過使用戶會話無效來處理無效的CSRF令牌,但這會導致其自身的問題。 相反,默認情況下,Spring Security的CSRF保護將產生拒絕HTTP 403訪問

Ajax和JSON請求

如果使用的是JSON,則無法在HTTP參數內提交CSRF令牌。 相反,您可以在HTTP標頭中提交令牌。 一種典型的模式是在您的元標記中包含CSRF令牌

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM