shiro的授权
授权,即访问控制,控制谁能访问哪些资源。主体进行身份认证后需要分配权限方可访问系统的资源,对于某些资源没有权限是无法访问的。
关键对象
授权可简单理解为who对what(which)进行How操作:
Who,即主体(Subject)
,主体需要访问系统中的资源。
What,即资源(Resource)
,如系统菜单、页面、按钮、类方法、系统商品信息等。资源包括资源类型
和资源实例
,比如商品信息为资源类型
,类型为t01的商品为资源实例
,编号为001的商品信息也属于资源实例。
How,权限/许可(Permission)
,规定了主体对资源的操作许可,权限离开资源没有意义,如用户查询权限、用户添加权限、某个类方法的调用权限、编号为001用户的修改权限等,通过权限可知主体对哪些资源都有哪些操作许可。
授权流程
授权方式
基于角色的访问控制
RBAC基于角色的访问控制(Role-Based Access Control)是以角色为中心进行访问控制
1 | if(subject.hasRole("admin")){ |
基于资源的访问控制
RBAC基于资源的访问控制(Resource-Based Access Control)是以资源为中心进行访问控制
1 | if(subject.isPermission("user:update:01")){ //资源实例 |
权限字符串
权限字符串的规则是:资源标识符:操作:资源实例标识符
,意思是对哪个资源的哪个实例具有什么操作,:
是资源/操作/实例的分割符,权限字符串也可以使用*
通配符。
例子:
- 用户创建权限:user:create,或user:create:*
- 用户修改实例001的权限:user:update:001
- 用户实例001的所有权限:user:*:001
shiro中授权编程实现方式
编程式
1 | Subject subject = SecurityUtils.getSubject(); |
注解式
1 |
|
标签式
1 | JSP/GSP 标签:在JSP/GSP 页面通过相应的标签完成: |
开发授权
1 | /** |
添加了两个角色
admin
user
两个权限字符串
- user:*:01
- product:create
当用户通过了认证,则会给该用户添加两个角色,两个权限字符串。
public class TestCustomerMd5RealmAuthenticator {
public static void main(String[] args) {
//创建安全管理器
DefaultSecurityManager defaultSecurityManager = new DefaultSecurityManager();
//注入realm
CustomerMd5Realm realm = new CustomerMd5Realm();
defaultSecurityManager.setRealm(realm);
//设置realms使用hash凭证匹配器
HashedCredentialsMatcher credentialsMatcher = new HashedCredentialsMatcher();
credentialsMatcher.setHashAlgorithmName("md5");
credentialsMatcher.setHashIterations(1024);
realm.setCredentialsMatcher(credentialsMatcher);
//将安全管理器注入安全工具
SecurityUtils.setSecurityManager(defaultSecurityManager);
//通过安全工具类获取subject
Subject subject = SecurityUtils.getSubject();
//认证
UsernamePasswordToken token = new UsernamePasswordToken("kylin", "123");
subject.login(token);
//认证用户进行授权
if (subject.isAuthenticated()) {
//基于角色权限控制
System.out.println(subject.hasRole("admin"));
//基于多角色的权限控制
System.out.println(subject.hasAllRoles(Arrays.asList("admin", "user")));
//是否具有其中一个角色
boolean[] booleans = subject.hasRoles(Arrays.asList("admin", "super", "user"));
for (boolean aBoolean : booleans) {
System.out.println(aBoolean);
}
//基于权限字符串的访问控制 资源标识符:操作:资源类型
System.out.println("权限:" + subject.isPermitted("user:update:01"));
System.out.println("权限:" + subject.isPermitted("product:create:03"));
//分别具有哪些权限
boolean[] permitted = subject.isPermitted("user:*:01", "order:*:10");
for (boolean b : permitted) {
System.out.println(b);
}
//同时具有哪些权限
boolean permittedAll = subject.isPermittedAll("user:*:01", "product:create:01");
System.out.println(permittedAll);
}
}
}
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Kylin!
评论