一、背景與目標
在Spring Boot應用開發中,接口級別的權限控制是系統安全的重要組成部分。本文將介紹一種簡單直接的接口角色授權檢查實現方案,適合快速開發和安全合規檢查場景。
二、技術方案概述
本方案采用自定義注解+攔截器的方式實現,具有以下特點:
零依賴(不引入Spring Security等重型框架)
代碼簡潔(總共不到100行核心代碼)
易于理解和使用
滿足基本的安全檢查要求
三、完整實現步驟
1. 創建權限注解
import java.lang.annotation.*;/*** 權限檢查注解*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface RequiredPermission {String value(); // 權限標識符,如"user:add"
}
2. 實現權限攔截器
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Method;/*** 權限檢查攔截器*/
@Component
public class PermissionInterceptor implements HandlerInterceptor {// 可以注入需要的服務(如用戶服務)@Autowiredprivate UserService userService;@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {if (!(handler instanceof HandlerMethod)) {return true;}HandlerMethod handlerMethod = (HandlerMethod) handler;Method method = handlerMethod.getMethod();// 獲取方法上的權限注解RequiredPermission permission = method.getAnnotation(RequiredPermission.class);if (permission == null) {return true; // 無權限注解則放行}String requiredPermission = permission.value();String token = request.getHeader("Authorization");// 實際項目中應從token解析用戶信息,這里簡化為直接判斷boolean hasPermission = checkPermission(token, requiredPermission);if (!hasPermission) {response.setStatus(HttpServletResponse.SC_FORBIDDEN);response.getWriter().write("Access denied: Required permission - " + requiredPermission);return false;}return true;}private boolean checkPermission(String token, String requiredPermission) {// 這里寫死檢查邏輯,實際項目應從數據庫或緩存獲取用戶權限if ("admin-token".equals(token)) {return true; // 管理員有所有權限} else if ("user-token".equals(token)) {return !"user:add".equals(requiredPermission); // 普通用戶不能新增用戶}return false;}
}
3. 注冊攔截器
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;@Configuration
public class WebConfig implements WebMvcConfigurer {@Autowiredprivate PermissionInterceptor permissionInterceptor;@Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(permissionInterceptor).addPathPatterns("/api/**"); // 攔截/api開頭的請求}
}
4. 在Controller中使用
import org.springframework.web.bind.annotation.*;@RestController
@RequestMapping("/api/user")
public class UserController {@PostMapping@RequiredPermission("user:add")public String addUser() {return "User added successfully";}@GetMapping@RequiredPermission("user:view")public String listUsers() {return "User list";}@PutMapping("/{id}")@RequiredPermission("user:edit")public String updateUser(@PathVariable Long id) {return "User updated";}@DeleteMapping("/{id}")@RequiredPermission("user:delete")public String deleteUser(@PathVariable Long id) {return "User deleted";}
}
四、方案特點與優勢
簡單直接:無需復雜配置,快速實現權限控制
靈活可控:可以自由定義權限標識和檢查邏輯
易于擴展:可以方便地替換為從數據庫檢查權限
符合RESTful:返回標準的HTTP狀態碼(403 Forbidden)
低侵入性:只需要添加注解,不影響業務邏輯代碼
五、進階優化方向
結合JWT:從token中解析用戶角色和權限
緩存優化:緩存用戶權限數據,減少數據庫查詢
動態權限:實現權限的動態配置和管理
日志記錄:記錄權限驗證失敗的訪問嘗試
白名單:添加無需權限檢查的接口白名單
六、測試驗證
可以使用Postman或curl進行測試:
# 管理員可以訪問所有接口
curl -X POST -H "Authorization: admin-token" http://localhost:8080/api/user# 普通用戶不能訪問添加接口
curl -X POST -H "Authorization: user-token" http://localhost:8080/api/user
# 返回: Access denied: Required permission - user:add# 普通用戶可以訪問查看接口
curl -X GET -H "Authorization: user-token" http://localhost:8080/api/user
# 返回: User list
七、總結
本文介紹的Spring Boot接口權限控制方案雖然簡單,但包含了權限控制的核心要素,能夠滿足基本的安全需求。對于快速開發和小型項目來說,這是一個輕量級且有效的解決方案。對于更復雜的企業級應用,建議在此基礎上進行擴展或考慮使用Spring Security等專業安全框架。