进阶SpringBoot之 Shiro(1)快速开始

Shiro 是一个 Java 的安全(权限)框架,它可以在 JavaSE、JavaEE 环境下使用

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

Shiro 官网

Shiro 中文文档

GitHub 下载 Shiro

下载源码,samples -> quickstart 目录下提供了一个快速开始的 Java 程序

新建一个 Maven 项目,pom.xml 文件引入依赖:

XML 复制代码
  <dependencies>
    <dependency>
      <groupId>org.apache.shiro</groupId>
      <artifactId>shiro-core</artifactId>
      <version>2.0.1</version>
    </dependency>

    <dependency>
      <groupId>org.slf4j</groupId>
      <artifactId>jcl-over-slf4j</artifactId>
      <version>2.0.16</version>
    </dependency>

    <dependency>
      <groupId>org.apache.logging.log4j</groupId>
      <artifactId>log4j-slf4j2-impl</artifactId>
      <version>2.23.1</version>
    </dependency>

    <dependency>
      <groupId>org.apache.logging.log4j</groupId>
      <artifactId>log4j-core</artifactId>
      <version>2.23.1</version>
    </dependency>
  </dependencies>

  <build>
    <plugins>
      <plugin>
        <groupId>org.codehaus.mojo</groupId>
        <artifactId>exec-maven-plugin</artifactId>
        <version>3.4.1</version>
        <executions>
          <execution>
            <goals>
              <goal>java</goal>
            </goals>
          </execution>
        </executions>
        <configuration>
          <classpathScope>test</classpathScope>
          <mainClass>Quickstart</mainClass>
        </configuration>
      </plugin>
    </plugins>
  </build>

quickstart -> resources 目录下的所有文件复制到新建的 Maven 项目下 resources 目录

log4j2.xml 文件:

XML 复制代码
<Configuration name="ConfigTest" status="ERROR" monitorInterval="5">
    <Appenders>
        <Console name="Console" target="SYSTEM_OUT">
            <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
        </Console>
    </Appenders>
    <Loggers>
        <Logger name="org.springframework" level="warn" additivity="false">
            <AppenderRef ref="Console"/>
        </Logger>
        <Logger name="org.apache" level="warn" additivity="false">
            <AppenderRef ref="Console"/>
        </Logger>
        <Logger name="net.sf.ehcache" level="warn" additivity="false">
            <AppenderRef ref="Console"/>
        </Logger>
        <Logger name="org.apache.shiro.util.ThreadContext" level="warn" additivity="false">
            <AppenderRef ref="Console"/>
        </Logger>
        <Root level="info">
            <AppenderRef ref="Console"/>
        </Root>
    </Loggers>
</Configuration>

shiro.ini 文件:

XML 复制代码
[users]
# user 'root' with password 'secret' and the 'admin' role
root = secret, admin
# user 'guest' with the password 'guest' and the 'guest' role
guest = guest, guest
# user 'presidentskroob' with password '12345' ("That's the same combination on
# my luggage!!!" ;)), and role 'president'
presidentskroob = 12345, president
# user 'darkhelmet' with password 'ludicrousspeed' and roles 'darklord' and 'schwartz'
darkhelmet = ludicrousspeed, darklord, schwartz
# user 'lonestarr' with password 'vespa' and roles 'goodguy' and 'schwartz'
lonestarr = vespa, goodguy, schwartz

[roles]
# 'admin' role has all permissions, indicated by the wildcard '*'
admin = *
# The 'schwartz' role can do anything (*) with any lightsaber:
schwartz = lightsaber:*
# The 'goodguy' role is allowed to 'drive' (action) the winnebago (type) with
# license plate 'eagle5' (instance specific id)
goodguy = winnebago:drive:eagle5

Quickstart.java 文件:(建议直接分析源码)

工厂模式,读取配置文件,创建实例

获取当前用户对象 Subject

通过当前用户拿到 Shiro 的 Session

判断当前用户是否被认证,拿到 Token,根据用户名和密码拿到令牌

捕获异常,测试角色,最后结束

java 复制代码
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.env.BasicIniEnvironment;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.Subject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class Quickstart {

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

    public static void main(String[] args) {

        SecurityManager securityManager = new BasicIniEnvironment("classpath:shiro.ini").getSecurityManager();
        SecurityUtils.setSecurityManager(securityManager);

        //获取当前用户对象Subject
        Subject currentUser = SecurityUtils.getSubject();

        //通过当前用户拿到Shiro的Session
        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()) {
            //Token:令牌
            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);
    }
}

运行结果如下:

总结:

1.导入依赖

2.配置文件

3.快速开始

相关推荐
code_std5 分钟前
保存文件到指定位置,读取/删除指定文件夹中文件
java·spring boot·后端
小许学java12 分钟前
Spring事务和事务传播机制
java·数据库·spring·事务
大学生资源网12 分钟前
基于Javaweb技术的宠物用品商城的设计与实现(源码+文档)
java·mysql·毕业设计·源码·springboot
汤姆yu14 分钟前
基于springboot的热门文创内容推荐分享系统
java·spring boot·后端
星光一影15 分钟前
教育培训机构消课管理系统智慧校园艺术舞蹈美术艺术培训班扣课时教务管理系统
java·spring boot·mysql·vue·mybatis·uniapp
lkbhua莱克瓦2418 分钟前
MySQL介绍
java·开发语言·数据库·笔记·mysql
武昌库里写JAVA21 分钟前
在iview中使用upload组件上传文件之前先做其他的处理
java·vue.js·spring boot·后端·sql
董世昌4124 分钟前
什么是事件冒泡?如何阻止事件冒泡和浏览器默认事件?
java·前端
好度31 分钟前
配置java标准环境?(详细教程)
java·开发语言
teacher伟大光荣且正确35 分钟前
关于Qt QReadWriteLock(读写锁) 以及 QSettings 使用的问题
java·数据库·qt