授权关键对象
- 主体(Subject)
- 资源(Resource)
- 权限(Permission)
- 角色(Role)
快速上手
- 配置shiro.ini
#对用户信息进行配置
[users]
#用户账号和密码
#配置规则:用户账号=密码,角色1,角色2
zhangsan=123456,管理员
xiaobei=123456,客户经理
qingjing=123456,总经理
#对权限信息进行配置,基于角色配置
[roles]
#角色和权限
#配置规则:角色=权限1,权限2,权限字符串可使用通配符配置
#管理员能够对用户和角色进行所有操作
管理员=user:*,role:*
#客户经理支队用户进行列表和详情的查看操作
客户经理=user:list,user:view
授权测试
@Test
public void testShiro() {
//1.创建Realm(安全数据源)
//通过shiro.ini配置文件创建Realm
IniRealm realm = new IniRealm("classpath:shiro.ini");
//2.配置SecurityManager
DefaultSecurityManager securityManager = new DefaultSecurityManager();
//注入创建的Realm(安全数据源)
securityManager.setRealm(realm);
SecurityUtils.setSecurityManager(securityManager);
//3.操作subject,进行认证
Subject subject = SecurityUtils.getSubject();
//封装一个令牌
// UsernamePasswordToken token = new UsernamePasswordToken("admin","123456");
UsernamePasswordToken token = new UsernamePasswordToken("zhangsan", "123456");
try {
subject.login(token);//登录,即认证
} catch (AuthenticationException e) {
log.info("认证异常!");
e.printStackTrace();
}
log.info("是否认证通过:" + subject.isAuthenticated());
log.info("身份信息:" + subject.getPrincipal());
//判断是否为某角色
log.info("是否为管理员角色:" + subject.hasRole("客户经理"));
//判断是否拥有某权限,也可以使用check方法判断是否拥有某权限,单失败的情况下会抛出UnauthorizedException异常
log.info("是否能操作用户查看功能:" + subject.isPermitted("user:view"));
subject.checkPermission("user:view");
}
测试过后的效果:
授权流程
- 首先调用Subject.isPermitted*/hasRole*接口,其会委托给SecurityManager,而SecurityManager接着会委托给Authorizer
- Authorizer是真正的授权者,如果我们都爱用如isPermitted(“user:view”),其首先会通过PermissionResolver把字符串转换成相应的Permisson实例
- 在进行授权之前,其会调用相应的Realm获取Subject相应的角色/权限用于匹配传入的角色/权限
- Authorizer会判断Realm的角色/权限是否和传入的匹配,如果有多个Realm,会委托给ModeularRealmAuthoriizer进行循环判断,isPermitted*/hasRole*如果匹配会返回true,否则返回false表示授权失败