IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> shiro学习笔记:简单的入门 -> 正文阅读

[Java知识库]shiro学习笔记:简单的入门

一些理论知识:

https://blog.csdn.net/zifengye520/article/details/121969099

一、基本使用

官网的入门案例,使用的是ini配置文件来模拟用户的信息,这里直接跳过这个步骤,直接使用自定义的Realm来模拟数据库获取用户信息

1、创建一个springboot项目

2、添加shiro依赖

<dependency>
  <groupId>org.apache.shiro</groupId>
  <artifactId>shiro-core</artifactId>
  <version>1.5.3</version>
</dependency>

3、自定义Realm,继承AuthorizingRealm,模拟从数据库卡获取用户信息

public class MyRealm extends AuthorizingRealm {
    @Override
    //实现授权
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        return null;
    }

    @Override
    //实现认证
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        String principal = (String) authenticationToken.getPrincipal();
        //如果输入的是test,表示这个用户存在
        if(principal.equals("test")){
            //返回一个假数据,模拟从数据库取出:test|123
            return new SimpleAuthenticationInfo("test","123",getName());
        }
        return null;
    }
}

4、创建测试类,执行main方法,模拟用户登录

public class MyReamTest {
    public static void main(String[] args) {
        DefaultSecurityManager securityManager = new DefaultSecurityManager();
        //设置realm为自定义的MyRealm
        securityManager.setRealm(new MyRealm());
        //给安全工具类,设置安全管理器
        SecurityUtils.setSecurityManager(securityManager);

        //从安全工具类中获取主体
        Subject subject = SecurityUtils.getSubject();
        //创建token
        UsernamePasswordToken token = new UsernamePasswordToken("test","123");

        try{
            //登录
            subject.login(token);
        }catch (UnknownAccountException e){
            System.out.println("登录账号不存在");
        }
        catch (IncorrectCredentialsException e){
            System.out.println("登录密码不正确");
        }
        //判断登录成功
        if(subject.isAuthenticated()){
            System.out.println("登录成功");
        }
    }
}

?5、通过修改代码中用户名test,或者密码123,可以看到后台打印出对应账号或密码错误的日志

二、基本流程

1、首先,自定义的Realm,继承了AuthorizingRealm?

2、在调用subject.login(token)的时候,通过断点调试,会一步一步执行到如下图中的方法

3、当info为null,就会调用自定义realm中的doGetAuthenticationInfo方法。?

三、密码加盐

1、同样自定义一个realm,并继承AuthorizingRealm

?在认证的方法doGetAuthenticationInfo中,返回SimpleAuthenticationInfo对象时,需要提供盐值

public class MySaltRealm extends AuthorizingRealm {
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        String principal = (String) principalCollection.getPrimaryPrincipal();//主凭证,用来从数据库获取角色和权限等

        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();

        info.addRoles(Arrays.asList("admin","user"));
        info.addStringPermissions(Arrays.asList("user:create"));

        return info;
    }

    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        String principal = (String) authenticationToken.getPrincipal();
        //test是模拟从数据库查出的账号,表示test账号存在数据库中
        if("test".equals(principal)){
            //894b3913a4a13b25dc6186d11835c209,是模拟从数据库查出的加密后的密码,该密码是经过MD5加密后的
            //加密方式:Md5Hash str = new Md5Hash("123","abc",1024);

            //参数:用户名、密码、盐值、realm名称
            //加上盐值的参数,shiro在验证密码的时候,会自动加上盐值
            return new SimpleAuthenticationInfo("test","894b3913a4a13b25dc6186d11835c209", ByteSource.Util.bytes("abc"),this.getName());
        }
        return null;
    }
}

2、写个测试类,模拟登录

要给realm设置一个凭证匹配器,并指定加密算法盐值散列次数

public class MySaltRealmTest {

    public static void main(String[] args) {
        DefaultSecurityManager defaultSecurityManager = new DefaultSecurityManager();

        AuthorizingRealm myRealm = new MySaltRealm();
        //获取hash凭证匹配器
        HashedCredentialsMatcher credentialsMatcher = new HashedCredentialsMatcher();
        //设置hash凭证匹配器使用的算法(MD5)
        credentialsMatcher.setHashAlgorithmName("md5");
        //如果使用散列(加密次数),则需要设置散列的次数:1024次
        credentialsMatcher.setHashIterations(1024);

        //给自定义的realm设置密码匹配器
        myRealm.setCredentialsMatcher(credentialsMatcher);

        //设置realm为自定义的realm
        defaultSecurityManager.setRealm(myRealm);

        SecurityUtils.setSecurityManager(defaultSecurityManager);

        UsernamePasswordToken token = new UsernamePasswordToken("test","123");

        Subject subject = SecurityUtils.getSubject();
        try{
            //认证
            subject.login(token);
        }catch (UnknownAccountException e){
            e.printStackTrace();
            System.out.println("账号出错");
        }catch (IncorrectCredentialsException e){
            e.printStackTrace();
            System.out.println("密码出错");
        }

        if(subject.isAuthenticated()){
            System.out.println("认证成功");
            //判断权限
            System.out.println("角色权限"+subject.hasRole("admin"));
            System.out.println("资源权限"+subject.isPermitted("user:*"));
        }
    }
}

3、通过修改登录方法中的账号和密码,看控制台打印出对应的信息

  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2021-12-18 15:50:19  更:2021-12-18 15:50:40 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/18 20:02:08-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码