• Shiro第一个程序官方快速入门程序Qucickstart详解教程



    目录


    一、下载解压

    首先下载Shirohttps://github.com/apache/shiro
    image-20201013230542649
    下载完成后解压
    image-20201013230605248


    二、第一个Shiro程序

    接下来我们根据官方文档编写第一个Shiro程序

    官方文档:

    新建一个普通的maven项目,删除src目录,然后再新建一个modulehello-shiro
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-uSSa3VpM-1661287713754)(https://gitee.com/zhong_siru/images/raw/master//img/image-20201013231218621.png)]

    根据官方文档:
    image-20201013231730485
    接下来进入到samples/quickstart目录,可以看到src目录和对应的pom.xml,这就是为了我们快速入门shiro一个maven项目的源代码,接下来我们将该项目对应的代码拷贝到我们自己创建的项目中
    image-20201013230913910


    1. 导入依赖

    复制pom.xml中的dependency依赖到自己创建的项目的pom.xml中

    
    	
        	org.apache.shiro
            shiro-core
        
        
        
            org.slf4j
            jcl-over-slf4j
            runtime
        
        
            org.slf4j
            slf4j-log4j12
            runtime
        
        
            log4j
            log4j
            runtime
        
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    然后替换为有版本号的依赖,注意删除scope属性!! 否则测试结果无法成功

    
        
            org.apache.shiro
            shiro-core
            1.6.0
        
        
        
            org.slf4j
            jcl-over-slf4j
            2.0.0-alpha1
        
        
            org.slf4j
            slf4j-log4j12
            2.0.0-alpha1
        
        
            log4j
            log4j
            1.2.17
        
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    2. 配置shiro配置文件

    quickstartsrcmain esources下的log4j.propertiesshiro.ini拷贝到项目的resources目录下
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TqWi2giB-1661287713757)(https://gitee.com/zhong_siru/images/raw/master//img/image-20201013232245234.png)]
    其中.ini文件并没有高亮,IDEA提示我们安装插件,我们点击install plugins安装即可

    然后点击OK即可
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zLPKSaP2-1661287713758)(https://gitee.com/zhong_siru/images/raw/master//img/image-20201013232455343.png)]
    完成后即有高亮显示


    3. Quickstart.java

    quickstartsrcmainjava目录下的Quickstart.java到自己项目的java目录下

    image-20201014001721584
    发现爆红,这时候将爆红的两个import删除即可


    4. 启动测试

    运行Quickstart的main方法

    发现打印了一些日志信息,到此我们第一shiro程序quickstart就搞定了
    image-20201017181227534


    三、shiro.ini分析

    我们来分析一下官方提供的快速入门的INI Realm配置文件,可以分为两个部分

    • 设置用户名以及对应的角色
    • 设置角色对应的权限
    #快速入门INI Realm配置
    
    #用户及其分配的角色
    [users]
    #用户root 密码:secret 角色:admin
    root = secret, admin
    #用户guest 密码:guest 角色:guest
    guest = guest, guest
    #用户presidentskroob 密码:12345 角色:president
    presidentskroob = 12345, president
    #用户darkhelmet 密码:ludicrousspeed 角色:darklord和schwartz
    darkhelmet = ludicrousspeed, darklord, schwartz
    #用户lonestarr 密码:vespa 角色:goodguy和schwartz
    lonestarr = vespa, goodguy, schwartz
    
    # 具有分配权限的角色
    [roles]
    #admin角色具有所有权限,用通配符*表示
    admin = *
    #schwartz角色通过lightsaber:*获得有所有权限
    schwartz = lightsaber:*
    #goodguy角色通过eagle5(特定实例的ID)可以dirve(动作)Winnebago(类型)
    goodguy = winnebago:drive:eagle5
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    四、Quickstart.java源码分析

    我们来分析以下官方提供的Quickstart.java

    1. 使用指定类初始化日志对象

    private static final transient Logger log = LoggerFactory.getLogger(Quickstart.class);
    
    • 1

    通过获得日志对象,打印后续的日志信息

    2. 通过.ini文件创建SecurityManager实例

    //创建带有realms,users,roles和permissions配置的Shiro SecurityManager的最简单方法是使用简单的ini配置
    //我们将使用可提取.ini文件(在类路径的根目录下使用shiro.ini文件)的工厂返回一个SecurityManager实例
    Factory factory = new IniSecurityManagerFactory("classpath:shiro.ini");
    SecurityManager securityManager = factory.getInstance();
    
    //对于这个简单的示例快速入门,请使SecurityManager作为JVM单例访问。
    //大多数应用程序都不会这样做,而在webapps会依靠其容器配置或web.xml进行使用
    SecurityUtils.setSecurityManager(securityManager);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    到此,基本的shiro环境已经搭建完成,接下来进行的是自己的一些操作

    3. 获取当前执行的用户subject

    //获取当前执行的用户subject
    Subject currentUser = SecurityUtils.getSubject();
    
    • 1
    • 2

    4. 通过当前用户得到session存取值并打印

    //通过当前用户得到session,使用Session做一些事情(不需要Web或EJB容器)
    Session session = currentUser.getSession();
    session.setAttribute("someKey", "aValue");//设置session其中的值
    String value = (String) session.getAttribute("someKey");//获取session中值
    if (value.equals("aValue")) {
        log.info("Retrieved the correct value! [" + value + "]");//通过日志打印session的值
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    5. 测试当前用户是否被认证

    //测试当前用户是否被认证
    if (!currentUser.isAuthenticated()) {//如果没有被认证
        UsernamePasswordToken token = new UsernamePasswordToken("lonestarr", "vespa");//生成一个Token令牌,随机设置
        token.setRememberMe(true);//设置记住我
        try {
            currentUser.login(token);//执行登录操作
        } catch (UnknownAccountException uae) {//未知的账户
            log.info("There is no user with username of " + token.getPrincipal());
        } catch (IncorrectCredentialsException ice) {//证书不正确
            log.info("Password for account " + token.getPrincipal() + " was incorrect!");
        } catch (LockedAccountException lae) {//用户被锁定
            log.info("The account for username " + token.getPrincipal() + " is locked.  " +
                    "Please contact your administrator to unlock it.");
        }
        //...还可以捕获更多异常(也许是针对您的应用程序的自定义异常)
        catch (AuthenticationException ae) {
            //意外状况?错误?
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    6. 打印当前用户的主要身份信息

    //打印当前用户的主要身份信息(本案例中是用户名)
    log.info("User [" + currentUser.getPrincipal() + "] logged in successfully.");
    
    • 1
    • 2

    7. 判断当前用户角色

    //测试角色
    if (currentUser.hasRole("schwartz")) {
        log.info("May the Schwartz be with you!");
    } else {
        log.info("Hello, mere mortal.");
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    8. 判断当前用户的权限

    //测试权限(不是实例级别:粗粒度)
    if (currentUser.isPermitted("lightsaber:wield")) {
        log.info("You may use a lightsaber ring.  Use it wisely.");
    } else {
        log.info("Sorry, lightsaber rings are for schwartz masters only.");
    }
    
    //(非常强大的)实例级别权限:细粒度
    if (currentUser.isPermitted("winnebago:drive:eagle5")) {
        log.info("You are permitted to 'drive' the winnebago with license plate (id) 'eagle5'.  " +
                "Here are the keys - have fun!");
    } else {
        log.info("Sorry, you aren't allowed to drive the 'eagle5' winnebago!");
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    9. 注销结束系统

    //注销
    currentUser.logout();
    
    //结束系统
    System.exit(0);
    
    • 1
    • 2
    • 3
    • 4
    • 5

    完整含注释代码:

    import org.apache.shiro.SecurityUtils;
    import org.apache.shiro.authc.*;
    import org.apache.shiro.config.IniSecurityManagerFactory;
    import org.apache.shiro.mgt.SecurityManager;
    import org.apache.shiro.session.Session;
    import org.apache.shiro.subject.Subject;
    import org.apache.shiro.util.Factory;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    
    
    //简单的快速入门应用程序,显示了如何使用Shiro的API
    public class Quickstart {
    
        private static final transient Logger log = LoggerFactory.getLogger(Quickstart.class);
    
    
        public static void main(String[] args) {
            //创建带有realms,users,roles和permissions配置的Shiro SecurityManager的最简单方法是使用简单的ini配置
            //我们将使用可提取.ini文件(在类路径的根目录下使用shiro.ini文件)的工厂返回一个SecurityManager实例
            Factory factory = new IniSecurityManagerFactory("classpath:shiro.ini");
            SecurityManager securityManager = factory.getInstance();
    
            //对于这个简单的示例快速入门,请使SecurityManager作为JVM单例访问。
            //大多数应用程序都不会这样做,而在webapps会依靠其容器配置或web.xml进行使用
            SecurityUtils.setSecurityManager(securityManager);
    
            //现在已经建立了一个简单的Shiro环境,接下来可以进行一些操作
    
            //获取当前执行的用户subject
            Subject currentUser = SecurityUtils.getSubject();
    
            //通过当前用户得到session,使用Session做一些事情(不需要Web或EJB容器)
            Session session = currentUser.getSession();
            session.setAttribute("someKey", "aValue");//设置值
            String value = (String) session.getAttribute("someKey");//获取值
            if (value.equals("aValue")) {
                log.info("Retrieved the correct value! [" + value + "]");
            }
    
            //让我们登录当前用户,以便我们可以检查角色和权限
            //测试当前用户是否被认证
            if (!currentUser.isAuthenticated()) {//如果没有被认证
                UsernamePasswordToken token = new UsernamePasswordToken("lonestarr", "vespa");//生成一个Token令牌,随机设置
                token.setRememberMe(true);//设置记住我
                try {
                    currentUser.login(token);//执行登录操作
                } catch (UnknownAccountException uae) {//未知的账户
                    log.info("There is no user with username of " + token.getPrincipal());
                } catch (IncorrectCredentialsException ice) {//证书不正确
                    log.info("Password for account " + token.getPrincipal() + " was incorrect!");
                } catch (LockedAccountException lae) {//用户被锁定
                    log.info("The account for username " + token.getPrincipal() + " is locked.  " +
                            "Please contact your administrator to unlock it.");
                }
                //...还可以捕获更多异常(也许是针对您的应用程序的自定义异常)
                catch (AuthenticationException ae) {
                    //意外状况?错误?
                }
            }
    
            //打印当前用户的主要身份信息(本案例中是用户名)
            log.info("User [" + currentUser.getPrincipal() + "] logged in successfully.");
    
            //测试角色
            if (currentUser.hasRole("schwartz")) {
                log.info("May the Schwartz be with you!");
            } else {
                log.info("Hello, mere mortal.");
            }
    
            //测试权限(不是实例级别:粗粒度)
            if (currentUser.isPermitted("lightsaber:wield")) {
                log.info("You may use a lightsaber ring.  Use it wisely.");
            } else {
                log.info("Sorry, lightsaber rings are for schwartz masters only.");
            }
    
            //(非常强大的)实例级别权限:细粒度
            if (currentUser.isPermitted("winnebago:drive:eagle5")) {
                log.info("You are permitted to 'drive' the winnebago with license plate (id) 'eagle5'.  " +
                        "Here are the keys - have fun!");
            } else {
                log.info("Sorry, you aren't allowed to drive the 'eagle5' winnebago!");
            }
    
            //注销
            currentUser.logout();
    
            //结束系统
            System.exit(0);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93

    }

  • 相关阅读:
    51单片机循迹小车工作原理与程序设计思路
    goLand 项目开发校验
    组件分享之后端组件——基于Golang实现的全局的、版本化的、点对点的文件系统go-ipfs...
    MySQL索引
    Linux命令:free命令
    护网IP去重,去白名单
    ZLMediaKit启用webrtc编译
    Golang-Gin Response 统一返回restful格式的数据
    Java#8(对一些知识点的补充)
    Python - Matplot 绘制多图 直方图和折线图并存 共用 X 轴
  • 原文地址:https://blog.csdn.net/jiey0407/article/details/126496473