为什么我必须禁用 csrf 令牌才能使用 postman 获取 post 数据?
Why I have to disable csrf token in order to post data using postman?
我正在尝试对我的服务器 (localhost) 进行一些 REST 调用,GET 方法正常工作但是,当我尝试通过 postman 方法 post JSON 对象时POST、PUT、DELETE 不起作用它说 "Request method POST not supported" 当我再次尝试在 http 上禁用 csrf 令牌时,一切正常。
这是我的休息控制器。
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.kish.Service.CustomerService;
import com.kish.entity.Customer;
@RestController
@RequestMapping("/api")
public class CRMRestController {
public CRMRestController() {
}
@Autowired
private CustomerService customerService;
@GetMapping("/customers")
public List<Customer> getCustomers() {
return customerService.getCustomers();
}
@GetMapping("/customers/{customerId}")
public Customer getCustomer(@PathVariable int customerId) {
if((customerService.getCustomer(customerId) == null)) {
throw new CustomerNotFoundException("No customer found in the database" + customerId);
}
return customerService.getCustomer(customerId);
}
@PostMapping("/customers")
public Customer addCustomer(@RequestBody Customer customer) {
customer.setId(0);
customerService.saveCustomer(customer);
return customer;
}
@PutMapping("/customers")
public Customer updateCustomer(@RequestBody Customer customer) {
customerService.saveCustomer(customer);
return customer;
}
@DeleteMapping("/customers/{customerId}")
public String deleteCustomer(@PathVariable int customerId) {
if((customerService.getCustomer(customerId)) == null) throw new CustomerNotFoundException("request valid data");
customerService.deleteCustomer(customerId);
return "deleted customer id is " + customerId;
}
}
安全配置方法
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable();
http.authorizeRequests() // restrict access based on the request coming in.
.antMatchers("/customer/list").hasRole("EMPLOYEE")
.antMatchers("/customer/Actions/**").hasAnyRole("ADMIN","MANAGER")
.and()
.formLogin()
.loginPage("/showMyLoginForm")
.loginProcessingUrl("/authenticateTheUser") // it checks the
.permitAll()
.and()
.logout()
.permitAll()
.and().exceptionHandling().accessDeniedPage("/access-denied"); // Spring Security uses this page for Access denied pages
}
所以我的问题是为什么我必须禁用 csrf 才能进行 POST 调用而不是 GET 调用?还是我遗漏了什么?
简答
CSRF 只关心可以操作数据的动作;用于此的 http 动词是:POST、PUT、PATCH 和 DELETE。 CSRF 的工作不是保护您免受仅旨在查看数据的请求:GET、HEAD、OPTIONS、TRACE。
长答案
Spring 安全性通过实施同步器令牌模式默认启用 CSRF。它的实际含义是什么:当您启动 session 时,您将收到一个令牌(随机生成),每次都需要将其作为 X-XSRF-TOKEN
(或类似的东西)header 传递您发出 POST、PUT、PATCH 或 DELETE 请求的时间。如果令牌是 not present
,或者如果令牌存在但 not matched
到 Spring 安全生成的令牌,则不允许您发出该请求。
您现在遇到的问题是因为您没有通过 Postman 传递 CSRF header。
现在,有一个问题,你是否真的需要 CSRF 保护?这取决于您如何在客户端中存储身份验证令牌。我建议看一下 CSRF 保护,如果不需要,您可以将其禁用。
我正在尝试对我的服务器 (localhost) 进行一些 REST 调用,GET 方法正常工作但是,当我尝试通过 postman 方法 post JSON 对象时POST、PUT、DELETE 不起作用它说 "Request method POST not supported" 当我再次尝试在 http 上禁用 csrf 令牌时,一切正常。
这是我的休息控制器。
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.kish.Service.CustomerService;
import com.kish.entity.Customer;
@RestController
@RequestMapping("/api")
public class CRMRestController {
public CRMRestController() {
}
@Autowired
private CustomerService customerService;
@GetMapping("/customers")
public List<Customer> getCustomers() {
return customerService.getCustomers();
}
@GetMapping("/customers/{customerId}")
public Customer getCustomer(@PathVariable int customerId) {
if((customerService.getCustomer(customerId) == null)) {
throw new CustomerNotFoundException("No customer found in the database" + customerId);
}
return customerService.getCustomer(customerId);
}
@PostMapping("/customers")
public Customer addCustomer(@RequestBody Customer customer) {
customer.setId(0);
customerService.saveCustomer(customer);
return customer;
}
@PutMapping("/customers")
public Customer updateCustomer(@RequestBody Customer customer) {
customerService.saveCustomer(customer);
return customer;
}
@DeleteMapping("/customers/{customerId}")
public String deleteCustomer(@PathVariable int customerId) {
if((customerService.getCustomer(customerId)) == null) throw new CustomerNotFoundException("request valid data");
customerService.deleteCustomer(customerId);
return "deleted customer id is " + customerId;
}
}
安全配置方法
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable();
http.authorizeRequests() // restrict access based on the request coming in.
.antMatchers("/customer/list").hasRole("EMPLOYEE")
.antMatchers("/customer/Actions/**").hasAnyRole("ADMIN","MANAGER")
.and()
.formLogin()
.loginPage("/showMyLoginForm")
.loginProcessingUrl("/authenticateTheUser") // it checks the
.permitAll()
.and()
.logout()
.permitAll()
.and().exceptionHandling().accessDeniedPage("/access-denied"); // Spring Security uses this page for Access denied pages
}
所以我的问题是为什么我必须禁用 csrf 才能进行 POST 调用而不是 GET 调用?还是我遗漏了什么?
简答
CSRF 只关心可以操作数据的动作;用于此的 http 动词是:POST、PUT、PATCH 和 DELETE。 CSRF 的工作不是保护您免受仅旨在查看数据的请求:GET、HEAD、OPTIONS、TRACE。
长答案
Spring 安全性通过实施同步器令牌模式默认启用 CSRF。它的实际含义是什么:当您启动 session 时,您将收到一个令牌(随机生成),每次都需要将其作为 X-XSRF-TOKEN
(或类似的东西)header 传递您发出 POST、PUT、PATCH 或 DELETE 请求的时间。如果令牌是 not present
,或者如果令牌存在但 not matched
到 Spring 安全生成的令牌,则不允许您发出该请求。
您现在遇到的问题是因为您没有通过 Postman 传递 CSRF header。
现在,有一个问题,你是否真的需要 CSRF 保护?这取决于您如何在客户端中存储身份验证令牌。我建议看一下 CSRF 保护,如果不需要,您可以将其禁用。