shiro细粒度资源访问控制
细粒度资源访问控制是 Shiro 的核心功能之一,允许开发者基于资源实例(如数据库记录、文件路径等)和操作(如读取、编辑、删除)定义权限。以下是完整的实现步骤和示例代码:
1. 核心概念
- 权限字符串格式:
资源:操作(如user:edit:123表示编辑 ID 为 123 的用户) - 授权流程:通过
Subject.isPermitted("权限字符串")动态判断权限。
2. 完整实现步骤
(1) 自定义 Realm 实现权限校验
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import java.util.HashSet;
import java.util.Set;
public class PermissionRealm extends AuthorizingRealm {
// 模拟数据库存储的用户角色和权限
private static final Map<String, Set<String>> USER_ROLES = new HashMap<>();
private static final Map<String, Set<String>> ROLE_PERMISSIONS = new HashMap<>();
static {
// 初始化角色和权限数据
Set<String> adminPermissions = new HashSet<>();
adminPermissions.add("user:create");
adminPermissions.add("user:edit:123"); // 允许编辑ID为123的用户
adminPermissions.add("user:delete");
ROLE_PERMISSIONS.put("admin", adminPermissions);
Set<String> userPermissions = new HashSet<>();
userPermissions.add("user:view");
ROLE_PERMISSIONS.put("user", userPermissions);
USER_ROLES.put("admin", new HashSet<>(Collections.singletonList("admin")));
USER_ROLES.put("user1", new HashSet<>(Arrays.asList("user", "guest")));
}
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
// 模拟从数据库获取用户信息
UsernamePasswordToken upToken = (UsernamePasswordToken) token;
String username = upToken.getUsername();
if (!"admin".equals(username) && !"user1".equals(username)) {
throw new UnknownAccountException("用户不存在");
}
return new SimpleAuthenticationInfo(username, "password", getName());
}
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
String username = (String) principals.getPrimaryPrincipal();
Set<String> roles = USER_ROLES.get(username);
if (roles == null) {
return null;
}
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
info.addRoles(roles);
// 根据角色添加权限
for (String role : roles) {
Set<String> permissions = ROLE_PERMISSIONS.get(role);
if (permissions != null) {
info.addStringPermissions(permissions);
}
}
return info;
}
}
(2) 配置 Shiro 使用自定义 Realm
shiro.ini 配置文件:
[main]
permissionRealm = com.example.PermissionRealm
securityManager.realms = $permissionRealm
(3) 测试细粒度权限校验
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.config.IniSecurityManagerFactory;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.util.Factory;
public class PermissionDemo {
public static void main(String[] args) {
// 初始化 SecurityManager
Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro.ini");
SecurityManager securityManager = factory.getInstance();
SecurityUtils.setSecurityManager(securityManager);
// 获取当前用户
Subject currentUser = SecurityUtils.getSubject();
// 模拟用户登录
currentUser.login(new org.apache.shiro.authc.UsernamePasswordToken("admin", "password"));
// 测试细粒度权限
System.out.println("是否有创建用户权限: " + currentUser.isPermitted("user:create")); // true
System.out.println("是否有编辑ID为123的用户权限: " + currentUser.isPermitted("user:edit:123")); // true
System.out.println("是否有删除用户权限: " + currentUser.isPermitted("user:delete")); // true
System.out.println("是否有编辑ID为456的用户权限: " + currentUser.isPermitted("user:edit:456")); // false(未授权)
// 模拟普通用户登录
currentUser.logout();
currentUser.login(new org.apache.shiro.authc.UsernamePasswordToken("user1", "password"));
System.out.println("普通用户是否有编辑权限: " + currentUser.isPermitted("user:edit:123")); // false
}
}
3. 关键点说明
-
权限字符串设计:
user:create:全局用户创建权限。user:edit:123:仅允许编辑 ID 为 123 的用户,实现实例级控制。
-
动态权限校验:
- 通过
Subject.isPermitted("权限字符串")动态判断,无需硬编码权限逻辑。
- 通过
-
扩展性:
- 可从数据库加载权限数据,支持动态权限变更。
4. 输出结果
运行 PermissionDemo 的输出:
是否有创建用户权限: true
是否有编辑ID为123的用户权限: true
是否有删除用户权限: true
是否有编辑ID为456的用户权限: false
普通用户是否有编辑权限: false
总结
通过自定义 Realm 和权限字符串设计,Shiro 可以轻松实现细粒度资源访问控制。关键点包括:

- 权限字符串格式化:用
资源:操作:实例定义权限。 - 动态校验:通过
Subject.isPermitted()实时判断权限。 - 数据驱动:权限数据可从数据库动态加载,适应复杂业务场景。
这种设计既灵活又安全,适用于企业级应用中的权限管理需求。
- 随机文章
- 热门文章
- 热评文章
- 全面了解自我:20个心理健康测试题目心理健康测试20题目问答
- 实用心理测试大全:深入了解自己,提升人际关系与生活质量实用心理测试大全大白
- 霍格沃茨分院测试:探索你的魔法学院归属pottermore:官方分院测验
- Java Spring Boot 电商系统
- Java Hibernate ORM系统
- Java 事件驱动架构:构建响应式系统的实践
- 测你的性格像《且听凤鸣》中的谁
- 个性测试 测测你有多招人羡慕嫉妒
- 鸿蒙应用安全检测指南——开发者不可忽视的隐患与工具【华为根技术】
回归分析


