shiro总结

什么是权限管理

在这里插入图片描述
shiro各功能解释

在这里插入图片描述
shiro.ini配置文件使用,此处简单作为读取的数据库中的用户信息,方便前期测试

在这里插入图片描述
shiro认证流程

在这里插入图片描述

1 shiro简单认证演示 此处为测试从shiro.ini配置中读取数据

public class TestAuthenticator {
    public static void main(String[] args) throws NamingException {
        //1.创建安全管理器对象
        DefaultSecurityManager securityManager = new DefaultSecurityManager();
        //2.给安全管理器设置realm,也就是读取数据, 此处是在shiro.ini中读取的用户信息
        securityManager.setRealm(new IniRealm("classpath:shiro.ini"));
        //3.SecurityUtils(全局安全管理器) , 给全局安全管理器设置安全管理器
        SecurityUtils.setSecurityManager(securityManager);
        //4.关键对象  subject主体
        Subject subject = SecurityUtils.getSubject();
        //5.创建令牌  请求的用户信息
        UsernamePasswordToken token = new UsernamePasswordToken("zhangsan", "123456");
        try {
            System.out.println("认证状态: " + subject.isAuthenticated());  //未认证 false
            //5.进行认证
            subject.login(token);
            System.out.println("认证状态: " + subject.isAuthenticated());  //已认证 true
        } catch (UnknownAccountException e) {
            e.printStackTrace();
            System.out.println("未知用户异常");
        } catch (IncorrectCredentialsException e) {
            e.printStackTrace();
            System.out.println("密码错误异常");
        }
    }
}

shiro真实做认证和授权的类

在这里插入图片描述
2 自定义realm域进行shiro认证 授权
2.1 自定义的realm

/**
 * 自定义realm,继承AuthorizingRealm类,重写认证授权的具体方法,完成自定义认证授权
 */
public class MyRealm extends AuthorizingRealm {
    //授权
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        return null;
    }
    //认证
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        System.out.println("============================================");
        //进行认证时候,shiro会把携带用户信息的token传递过来,可以从参数authenticationToken 中获取用户信息,
        String principal = (String) authenticationToken.getPrincipal();//Principal主要的,也就是当前用户主体,得到用户名,可以直接转为String
        System.out.println("登录用户信息 :" + principal);    //打印  登录用户信息 :zhangsan
        //可以将获取到的用户名 去查询自己的数据库 看看是否有此人信息,此处为查库,假设有
        if ("zhangsan".equals(principal)) {
            //源码中,最终进行用户名比较是在SimpleAccountRealm 中 方法 doGetAuthenticationInfo中进行的
            /*参数解释:
            参数principal: 数据库中的用户名
            参数credentials: 数据库中的用户密码
            realmNmae: 自定义的realm名字,可以通过父类方法getName()直接获取到
            SimpleAuthenticationInfo 就会进行 登录用户 与数据库中的用户信息进行校验
            */
            SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo("zhangsan","123456",this.getName());
            return simpleAuthenticationInfo;
        }
        return null;
    }
}

2.2 在测试用使用自定的 realm进行认证 ,当调用subject.login时,会将用户信息传递到自定义的realm中进行认证校验

/**
 * 通过自定义的realm进行shiro认证,也就是将realm设置成自定义的
 */
public class MyRealmAuthenticator {
    public static void main(String[] args) {
        //创建默认的安全管理器
        DefaultSecurityManager securityManager = new DefaultSecurityManager();
        //给安全管理器设置自定义的realm,也就是读取数据
        securityManager.setRealm(new MyRealm());
        //将此安全管理器交给安全管理器工具类管理
        SecurityUtils.setSecurityManager(securityManager);
        //安全管理器,获取当前认证用户主体
        Subject subject = SecurityUtils.getSubject();
        //通过用户名和密码生成shiro的token,这就是访问用户的信息,拿去和系统中的用户信息进行比较
        UsernamePasswordToken token = new UsernamePasswordToken("zhangsan", "123456");
        try {
        //进行login认证校验
        subject.login(token);  //此处的token会传送到自定义的realm中进行与系统中的用户信息进行校验
            System.out.println("认证状态: " + subject.isAuthenticated());
        } catch (UnknownAccountException e) {
            e.printStackTrace();
            System.out.println("未知用户异常");
        } catch (IncorrectCredentialsException e) {
            e.printStackTrace();
            System.out.println("密码错误异常");
        }
    }
}

