【Spring 注解详解】@PreAuthorize(“@pms.hasPermission(‘user_add‘)“)

内容分享2小时前发布
0 0 0

背景


@PreAuthorize("@pms.hasPermission('user_add')")
Spring Security 框架中的一个注解,用于在方法级别进行权限控制。它的作用是 在执行被注解的方法之前,检查当前用户是否拥有指定的权限,如果没有权限则抛出
AccessDeniedException


代码解析

1.
@PreAuthorize
注解

作用:Spring Security 提供的 方法级安全注解,用于在方法调用前进行权限校验。类似注解

@PostAuthorize
:方法执行后校验权限(较少用)。
@Secured
:更简单的权限控制(但不如
@PreAuthorize
灵活)。


2.
@pms.hasPermission('user_add')


@pms
:这是一个 SpEL(Spring Expression Language)表达式,引用了一个名为
pms
的 Spring Bean。
hasPermission('user_add')
:调用
pms
Bean 的
hasPermission
方法,检查当前用户是否拥有
'user_add'
权限。


底层原理

Spring Security 执行流程

当调用被
@PreAuthorize
注解的方法时,Spring Security 会先解析 SpEL 表达式。它会查找
pms
Bean(通常是一个自定义的权限管理服务)。调用
pms.hasPermission('user_add')
,返回
true
(允许访问)或
false
(拒绝访问)。


pms
Bean 的典型实现

通常是一个自定义的权限服务,例如:


@Service("pms")
public class PermissionService {
    public boolean hasPermission(String permission) {
        // 1. 获取当前用户(从 SecurityContext)
        Authentication auth = SecurityContextHolder.getContext().getAuthentication();
        
        // 2. 检查用户是否拥有该权限(可能查数据库、Redis 或内存缓存)
        return auth.getAuthorities().stream()
            .anyMatch(auth -> auth.getAuthority().equals(permission));
    }
}

也可以集成 RBAC(基于角色的权限控制),例如:


public boolean hasPermission(String permission) {
    UserDetails user = (UserDetails) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
    return user.getAuthorities().stream()
        .anyMatch(auth -> auth.getAuthority().equals("ROLE_ADMIN") || auth.getAuthority().equals(permission));
}

使用场景

适用场景
限制某些方法只能由特定权限的用户调用(如
user_add

user_delete
)。动态权限控制(如基于数据库的权限管理)。
示例


@RestController
@RequestMapping("/users")
public class userController {

    @PostMapping
    @PreAuthorize("@pms.hasPermission('user_add')")
    public ResponseEntity<String> adduser() {
        return ResponseEntity.ok("user added successfully!");
    }

    @DeleteMapping("/{id}")
    @PreAuthorize("@pms.hasPermission('user_delete')")
    public ResponseEntity<String> deleteuser(@PathVariable Long id) {
        return ResponseEntity.ok("user deleted successfully!");
    }
}

只有拥有
user_add
权限的用户才能调用
adduser()
。只有拥有
user_delete
权限的用户才能调用
deleteuser()


常见问题


pms
Bean 未找到

确保
PermissionService
被 Spring 管理(加了
@Service

@Component
)。确保 Bean 的名称是
pms

@Service("pms")
)。

权限校验失败

检查当前用户是否登录(
SecurityContextHolder.getContext().getAuthentication()
)。检查用户的权限是否包含
user_add

SpEL 表达式错误

确保表达式语法正确,例如
@pms.hasPermission('user_add')
而不是
@pms.hasPermission(user_add)
(缺少引号)。


总结

组件 说明

@PreAuthorize
Spring Security 方法级权限控制注解

@pms
引用名为
pms
的 Spring Bean

hasPermission('user_add')
调用
pms
Bean 的方法,检查当前用户是否有
user_add
权限

作用:确保只有拥有
user_add
权限的用户才能执行该方法,否则拒绝访问。
适用场景:动态权限控制、RBAC(基于角色的访问控制)。

© 版权声明

相关文章

暂无评论

none
暂无评论...