zoukankan      html  css  js  c++  java
  • 【Shiro】四、Apache Shiro授权

    1、授权实现方式

    1.1、什么是授权

    授权包含4个元素(一个比较流行通用的权限模型)

    Resources:资源
      各种需要访问控制的资源

    Permissions:权限
      安全策略控制原子元素
      基于资源和动作
      控制力度

    Roles:角色
       行为的集合

    User:用户主体
      Subject,关联Role或Permission

    简单来说,可以这样理解:我们登录进系统,我们就是一个【用户】;【用户】可以是一个或多个【角色】,一个【角色】可以有多种【权限】,这些【权限】代表了我们可以访问哪些【资源】。当然【用户】也可以直接跳过【角色】,直接给【用户】分配【权限】,表明这个【用户】可以访问的【资源】。

    1.2、授权方式

    a、编程模型

      基于Role

        Role校验
          API:
            hasRole(String roleName)
            hasRoles(List<String> roleNames)
            hasAllRoles(Collection<String> roleNames)

    Subject currentUser = SecurityUtils.getSubject();
    if(currentUser.hasRole("admin")){
        ...
    } else{
        ...
    }

        Role断言(Assertion)
          失败会抛出异常AuthorizationException
          API
            checkRole(String roleName)
            checkRoles(Collection<String> roleNames)
            checkRoles(String... roleNames)

    Subject currentUser = SecurityUtils.getSubject();
    currentUser.checkRole("bankTeller");
    openBankAccount();

      基于Permission

        Permission校验
          基于对象的Permission校验
            应用场景:显式控制、类型安全
            API
              isPermiited(Permission p)
              isPermiited(List<Permission> perms)
              isPermiitedAll(Collection<Permission> perms)

    Permission printPermission = new PrinterPermission("hp","print");
    Subject currentUser = SecurityUtils.getSubject();
    if(currentUser.isPermitted(printPermission)){
        ...
    } else {
        ...
    }

          基于String的Permission校验
            应用场景:轻量级、简单
            API
              isPermiited(String perm)
              isPermiited(String... perms)
              isPermiitedAll(String... perms)

    Subject currentUser = SecurityUtils.getSubject();
    if(currentUser.isPermitted("printer:print:hp")){
        ...
    } else {
        ...
    }

        Permission断言(Assertion)
          失败会抛出异常AuthorizationException
          API
            checkPermission(Permission p))
            checkPermission(String perm)
            checkPermissions(Collection<Permission> perms)
            checkPermissions(String... perms)

    Subject currentUser = SecurityUtils.getSubject();
    
    Permission p = new AccountPermission("open");
    current.checkPermission(p);
    openBankAccount();

    b、JDK注解

    @RequiresAuthentication

    用于判断是否已认证,未认证访问该资源会抛异常,下面代码效果相同

    @RequiresAuthentication
    public void updateAccount(Account userAccount){
        ...
    }
    
    
    public void updateAccount(Account userAccount){
        if(!SecurityUtils.getSubject().isAuthenticated()){
            throw new AuthorizationException(...);
        }
    }

    @RequiresGuest

    用于判断是否为游客,如果非游客会抛异常,下面代码效果相同

    @RequiresGuest
    public void signUp(User newUser){
        ...
    }
    
    public void signUp(User newUser){
        Subject currentUser = SecurityUtils.getSubject();
        PrincipalCollection principals = currentUser.getPrincipals();
        if(principals != null && !principals.isEmpty()){
            throw new AuthorizationException(...);
        }
    }

    @RequiresPermissions

    用于判断有该权限才能访问,下面代码效果相同

    @ReruiresPermissions("account:create")
    public void creatAccount(Account account){
        ...
    }
    
    public void creatAccount(Account account){
        Subject currentUser = SecurityUtils.getSubject();
        if(!subject.isPermitted("account:create")){
            throw new AuthorizationException(...);
        }
    }

    @RequiresRoles

    用于判断有该角色才能访问,下面代码效果相同

    @RequiresRoles("admin")
    public void deleteUser(User user){
        ...
    }
    
    public void deleteUser(User user){
        Subject currentUser = SecurityUtils.getSubject();
        if(!subject.hasRole("admin")){
            throw new AuthorizationException(...);
        }
    }

    @RequiresUser

    用于判断非游客才能访问,下面代码效果相同

    @RequiresUser
    public void updateAccount(Account account){
        ...
    }
    
    public void updateAccount(Account account){
        Subject currentUser = SecurityUtils.getSubject();
        PrincipalCollection principals = currentUser.getPrincipals();
        if(principals == null || principals.isEmpty()){
            throw new AuthorizationException(...);
        }
    }

    c、JSP/GSP TagLibs

    偏向web,不介绍

    2、授权架构

     

    1、调用Subject的isPermitted或HasRole方法

    2、找Security Manager(门面模式)

    3、调用Authorizer组件

    4、通过Realm访问数据库等获取数据,用于判断是否有授权

    Authorizer

    默认实现ModularRealmAuthorizer

      迭代授权多个Realm

    策略

      如果一个Realm不实现Authorizer,不校验

      如果一个Realm实现Authorizer

        一旦校验失败,马上抛AuthorizationException

        一旦校验成功,马上返回true

    PermissionResolver权限解析器

      用于将Permission字符串解析成Permission对象,Shiro内部都是使用Permission对象来进行验证

      默认WildcardPermissionResolver(通配符权限解析器)

      可以自定义解析器

    RolePermissionResolver

      用于将Role字符串转换为Permission对象

      可以自定义解析器

      

  • 相关阅读:
    数据终端设备与无线通信模块之间串行通信链路复用协议(TS27.010)在嵌入式系统上的开发【转】
    设备树网址【原创笔记】
    clock()、time()、clock_gettime()和gettimeofday()函数的用法和区别【转】
    ajaxFileUpload SyntaxError: syntax error
    工厂模式
    程序猿都是project师吗?
    [android开发之内容更新类APP]二、这几日的结果
    Java实现将指定目录内的指定类型的文件归类
    移动支付之智能IC卡与Android手机进行NFC通信
    Java并发框架——AQS堵塞队列管理(一)——自旋锁
  • 原文地址:https://www.cnblogs.com/LiveYourLife/p/9092973.html
Copyright © 2011-2022 走看看