3 shiro整合了校验的算法 MD5 + 加盐 + 加散次列(加盐的次数)

3.1 shiro中 MD5 简单使用演示

/**
 * shiro中整合 MD5加密 测试
 * 生成的都是 16进制32位长度的字符串
 */
public class shiro_MD5_test {
    public static void main(String[] args) {
        //简单对 123456 进行MD5加密
        Md5Hash md5Hash = new Md5Hash("123456");
        System.out.println("md5简单加密 : " + md5Hash);

        //使用md5 + 盐 进行加密
        Md5Hash md5_salt = new Md5Hash("123456", "my_salt");
        System.out.println("md5加盐加密 : " + md5_salt);

        //MD5 + salt + 散次列(盐次数)
        Md5Hash md5_salt_times = new Md5Hash("123456", "my_salt", 5);
        System.out.println("md5加盐加散次列 : " + md5_salt_times);
    }
}

测试结果:
md5简单加密 : e10adc3949ba59abbe56e057f20f883e
md5加盐加密 : 622708d1cb1a66ca96b087344e56598d
md5加盐加散次列 : 95683f31ef383ecfe3d4d332ff762c5f

3.2 测试 设置realm设置MD5加密 对用户进行校验

3.2.1自定义realm

/**
 * 自定义realm ,测试使用MD5 + 盐 + 散次列  进行校验
 */
public class Md5Realm extends AuthorizingRealm {
    //授权
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        return null;
    }
    //认证
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        System.out.println("-------------------------------------");
        //进行认证时候,shiro会把携带用户信息的token传递过来,可以从参数authenticationToken 中获取用户信息,
        String principal = (String) authenticationToken.getPrincipal(); //Principal主要的,也就是当前用户主体,得到用户名,可以直接转为String
        System.out.println("登录用户信息 :" + principal);
        //可以将获取到的用户名 去查询自己的数据库 看看是否有此人信息,此处为查库,假设有
        if ("zhangsan".equals(principal)) {
            //源码中,最终进行用户名比较是在SimpleAccountRealm 中 方法 doGetAuthenticationInfo中进行的
            /*参数解释:
            参数principal: 数据库中的用户名
            参数credentials: 数据库中的用户密码
            realmNmae: 自定义的realm名字,可以通过父类方法getName()直接获取到
            SimpleAuthenticationInfo 就会进行 登录用户 与数据库中的用户信息进行校验
            */
            //参数1:数据库用户名 参数2: 数据库md5 + salt + 散次列 后的密码  参数3:散次列 参数4:realm名字
            SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(
                    "zhangsan",
                    "95683f31ef383ecfe3d4d332ff762c5f",
                    ByteSource.Util.bytes("my_salt"),
                    this.getName());
            return simpleAuthenticationInfo;
        }
        return null;
    }
}

3.2.2 用户认证测试

/**
 * 在进行用户信息校验的时候,设置校验方式为MD5校验,可以设置散次列, 盐放在了realm中设置
 */
