一、门派之争:Spring Security 与 Shiro 的江湖地位
1. 设计哲学
- Spring Security
名门正派,深度融入 Spring 生态,招式复杂但体系完整,适合大型宗门(企业级应用)。 - Shiro
逍遥散修,轻量灵活,招式简单直接,适合独行侠客(小型项目或非 Spring 应用)。
2. 核心差异
// Spring Security 的配置像一本武功秘籍
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
// 需打通任督二脉(理解过滤器链)
}
// Shiro 的配置像一把瑞士军刀
@Bean
public ShiroFilterFactoryBean shiroFilter() {
// 即插即用,但拓展性有限
}
二、Spring Security 的「独孤九剑」:方法级权限
1. 起手式:开启招式开关
@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class MethodSecurityConfig {
// 解锁 @PreAuthorize 等剑招
}
2. 破剑式:精准拦截
// 招式1:剑气外放(表达式控制)
@PreAuthorize("hasRole('ADMIN') || #userId == principal.id")
public void deleteUser(Long userId) {
// 管理员或本尊可出招
}
// 招式2:以气御剑(自定义逻辑)
@Component("perm")
public class PermissionChecker {
public boolean isOwner(Long docId) {
// 乾坤大挪移:自定义权限规则
}
}
@PreAuthorize("@perm.isOwner(#docId)")
public Document getDoc(Long docId) { ... }
3. 御剑式:多剑齐发
// 招式组合:先验剑气(@Secured)
@Secured("ROLE_DEV")
public void deploy() { ... }
// 后发制人(@PostAuthorize)
@PostAuthorize("returnObject.status != 'SECRET'")
public Report getReport() { ... }
三、实战过招:权限控制的三种境界
1. 第一层:以名制敌(角色控制)
@PreAuthorize("hasRole('BOSS')")
public void raiseSalary() {
// 只有掌门可调用
}
2. 第二层:人剑合一(动态逻辑)
@PreAuthorize("#user.level > 5 && @perm.isVIP(#user)")
public void accessVIPArea(User user) {
// 内力(业务规则)与剑招结合
}
3. 第三层:无招胜有招(元注解)
@Target(METHOD)
@Retention(RUNTIME)
@PreAuthorize("hasPermission(#id, 'READ')")
public @interface CanRead { }
@CanRead
public File getFile(Long id) { ... }
四、避坑指南:江湖险恶
-
剑气反噬
- 避免在注解中写复杂业务逻辑
- 自定义表达式建议封装为 Bean
-
招式冲突
-
多个拦截器顺序用
@Order控制 -
禁用 CSRF 时需显式配置:
http.csrf().disable(); -
-
心法不匹配
-
测试时用
@WithMockUser模拟对手:
@Test @WithMockUser(roles = "GUEST") void testAccessDenied() { ... } -