Shiro实战学习笔记(3)- 授权

1 授权

授权可简单理解为who对what(which)进行How操作:

Who,即主体(Subject),主体需要访问系统中的资源。

What,即资源(Resource),如系统菜单、页面、按钮、类方法、系统商品信息等。资源包括资源类型资源实例,比如商品信息为资源类型,类型为t01的商品为资源实例,编号为001的商品信息也属于资源实例。

How,权限/许可(Permission),规定了主体对资源的操作许可,权限离开资源没有意义,如用户查询权限、用户添加权限、某个类方法的调用权限、编号为001用户的修改权限等,通过权限可知主体对哪些资源都有哪些操作许可。

在这里插入图片描述

1.1 授权方式

  • 基于角色的访问控制

    • RBAC基于角色的访问控制(Role-Based Access Control)是以角色为中心进行访问控制

      if(subject.hasRole("admin")){
         //操作什么资源
      }
      
  • 基于资源的访问控制

    • RBAC基于资源的访问控制(Resource-Based Access Control)是以资源为中心进行访问控制

      if(subject.isPermission("user:update:01")){ //资源实例
        //对01用户进行修改
      }
      if(subject.isPermission("user:update:*")){  //资源类型
        //对01用户进行修改
      }
      

    1.2 权限字符串

权限字符串的规则是:资源标识符:操作:资源实例标识符,意思是对哪个资源的哪个实例具有什么操作,“:”是资源/操作/实例的分割符,权限字符串也可以使用*通配符。

例子:

  • 用户创建权限:user:create,或user:create:*
  • 用户修改实例001的权限:user:update:001
  • 用户实例001的所有权限:user:*:001

1.3 shiro中授权的编程实现

  • 编程式

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

    @RequiresRoles("admin")
    public void hello() {
    	//有权限
    }
    
  • 标签式

    JSP/GSP 标签:在JSP/GSP 页面通过相应的标签完成:
    <shiro:hasRole name="admin">
    	<!— 有权限—>
    </shiro:hasRole>
    注意: Thymeleaf 中使用shiro需要额外集成!
    

2 案例

/**
 * @Description md5 + salt + hash
 * @Author tzb
 * @Date 2021/8/28 10:41
 * @Version 1.0
 **/
public class CustomMd5Realm extends AuthorizingRealm {

    /**
     * 授权
     *
     * @param principals
     * @return
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {

        String primaryPrincipal = (String) principals.getPrimaryPrincipal();
        System.out.println("身份信息:" + primaryPrincipal);

        //根据名字获取角色
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();

        //将数据库查询出的角色信息赋值给权限对象
        info.addRole("admin");
        info.addRole("user");


        //将数据库查询权限信息赋值给权限对象
        info.addStringPermission("user:*:*");

        return info;
    }

    /**
     * 认证
     *
     * @param token
     * @return
     * @throws AuthenticationException
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {

        //获取身份信息
        String principal = (String) token.getPrincipal();

        //根据用户名查数据库
        if ("Mike".equals(principal)) {
            SimpleAuthenticationInfo simpleAuthenticationInfo =
                    new SimpleAuthenticationInfo("Mike",
                            "ead587102bc9adbf3ffda3f28d2e5dc8",
                            ByteSource.Util.bytes("qq"), this.getName());
            return simpleAuthenticationInfo;
        }

        return null;
    }
}

public class TestCustomMd5RealmAuthenticator {

    public static void main(String[] args) {
        //1.创建SecurityManager
        DefaultSecurityManager defaultSecurityManager = new DefaultSecurityManager();

        CustomMd5Realm realm = new CustomMd5Realm();

        HashedCredentialsMatcher credentialsMatcher = new HashedCredentialsMatcher();
        credentialsMatcher.setHashAlgorithmName("md5");
        credentialsMatcher.setHashIterations(1024);

        //设置realm使用hash凭证匹配器
        realm.setCredentialsMatcher(credentialsMatcher);

        //2.设置realm
        defaultSecurityManager.setRealm(realm);

        //3.安全工具类设置
        SecurityUtils.setSecurityManager(defaultSecurityManager);

        //4.通过安全工具类获取subject
        Subject subject = SecurityUtils.getSubject();

        //创建Token
        UsernamePasswordToken token = new UsernamePasswordToken("Mike","123");

        //执行认证
        try {
            subject.login(token);
            System.out.println("查询授权状态:" + subject.isAuthenticated());
        } catch (AuthenticationException e) {
            e.printStackTrace();
        }

        //认证用户进行授权
        if(subject.isAuthenticated()){
            // 1.基于角色权限控制
            System.out.println(subject.hasRole("admin"));
            // 多角色
            System.out.println(subject.hasAllRoles(Arrays.asList("admin", "user")));

            System.out.println("=====================================================");

            //2.基于权限字符串的访问控制, 资源标识符:操作:资源类型
            System.out.println("权限:"+subject.isPermitted("user:update:01"));
        }

    }
}

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值