欢迎您访问 最编程 本站为您分享编程语言代码,编程技术文章!
您现在的位置是: 首页

官方 Shiro 示例 quick_start

最编程 2024-04-16 21:06:45
...

Shiro

前言

Apache Shiro 是一个功能强大,使用简单的 Java安全框架。

Shiro可以完成 认证、授权、加密、会话管理、Web集成、缓存等操作

Shiro不仅可以用在 JavaSE环境,也可以用在 JavaEE环境

Shiro官网

GitHub

QuickStart

从 Shiro的 GitHub中找到 quickStart模块

resources目录下有两个配置文件分别是 log4j的日志配置、shiro 认证和授权的一些配置。

log4j 日志配置

log4j.rootLogger=INFO, stdout
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d %p [%c] - %m %n
log4j.logger.org.apache=WARN
log4j.logger.org.springframework=WARN
log4j.logger.org.apache.shiro=INFO
log4j.logger.org.apache.shiro.util.ThreadContext=WARN
log4j.logger.org.apache.shiro.cache.ehcache.EhCache=WARN

Shiro 用户和角色配置

[users]
root = secret, admin
guest = guest, guest
presidentskroob = 12345, president
darkhelmet = ludicrousspeed, darklord, schwartz
lonestarr = vespa, goodguy, schwartz

[roles]
admin = *
schwartz = lightsaber:*
goodguy = winnebago:drive:eagle5

而 Java目录下仅有一个 演示部分功能的可运行类

public class Quickstart {

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


    public static void main(String[] args) {
        // 从 resources目录下的 shiro.ini文件 读取 shiro的用户和角色配置,通过配置创建一个 工厂实例
        Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro.ini");
        // 得到 SecurityManager实例
        SecurityManager securityManager = factory.getInstance();

        SecurityUtils.setSecurityManager(securityManager);
        // 通过工具类获取 Subject对象,也就是当前用户对象
        Subject currentUser = SecurityUtils.getSubject();
        // 通过 Subject(当前用户)对象获取 Session
        Session session = currentUser.getSession();
        // 往 Session中设置了 一个 key为 "someKey" value为 "aValue"的值
        session.setAttribute("someKey", "aValue");
        // 取这个值
        String value = (String) session.getAttribute("someKey");
        // 判断该值的 value是否为 "aValue"
        if (value.equals("aValue")) {
            // 是的话日志就打印以下字符串和 value
            log.info("Retrieved the correct value! [" + value + "]");
        }
        // 判断当前用户是否认证
        if (!currentUser.isAuthenticated()) {
            // 将登录信息封装进令牌对象中
            UsernamePasswordToken token = new UsernamePasswordToken("lonestarr", "vespa");
            // 通过该令牌设置记住我
            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);
    }
}

运行后的日志打印

我们从该类中提取一些关键方法

  • // 通过工具类获取 Subject对象,也就是当前用户对象
    Subject currentUser = SecurityUtils.getSubject();
    
    • 主体,代表了当前 "用户"。
    • 这个用户不一定是一个具体的人,与当前应用交互的任何东西都是 Subject,如网络爬虫,机器人等。
    • 所有 Subject 都绑定到 SecurityManager,与 Subject 的所有交互都会委托给 SecurityManager。
      • 我们可以把 Subject 认为是一个门面,SecurityManager 才是实际的执行者。
  • // 通过 Subject(当前用户)对象获取 Session,
    Session session = currentUser.getSession();
    
    • 该 Session是 Shiro特有的实例 它不需要HTTP环境。
    • 也就是说该 Session可以运行在非 Web的环境下
  • // 往 Session中设置了 一个 key为 "someKey" value为 "aValue"的值
    session.setAttribute("someKey", "aValue");
    
  • // 当前用户是否被认证
    currentUser.isAuthenticated()
    // 获取当前用户名
    currentUser.getPrincipal()
    // 当前用户是否拥有该角色
    currentUser.hasRole("schwartz")
    // 当前用户是否拥有该权限
    currentUser.isPermitted("lightsaber:wield")
    // 注销
    currentUser.logout();
    

大部分都是 Subject对象的方法,通过该 quickStart我们大概能窥得 Shiro的 Subject对象一些端倪

那就到这里了,歇一歇准备写 SpringBoot整合 Shiro,剩下的 Shiro相关在那里面细说吧


放松一下眼睛

原图P站地址

画师主页