• shiro授权管理


    1、授权

      授权,即访问控制,控制谁能访问哪些资源主体进行身份认证后需要分配权限方可访问系统的资源,对于某些资源没有权限是无法访问的。

    2、关键对象

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

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

      what,资源(resource),如菜单,页面,按钮,类方法,系统商品信息。

      how,权限/许可(permission),规定了主体对资源的操作许可,通过权限可知主体对那些资源有操作许可。crud权限

    3、授权流程

    授权的流程是基于用户合法的访问

    4、授权方式

      基于角色的访问
    if(subject.hasRole("admin")){ //操作什么资源 }
      基于资源的访问控制
    if(subject.isPermission("user:update:01")){ //资源实例 //对01资源拥有修改权限 }
    if(subject.isPermission("user:update:*")){ //对所有资源,拥有update权限 }
    if(subject.isPermission("user:*:01")){ //资源实例 //对01资源拥有所有权限 }

    5、授权字符串

      权限字符串的规则是:资源标识符:操作:资源实例标识符,意思是对哪个资源的哪个实例具有什么操作,“:”是资源/操作/实例的分割符,权限字符串也可以使用*通配符。 
    用户创建权限:user:create,或user:create:*
    用户修改实例001的权限:user:update:001
    用户实例001的所有权限:user:*:001

    6、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需要额外集成!

    7、授权案例

    CustomerRealm授权域,添加授权角色、授权资源
    package com.demo.grant;
    import org.apache.shiro.authc.AuthenticationException;
    import org.apache.shiro.authc.AuthenticationInfo;
    import org.apache.shiro.authc.AuthenticationToken;
    import org.apache.shiro.authc.SimpleAuthenticationInfo;
    import org.apache.shiro.authz.AuthorizationInfo;
    import org.apache.shiro.authz.SimpleAuthorizationInfo;
    import org.apache.shiro.realm.AuthorizingRealm;
    import org.apache.shiro.subject.PrincipalCollection;
    import org.apache.shiro.util.ByteSource;
    //授权领域
    public class CustomerRealm extends AuthorizingRealm {
        //授权方法
        @Override
        protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
            //获取主要身份
            String primaryPrincipal = (String) principals.getPrimaryPrincipal();
            System.out.println("primaryPrincipal = " + primaryPrincipal);
            //根据身份信息  用户名   获取当前用户的角色信息,以及权限信息   xiaochen admin  user
            SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
            //将模拟数据库中查询角色信息赋值给权限对象
            simpleAuthorizationInfo.addRole("admin");
            simpleAuthorizationInfo.addRole("user");
            //将数据库中查询权限信息赋值给权限对象
            //对用户下01实例具有所有权限   这是资源路径实例
            simpleAuthorizationInfo.addStringPermission("user:*:01");
            //对product下一切资源实例具有创建权限,*可以省略
            simpleAuthorizationInfo.addStringPermission("product:create");
    
            return simpleAuthorizationInfo;
        }
    
        //认证方法
        @Override
        protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
            String principal = (String) token.getPrincipal();
            if("zhangsan".equals(principal)){        //模拟数据库中已经md5加盐处理过的密码
                String password = "efe2cdcad63be25838e3847becd43df4";
                String salt = "x0*&p";   //需要这个解开密码
                return new SimpleAuthenticationInfo(principal,password, 
                                                    ByteSource.Util.bytes(salt),this.getName());
            }
            return null;
        }
    
    }

    测试类

    package com.demo.md5;
    
    import org.apache.shiro.SecurityUtils;
    import org.apache.shiro.authc.IncorrectCredentialsException;
    import org.apache.shiro.authc.UnknownAccountException;
    import org.apache.shiro.authc.UsernamePasswordToken;
    import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
    import org.apache.shiro.mgt.DefaultSecurityManager;
    import org.apache.shiro.subject.Subject;
    
    public class TestAuthenticatorCusttomerRealm {
        public static void main(String[] args) {
            //创建securityManager
            DefaultSecurityManager defaultSecurityManager = new DefaultSecurityManager();
            //IniRealm realm = new IniRealm("classpath:shiro.ini");
            //设置为自定义realm获取认证数据
            CustomerRealm customerRealm = new CustomerRealm();
            //设置md5加密
            HashedCredentialsMatcher credentialsMatcher = new HashedCredentialsMatcher();
            credentialsMatcher.setHashAlgorithmName("MD5");  //添加加密字符串
            credentialsMatcher.setHashIterations(1024);//设置散列次数   打乱顺序
            customerRealm.setCredentialsMatcher(credentialsMatcher); //MD5加密器//设置自定义realm
            defaultSecurityManager.setRealm(customerRealm);  //将自定义的realm设置到安全管理中
            //将安装工具类中设置默认安全管理器
            SecurityUtils.setSecurityManager(defaultSecurityManager);  //将安全管理设置到安全工具中
            //获取主体对象   
            Subject subject = SecurityUtils.getSubject();  
            //创建token令牌
            UsernamePasswordToken token = new UsernamePasswordToken("zhangsan", "123");
            try {
                //subject对象 中方法  +加盐 +验证+权限操作 主体对象调用login方法
                subject.login(token);//用户登录,shiro会自动将token中的password在自定义realm中加上盐去处理
                System.out.println("登录成功~~");
            } catch (UnknownAccountException e) {
                e.printStackTrace();
                System.out.println("用户名错误!!");
            }catch (IncorrectCredentialsException e){
                e.printStackTrace();
                System.out.println("密码错误!!!");
            }
    
        }
    }

    效果

    登录成功~~
    primaryPrincipal = zhangsan
    true
    primaryPrincipal = zhangsan
    primaryPrincipal = zhangsan
    这是用户=======false
    primaryPrincipal = zhangsan
    primaryPrincipal = zhangsan
    primaryPrincipal = zhangsan
    true
    false
    true
    =====================================================
    primaryPrincipal = zhangsan
    权限资源判断=====true
    primaryPrincipal = zhangsan
    权限true
    primaryPrincipal = zhangsan
    primaryPrincipal = zhangsan
    true
    false
    primaryPrincipal = zhangsan
    primaryPrincipal = zhangsan
    true
  • 相关阅读:
    java基础梳理--朝花夕拾(三)
    java基础梳理--朝花夕拾(二)
    [C++] 分治法之棋盘覆盖、循环赛日程表
    [C++] 递归之全排列问题、半数集
    蓝桥杯 算法训练 ALGO-143 字符串变换
    蓝桥杯 算法训练 ALGO-129 特殊的数字四十
    蓝桥杯 算法训练 ALGO-126 水仙花
    蓝桥杯 算法训练 ALGO-122 未名湖边的烦恼
    蓝桥杯 算法训练 ALGO-121 猴子分苹果
    蓝桥杯 算法训练 ALGO-116 最大的算式
  • 原文地址:https://www.cnblogs.com/HelloM/p/14154766.html
Copyright © 2020-2023  润新知