Shiro三种授权方式

编程式:通过写 if/else 授权代码块完成:

Subject subject = SecurityUtils.getSubject();
if(subject.hasRole(“admin”)) {
    //有权限
} else {
    //无权限
}

注解式:通过在执行的 Java 方法上放置相应的注解完成:

@RequiresRoles("admin")
public void hello() {
    //有权限
}

没有权限将抛出相应的异常;

JSP/GSP 标签:在 JSP/GSP 页面通过相应的标签完成:

Shiro 提供了 JSTL 标签用于在 JSP/GSP 页面进行权限控制,如根据登录用户显示相应的页面按钮。

导入标签库

<%@taglib prefix="shiro" uri="http://shiro.apache.org/tags" %>

<shiro:hasRole name="admin">
<!— 有权限 —>
</shiro:hasRole>

授权流程

流程如下:

  1. 首先调用 Subject.isPermitted*/hasRole*接口,其会委托给 SecurityManager,而 SecurityManager 接着会委托给 Authorizer;

  2. Authorizer 是真正的授权者,如果我们调用如 isPermitted(“user:view”),其首先会通过 PermissionResolver 把字符串转换成相应的 Permission 实例;

  3. 在进行授权之前,其会调用相应的 Realm 获取 Subject 相应的角色/权限用于匹配传入的角色/权限;

  4. Authorizer 会判断 Realm 的角色/权限是否和传入的匹配,如果有多个 Realm,会委托给 ModularRealmAuthorizer 进行循环判断,如果匹配如 isPermitted*/hasRole* 会返回 true,否则返回 false 表示授权失败。

ModularRealmAuthorizer 进行多 Realm 匹配流程:

  • 首先检查相应的 Realm 是否实现了实现了 Authorizer;

  • 如果实现了 Authorizer,那么接着调用其相应的 isPermitted*/hasRole* 接口进行匹配;

  • 如果有一个 Realm 匹配那么将返回 true,否则返回 false。

如果 Realm 进行授权的话,应该继承 AuthorizingRealm,其流程是:

  • 如果调用 hasRole*,则直接获取 AuthorizationInfo.getRoles() 与传入的角色比较即可;首先如果调用如 isPermitted(“user:view”),首先通过 PermissionResolver 将权限字符串转换成相应的 Permission 实例,默认使用 WildcardPermissionResolver,即转换为通配符的 WildcardPermission;

  • 通过 AuthorizationInfo.getObjectPermissions() 得到 Permission 实例集合;通过 AuthorizationInfo.getStringPermissions() 得到字符串集合并通过 PermissionResolver 解析为 Permission 实例;然后获取用户的角色,并通过 RolePermissionResolver 解析角色对应的权限集合(默认没有实现,可以自己提供);

  • 接着调用 Permission.implies(Permission p) 逐个与传入的权限比较,如果有匹配的则返回 true,否则 false。

自定义 Realm设置权限

public class MyRealm extends AuthorizingRealm {
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
        authorizationInfo.addRole("role1");
        authorizationInfo.addRole("role2");
        authorizationInfo.addObjectPermission(new BitPermission("+user1+10"));
        authorizationInfo.addObjectPermission(new WildcardPermission("user1:*"));
        authorizationInfo.addStringPermission("+user2+10");
        authorizationInfo.addStringPermission("user2:*");
        return authorizationInfo;
    }
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        //身份认证
    }
}

QQ群:785071190
查看原文:http://www.coder306.cn/?p=210

最新文章

  1. 【转】Hibernate 常见异常
  2. [深度优先搜索] POJ 1426 Find The Multiple
  3. iOS 按钮点击变色
  4. ERDAS文件格式:IGE、IMG、RRD、AUX
  5. input 中的enabled与disabled属性
  6. 初始JSON
  7. HTTPS的工作原理
  8. KeepAlive详解
  9. wxPython学习笔记(三)
  10. (转)window.location.search的用法
  11. IOS8 设置TableView Separatorinset 分割线从边框顶端开始
  12. 创建maven项目pom.xml第一行报错
  13. 【转】 要做linux运维工程师的朋友,必须要掌握以下几个工具才行
  14. Eslint报错整理与解决方法(持续整理)
  15. sql where,group by ,having,order by用法和区别
  16. nginx——location匹配流程图
  17. eclipse与visualVM与mat
  18. [CSAcademy]Or Problem
  19. Modelsim command line 传参数到 .do 文件
  20. Struts2访问web元素的各种方法

热门文章

  1. 【Windows】快速启动软件 非点击软件图标 无限弹窗
  2. [自动化-脚本]001.自动领淘金币:Anyweb模拟操作
  3. 分布式事务专题笔记(三)分布式事务解决方案之TCC(三阶段提交)
  4. Spring Boot笔记(五) SpringBoot 集成Lombok 插件
  5. Spring Cloud Ribbon 客户端负载均衡
  6. Java实现 LeetCode 680 验证回文字符串 Ⅱ(暴力)
  7. Java实现 蓝桥杯 算法提高 拿糖果
  8. Java实现UVA10131越大越聪明(蓝桥杯每周一题)
  9. Java中环境变量PATH与CLASSPATH的区别
  10. 移除VS解决方案中的TFS版本控制