赞
踩
芋道框架支持基本的权限控制机制,其技术层面,是通过SpringSecurity框架来实现的。
下面就从源代码代码中,分析一下芋道是如何做权限控制的。
拿岗位管理的代码示例来说。在文件PostController.java中,看如下代码:
- @GetMapping(value = "/get")
- @Operation(summary = "获得岗位信息")
- @Parameter(name = "id", description = "岗位编号", required = true, example = "1024")
- @PreAuthorize("@ss.hasPermission('system:post:query')")
- public CommonResult<PostRespVO> getPost(@RequestParam("id") Long id) {
- PostDO post = postService.getPost(id);
- return success(BeanUtils.toBean(post, PostRespVO.class));
- }
这段代码是用于查询岗位列表的。其中,注解@PreAuthorize("@ss.hasPermission('system:post:query')"),表明了,要想调用本方法,需要当前用户具有'system:post:query'权限。
那么,@PreAuthorize("@ss.hasPermission('system:post:query')")这段代码是如何被执行的呢?
答案位于文件YudaoSecurityAutoConfiguration.java中:
- @Bean("ss") // 使用 Spring Security 的缩写,方便使用
- public SecurityFrameworkService securityFrameworkService(PermissionApi permissionApi) {
- return new SecurityFrameworkServiceImpl(permissionApi);
- }
可以看到,名称为ss的Bean被注入进来。它是接口SecurityFrameworkService的实现。
而该接口的实现,位于SecurityFrameworkServiceImpl.java。
- @AllArgsConstructor
- public class SecurityFrameworkServiceImpl implements SecurityFrameworkService {
-
- private final PermissionApi permissionApi;
-
- @Override
- public boolean hasPermission(String permission) {
- return hasAnyPermissions(permission);
- }
-
- @Override
- public boolean hasAnyPermissions(String... permissions) {
- return permissionApi.hasAnyPermissions(getLoginUserId(), permissions);
- }
-
- @Override
- public boolean hasRole(String role) {
- return hasAnyRoles(role);
- }
-
- @Override
- public boolean hasAnyRoles(String... roles) {
- return permissionApi.hasAnyRoles(getLoginUserId(), roles);
- }
-
- @Override
- public boolean hasScope(String scope) {
- return hasAnyScopes(scope);
- }
-
- @Override
- public boolean hasAnyScopes(String... scope) {
- LoginUser user = SecurityFrameworkUtils.getLoginUser();
- if (user == null) {
- return false;
- }
- return CollUtil.containsAny(user.getScopes(), Arrays.asList(scope));
- }
-
- }

可以看到,其中有一个方法hasPermission,正是上文中提到的注解中的方法。
继续跟踪该方法的实现,最终会落在接口PermissionService的实现类PermissionServiceImpl上:
- @Override
- public boolean hasAnyPermissions(Long userId, String... permissions) {
- // 如果为空,说明已经有权限
- if (ArrayUtil.isEmpty(permissions)) {
- return true;
- }
-
- // 获得当前登录的角色。如果为空,说明没有权限
- List<RoleDO> roles = getEnableUserRoleListByUserIdFromCache(userId);
- if (CollUtil.isEmpty(roles)) {
- return false;
- }
-
- // 情况一:遍历判断每个权限,如果有一满足,说明有权限
- for (String permission : permissions) {
- if (hasAnyPermission(roles, permission)) {
- return true;
- }
- }
-
- // 情况二:如果是超管,也说明有权限
- return roleService.hasAnySuperAdmin(convertSet(roles, RoleDO::getId));
- }

该方法的操作就很明显了,就是通过查询数据库,来判断当前的用户是否拥有对应的权限。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。