Shiro授权详解

在进行Shiro授权之前,了解相关术语对于理解整个过程至关重要。Shiro的授权机制以角色为中心,辅以权限,来控制主体对资源的访问。以下是常用术语的简要介绍:

  • 授权 (Authorization)
    授权是指确定主体是否有权访问某一资源或执行某一操作。通过角色和权限机制,Shiro为系统提供了细粒度的访问控制能力

  • 主体 (Subject)
    主体是指当前的用户、设备或其他能与应用进行交互的实体。每个主体在登录后,会被分配一定的权限和角色来确定其行为

  • 资源 (Resource)
    资源可以是系统中的任意数据或服务,例如文件、API接口等,主体通过权限来访问这些资源

  • 权限 (Permission)
    权限是允许主体执行某个具体操作的规则。Shiro的权限是基于字符串的,可以通过自定义规则实现不同的访问控制策略

  • 角色 (Role)
    角色是权限的集合,主体通过被分配某些角色来获得一系列权限。例如,一个"管理员"角色可能包含创建、更新、删除等权限

  • 隐式角色 (Implicit Role)
    隐式角色是指由系统规则自动分配的角色,无需明确配置。通常基于上下文、属性等信息动态确定

  • 显式角色 (Explicit Role)
    显式角色是通过明确配置的角色,例如在数据库中定义或直接在代码中指定的角色

1. 授权

授权是Shiro中重要的核心功能,通过角色和权限实现系统的安全控制

(1) 授权流程

Shiro的授权过程分为以下几步:

  1. 主体登录
    主体通过身份验证(认证)后,进入授权流程。Shiro通过Subject对象获取当前用户信息

  2. 权限检查
    当主体尝试访问某一资源时,Shiro首先通过SecurityManager查询该主体的权限信息。系统会根据配置的Realm来判断主体是否有权限

  3. 角色检查
    若主体的权限不足,Shiro还会查询主体所属的角色,检查该角色是否具备访问资源的权限

  4. 结果返回
    根据查询结果,Shiro决定是否允许主体访问对应资源。如果授权失败,Shiro会抛出UnauthorizedException异常

(2) 授权方式

Shiro支持多种授权方式,满足不同系统需求

  1. 基于角色的授权
    通过角色为主体赋予一组权限,这种方式适合结构清晰、权限划分明确的场景

    subject.hasRole("admin") //判断主体是否拥有“admin”角色
  1. 基于权限的授权
    直接为主体赋予特定的权限,通常使用字符串标识权限,具有高度灵活性

    subject.isPermitted("file:read")//判断主体是否具备“文件读取”的权限
  2. 基于注解的授权
    Shiro还提供了注解方式,通过注解可以直接在控制器、服务方法中指定授权规则

    @RequiresRoles("admin") 或 @RequiresPermissions("user:update")
2. SpringBoot+Shiro授权

将Shiro与SpringBoot集成是目前比较主流的实践,通过简单的配置即可为SpringBoot项目增加灵活的授权控制

(1) 静态授权

静态授权是指在代码或配置文件中提前定义好角色和权限的关系,不依赖运行时动态数据。这种方式适合权限结构简单的场景

  1. 配置静态授权规则
    在Shiro的配置文件中为不同角色配置权限:

    shiro:
      roles:
        admin: "file:create,file:read,file:update"
        user: "file:read"
    
  2. 代码中基于角色或权限的判断
    在代码中可以使用以下方式进行静态授权:

     System.out.println("调用MyShiroRealm的doGetAuthorizationInfo获取权限信息");
            //获得权限信息
            User user = (User) principalCollection.getPrimaryPrincipal();
            SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
            info.addRole(user.getRole().getRoleName());
            info.addStringPermission("用户列表");
            //管理增删改
            if ("管理员".equals(user.getRole().getRoleName())) {
                info.addStringPermission("用户添加");
                info.addStringPermission("用户编辑");
                info.addStringPermission("用户删除");
            }
(2) 动态授权

动态授权通过数据库或外部服务来实现对权限的实时控制。此方式更加灵活,适合权限体系复杂、需要频繁调整权限的场景

  1. 动态角色与权限的加载
    通过自定义Realm从数据库中加载角色和权限:

    System.out.println("调用MyShiroRealm的doGetAuthenticationInfo获取身份信息");
    //获得身份信息
    UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken;
    String usrName = token.getUsername();
    User user = userService.getUserByUsrName(usrName);
    if (user == null) {
          throw new AuthenticationException();//账号错误
    }
    if (user.getUsrFlag() == null || user.getUsrFlag().intValue() == 0) {
          throw new LockedAccountException();//账号被禁用
    }
    SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(
                    user,
                    user.getUsrPassword(),
                    getName());

  2. 结合动态数据判断
    使用动态方式可以根据业务需求实时调整权限,例如根据用户角色动态生成权限菜单

    Subject currentUser = SecurityUtils.getSubject();
    
    // 动态判断用户是否有管理员角色
    if (currentUser.hasRole("admin")) {
         return "你好admin";
    } else {
         return "角色不存在!";
    }

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值