public class Md5MyRealmAuthenticator {
    public static void main(String[] args) {
        //创建默认的安全管理器
        DefaultSecurityManager securityManager = new DefaultSecurityManager();
        //给安全管理器设置自定义的realm,也就是读取数据

        //创建自定义的Realm对象,为了后边设置 哈希凭证匹配器
        Md5Realm md5Realm = new Md5Realm();
        //设置 哈希凭证匹配器(加密方式) md5,设置散次列
        HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher();  //哈希凭证匹配器
        //使用算法
        hashedCredentialsMatcher.setHashAlgorithmName("MD5");
        //加盐次数
        hashedCredentialsMatcher.setHashIterations(5);
        //自定义的realm设置 哈希凭证匹配器
        md5Realm.setCredentialsMatcher(hashedCredentialsMatcher);
        //设置安全管理器使用自定义的realm域
        securityManager.setRealm(md5Realm);

        //将此安全管理器交给安全管理器工具类管理
        SecurityUtils.setSecurityManager(securityManager);
        //安全管理器,获取当前认证用户主体
        Subject subject = SecurityUtils.getSubject();
        //通过用户名和密码生成shiro的token,这就是访问用户的信息,拿去和系统中的用户信息进行比较
        UsernamePasswordToken token = new UsernamePasswordToken("zhangsan", "123456");
        try {
            //进行login认证校验
            subject.login(token);  //此处的token会传送到自定义的realm中进行与系统中的用户信息进行校验
            System.out.println("认证状态: " + subject.isAuthenticated());
        } catch (UnknownAccountException e) {
            e.printStackTrace();
            System.out.println("未知用户异常");
        } catch (IncorrectCredentialsException e) {
            e.printStackTrace();
            System.out.println("密码错误异常");
        }
    }
}

4 shiro中授权 知识点

在这里插入图片描述在这里插入图片描述在这里插入图片描述4.1 认证之后进行授权操作

基于md5 + 盐 + 散次列 进行认证之后的授权操作

4.1.1 自定的 realm

/**
 * 自定义realm ,测试使用MD5 + 盐 + 散次列  进行校验 ,此处进行授权测试
 * //认证是 new SimpleAuthenticationInfo   授权是  new SimpleAuthorizationInfo();
 */
public class Md5RealmAuthorizater extends AuthorizingRealm {
    //授权
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        System.out.println("++++++++++++++++++++++进入了授权方法++++++++++++++++++++++++++++++++");
        String primaryPrincipal = (String) principalCollection.getPrimaryPrincipal();
        System.out.println("当前用户信息 :" + primaryPrincipal);
        //正常业务是通过用户的信息,(用户名)去数据库中查询用户的角色或者资源信息,然后进行校验

        //将数据库中查询的权限信息赋予给用户对象
        SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
        //基于角色的权限控制
        simpleAuthorizationInfo.addRole("admin");
        simpleAuthorizationInfo.addRole("user");

        //将数据库中查询的资源权限信息赋予给权限对象  资源:操作:对象 -->  user:查询:01对象
        simpleAuthorizationInfo.addStringPermission("user:*:01");
        simpleAuthorizationInfo.addStringPermission("super:create");
        return simpleAuthorizationInfo;
    }


    //认证
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        System.out.println("-----------------进入了认证方法--------------------");
        //进行认证时候,shiro会把携带用户信息的token传递过来,可以从参数authenticationToken 中获取用户信息,
        String principal = (String) authenticationToken.getPrincipal(); //Principal主要的,也就是当前用户主体,得到用户名,可以直接转为String
        System.out.println("登录用户信息 :" + principal);
        //可以将获取到的用户名 去查询自己的数据库 看看是否有此人信息,此处为查库,假设有
        if ("zhangsan".equals(principal)) {
            //源码中,最终进行用户名比较是在SimpleAccountRealm 中 方法 doGetAuthenticationInfo中进行的
            /*参数解释:
            参数principal: 数据库中的用户名
            参数credentials: 数据库中的用户密码
            realmNmae: 自定义的realm名字,可以通过父类方法getName()直接获取到
            SimpleAuthenticationInfo 就会进行 登录用户 与数据库中的用户信息进行校验
            */
            //参数1:数据库用户名 参数2: 数据库md5 + salt + 散次列 后的密码  参数3:散次列 参数4:realm名字
            SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(
                    "zhangsan",
                    "95683f31ef383ecfe3d4d332ff762c5f",
                    ByteSource.Util.bytes("my_salt"),
                    this.getName());
            return simpleAuthenticationInfo;
        }
        return null;
    }
}

