SpringBoot越權(quán)和數(shù)據(jù)權(quán)限控制的實現(xiàn)方案(最新整理)
CodingTechWork
引言
在基于 Java 的開發(fā)中,通常使用 Spring 框架來實現(xiàn)權(quán)限管理、注解和切面編程。為了實現(xiàn)您提到的權(quán)限控制邏輯,我們可以按照以下步驟來實現(xiàn)注解、切面以及權(quán)限檢查。以下是一個詳細的實現(xiàn)方案:
定義權(quán)限注解
首先,我們需要定義一個自定義的注解 @PermissionCheck,這個注解會包含操作類型(CRUD)、資產(chǎn)ID和資產(chǎn)名稱作為入?yún)???梢詤⒖家韵麓a來定義這個注解:
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
// 該注解作用于方法
@Target(ElementType.METHOD)
// 運行時生效
@Retention(RetentionPolicy.RUNTIME)
public @interface PermissionCheck {
// 操作類型,默認為 READ
String operation() default "READ";
// 資產(chǎn) ID
String assetId() default "";
// 資產(chǎn)名稱
String assetName() default "";
// 還可以擴展其他的字段
... ...
}在 Controller 方法中使用注解
然后,在需要進行權(quán)限驗證的 Controller 方法中,我們可以使用 @PermissionCheck 注解來指定需要的操作類型、資產(chǎn) ID 和資產(chǎn)名稱。
@RestController
@RequestMapping("/assets")
public class AssetController {
// 只允許讀取權(quán)限
@PermissionCheck(operation = "READ", assetId = "asset123", assetName = "assetA")
@GetMapping("/view")
public Asset viewAsset(@RequestParam String assetId) {
// 業(yè)務(wù)邏輯
return assetService.getAssetById(assetId);
}
// 只允許創(chuàng)建操作
@PermissionCheck(operation = "CREATE", assetId = "asset124", assetName = "assetB")
@PostMapping("/create")
public Asset createAsset(@RequestBody Asset asset) {
// 業(yè)務(wù)邏輯
return assetService.createAsset(asset);
}
}切面(Aspect)實現(xiàn)權(quán)限驗證
接下來,我們要創(chuàng)建一個切面類,利用 AOP(面向切面編程)攔截標記了 @PermissionCheck 注解的方法。通過切面,我們可以獲取用戶的角色信息,判斷用戶是否有權(quán)限進行特定操作,并根據(jù)需要拋出異常。
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;
@Aspect
@Component
public class PermissionAspect {
// 用于獲取當前用戶的權(quán)限信息
@Autowired
private UserService userService;
// 切入點,攔截標注 @PermissionCheck 的方法
@Pointcut("@annotation(permissionCheck)")
public void checkPermission(PermissionCheck permissionCheck) {}
// 在方法執(zhí)行前進行權(quán)限校驗
@Before("checkPermission(permissionCheck)")
public void checkPermissionBefore(PermissionCheck permissionCheck) throws Exception {
String operation = permissionCheck.operation();
String assetId = permissionCheck.assetId();
String assetName = permissionCheck.assetName();
// 獲取當前登錄用戶的 ID
String userId = SecurityContextHolder.getContext().getAuthentication().getName();
// 獲取當前用戶的角色:可以是只讀或正常用戶等
User user = userService.getUserById(userId);
if ("READ".equals(operation) && !user.isReadOnly()) {
// 如果是只讀用戶但操作不是 READ,拋出異常
throw new PermissionException("只讀用戶不允許進行此操作");
}
// 檢查操作權(quán)限:只允許特定用戶對特定資產(chǎn)進行 CREATE/UPDATE/DELETE 操作
if (!"READ".equals(operation)) {
if (!hasPermission(userId, assetId, assetName)) {
throw new PermissionException("用戶沒有訪問該資產(chǎn)的權(quán)限");
}
}
}
private boolean hasPermission(String userId, String assetId, String assetName) {
// 查詢數(shù)據(jù)庫,檢查當前用戶是否對給定的資產(chǎn) ID 或資產(chǎn)名稱有權(quán)限
return userService.hasAssetPermission(userId, assetId, assetName);
}
}4. 用戶權(quán)限服務(wù)實現(xiàn)
在上面的切面代碼中,我們調(diào)用了 userService 來判斷當前用戶是否有權(quán)限操作某個資產(chǎn)。UserService 需要實現(xiàn)以下邏輯:
@Service
public class UserService {
// 根據(jù)用戶 ID 查詢用戶信息,判斷是否為只讀用戶
public User getUserById(String userId) {
// 假設(shè)從數(shù)據(jù)庫獲取用戶信息
return userRepository.findById(userId).orElseThrow(() -> new UserNotFoundException("用戶不存在"));
}
// 查詢用戶是否有訪問某個資產(chǎn)的權(quán)限
public boolean hasAssetPermission(String userId, String assetId, String assetName) {
// 這里我們可以查詢數(shù)據(jù)庫,檢查當前用戶是否有對應(yīng)資產(chǎn)的權(quán)限
return permissionRepository.existsByUserIdAndAssetIdOrAssetName(userId, assetId, assetName);
}
}異常處理
當權(quán)限不滿足時,我們需要拋出自定義的異常并進行全局處理。
public class PermissionException extends RuntimeException {
public PermissionException(String message) {
super(message);
}
}
@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(PermissionException.class)
@ResponseStatus(HttpStatus.FORBIDDEN)
public ResponseEntity<String> handlePermissionException(PermissionException ex) {
return ResponseEntity.status(HttpStatus.FORBIDDEN).body(ex.getMessage());
}
}其他相關(guān)注意事項
- 只讀用戶的限制:在
checkPermissionBefore方法中,我們通過判斷operation字段來確定是否是只讀用戶操作。若是只讀用戶,但操作嘗試修改數(shù)據(jù)(CREATE/UPDATE/DELETE),則會拋出異常。 - 權(quán)限查詢優(yōu)化:在實際項目中,查詢數(shù)據(jù)庫是否有權(quán)限時,可以使用緩存來提高查詢性能,避免頻繁的數(shù)據(jù)庫訪問。
- 全局異常處理:通過
@ControllerAdvice和自定義異常類,能夠確保權(quán)限錯誤的響應(yīng)更加友好和統(tǒng)一。
總結(jié)
通過以上的實現(xiàn),我們使用了自定義注解、切面編程和用戶權(quán)限服務(wù)的組合來對方法進行權(quán)限控制,確保只讀用戶無法進行修改操作,同時判斷其他用戶是否有權(quán)限訪問特定的資產(chǎn)。這樣的方法可以靈活擴展,方便在大型系統(tǒng)中進行細粒度的權(quán)限控制。
到此這篇關(guān)于SpringBoot越權(quán)和數(shù)據(jù)權(quán)限控制的實現(xiàn)方案(最新整理)的文章就介紹到這了,更多相關(guān)SpringBoot 權(quán)限控制內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- Springboot集成shiro之登錄攔截/權(quán)限控制方式
- SpringBoot整合Spring?Security實現(xiàn)權(quán)限控制的全過程
- SpringBoot集成Sa-Token實現(xiàn)權(quán)限認證流程入門教程
- springboot整合Sa-Token實現(xiàn)登錄認證和權(quán)限校驗的詳細流程
- springboot3整合SpringSecurity實現(xiàn)登錄校驗與權(quán)限認證
- SpringBoot?使用?Sa-Token?完成權(quán)限認證的操作方法
- SpringBoot整合Springsecurity實現(xiàn)數(shù)據(jù)庫登錄及權(quán)限控制功能
- 基于SpringBoot、SpringSecurity、JWT、RBAC搭建一套可落地的權(quán)限系統(tǒng)
相關(guān)文章
如何在Spring?Boot框架中使用攔截器實現(xiàn)URL限制
在Spring?Boot框架中,您可以使用攔截器(Interceptor)來控制限制URL列表,本文通過一個簡單的示例給大家介紹Spring?Boot?攔截器實現(xiàn)URL限制的操作方法,感興趣的朋友跟隨小編一起看看吧2023-08-08
SpringMVC中的HandlerMapping和HandlerAdapter詳解
這篇文章主要介紹了SpringMVC中的HandlerMapping和HandlerAdapter詳解,在Spring MVC中,HandlerMapping(處理器映射器)用于確定請求處理器對象,請求處理器可以是任何對象,只要它們使用了@Controller注解或注解@RequestMapping,需要的朋友可以參考下2023-08-08
利用Java如何實現(xiàn)將二維數(shù)組轉(zhuǎn)化為鏈式儲存
鏈式結(jié)構(gòu)不要求邏輯上相鄰的節(jié)點在物理位置上也相鄰,節(jié)點間的邏輯關(guān)系是由附加的指針字段表示的,通常借助于程序設(shè)計中的指針結(jié)構(gòu)來實現(xiàn),這篇文章主要給大家介紹了關(guān)于利用Java如何實現(xiàn)將二維數(shù)組轉(zhuǎn)化為鏈式儲存的相關(guān)資料,需要的朋友可以參考下2021-12-12
MyBatis中#{}?和?${}?的區(qū)別和動態(tài)?SQL詳解
這篇文章主要介紹了MyBatis中#{}和${}的區(qū)別,包括參數(shù)傳遞、安全性、性能等方面,然后詳細介紹了如何使用#{}和${}進行排序、模糊查詢、動態(tài)SQL、數(shù)據(jù)庫連接池等操作,最后,總結(jié)了注解方式的動態(tài)SQL,感興趣的朋友跟隨小編一起看看吧2024-11-11
springboot vue完成編輯頁面發(fā)送接口請求功能
這篇文章主要為大家介紹了springboot+vue完成編輯頁發(fā)送接口請求功能,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2022-05-05

