[英]Spring security Role based HTTP request Authorization
我在從庫存中刪除項目以及在數據庫中創建新資源時收到 403 禁止,下面是我的配置和我編寫的控制器。
Web 安全配置類:
package com.inventoryservice.config;
import org.springframework.context.annotation.Bean;
import org.springframework.http.HttpMethod;
import org.springframework.security.authorization.AuthorityAuthorizationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.password.NoOpPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()
.withUser("test")
.password("test_pass")
.roles("ADMIN")
.and()
.withUser("store")
.password("store_pass")
.roles("USER");
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests()
.antMatchers(HttpMethod.DELETE, "/items-management").hasRole("ADMIN")
.antMatchers(HttpMethod.POST, "/items-management").hasAnyRole("ADMIN","USER")
.antMatchers(HttpMethod.GET, "/items-management").permitAll()
.anyRequest().authenticated();
}
@Bean
public PasswordEncoder passwordEncoder() {
return NoOpPasswordEncoder.getInstance();
}
}
庫存控制器:
它的所有端點都配置有從服務中獲取的數據庫記錄
package com.inventoryservice.controller;
import com.inventoryservice.dto.request.InventoryRequestDto;
import com.inventoryservice.dto.response.InventoryItemDto;
import com.inventoryservice.dto.response.InventoryResponseDto;
import com.inventoryservice.entity.Inventory;
import com.inventoryservice.service.ItemService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/items-management")
public class InventoryController {
private ItemService itemService;
@Autowired
public InventoryController(ItemService itemService) {
this.itemService = itemService;
}
@GetMapping
public ResponseEntity<InventoryResponseDto> getItems() {
return new ResponseEntity(
InventoryResponseDto.builder()
.lines(itemService.getItems())
.build()
, HttpStatus.OK
);
}
@PostMapping
public ResponseEntity<InventoryResponseDto> create(@RequestBody InventoryRequestDto inventory) {
return new ResponseEntity(
InventoryResponseDto
.builder()
.lines(itemService.create(inventory.getLines()))
.build()
, HttpStatus.CREATED
);
}
@DeleteMapping
public ResponseEntity delete(@RequestBody InventoryItemDto inventoryItemDto) {
itemService.deleteItems(
inventoryItemDto.getItemIds()
);
return ResponseEntity.ok(inventoryItemDto);
}
}
我遇到過這個問題,因為在 Spring Security 中,針對跨站點請求偽造 (CSRF) 攻擊的保護是默認啟用的,該攻擊旨在誘騙用戶在經過身份驗證的應用程序中執行某些操作。
CSRF 保護旨在防止不良的變異行為,因此您的 POST 請求失敗。 有關 CSRF 的更多信息,當禁用 CSRF 保護是合理的時, 請參閱文檔。
現在,只是為了測試您的端點,您可以像這樣禁用 CSRF:
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests()
.antMatchers(HttpMethod.DELETE, "/items-management").hasRole("ADMIN")
.antMatchers(HttpMethod.POST, "/items-management").hasAnyRole("ADMIN","USER")
.antMatchers(HttpMethod.GET, "/items-management").permitAll()
.anyRequest().authenticated()
.csrf().disable(); // <- add this line
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.