4.1.2 进行授权测试 两种授权方式 : 01 基于角色的授权 02 基于资源权限的授权

/**
 * shiro中进行简单的授权测试 , 此处是基于md5 + salt + 散次列 认证之后进行的授权
 * 授权是在认证之后的,认证为true才可进行权限控制
 * 分为基于角色的授权  和   基于资源权限的授权(资源标识符:操作:资源类型)
 */
public class Md5SimpleAuthorizater {
    public static void main(String[] args) {
        //创建默认的安全管理器
        DefaultSecurityManager securityManager = new DefaultSecurityManager();
        //给安全管理器设置自定义的realm,也就是读取数据

        //创建自定义的Realm对象,为了后边设置 哈希凭证匹配器
        Md5RealmAuthorizater md5RealmAuthorizater = new Md5RealmAuthorizater();
        //设置 哈希凭证匹配器(加密方式) md5,设置散次列
        HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher();  //哈希凭证匹配器
        //使用算法
        hashedCredentialsMatcher.setHashAlgorithmName("MD5");
        //加盐次数
        hashedCredentialsMatcher.setHashIterations(5);
        //自定义的realm设置 哈希凭证匹配器
        md5RealmAuthorizater.setCredentialsMatcher(hashedCredentialsMatcher);
        //设置安全管理器使用自定义的realm域
        securityManager.setRealm(md5RealmAuthorizater);

        //将此安全管理器交给安全管理器工具类管理
        SecurityUtils.setSecurityManager(securityManager);
        //安全管理器,获取当前认证用户主体
        Subject subject = SecurityUtils.getSubject();
        //通过用户名和密码生成shiro的token,这就是访问用户的信息,拿去和系统中的用户信息进行比较
        UsernamePasswordToken token = new UsernamePasswordToken("zhangsan", "123456");
        try {
            //进行login认证校验
            subject.login(token);  //此处的token会传送到自定义的realm中进行与系统中的用户信息进行校验
            System.out.println("认证状态: " + subject.isAuthenticated());
        } catch (UnknownAccountException e) {
            e.printStackTrace();
            System.out.println("未知用户异常");
        } catch (IncorrectCredentialsException e) {
            e.printStackTrace();
            System.out.println("密码错误异常");
        }


        //认证完成,进行授权操作
        if (subject.isAuthenticated()) {
            //基于单个角色的权限控制
            System.out.println("是否有此角色信息 :" + subject.hasRole("admin"));
            //基于多角色权限控制,校验用户是否同时具有多个角色
            System.out.println("是否同时具有多个角色 :" + subject.hasAllRoles( Arrays.asList("admin", "user")));
            //是否有其中一个角色
            boolean[] roles = subject.hasRoles(Arrays.asList("admin", "user", "super"));
            for (boolean role : roles) {
                System.out.println("是否具有某个角色 : " + role);
            }

            //基于权限的字符串的访问控制   资源标识符:操作:资源类型
            System.out.println("资源权限" + subject.isPermitted("user:create:01"));  //资源权限true
            System.out.println("资源权限" + subject.isPermitted("super:update"));  //资源权限false
            //分别有那些权限
            boolean[] Permittes = subject.isPermitted("user:create:01", "user:create:02");  //资源权限 : true  资源权限 : false
            for (boolean permitte : Permittes) {
                System.out.println("资源权限 : " + permitte);
            }
            //同时具有哪些资源权限
            System.out.println("是否同时具有权限 : " + subject.isPermittedAll("user:create:01", "super:create:02"));  //是否同时具有权限 : true
        }
    }
}

5 springboot整合shiro思路

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值