【03】你的第一个Shiro应用
说明
本章节来自官网教程,对应官网文档地址https://shiro.apache.org/tutorial.html
环境要求
教程基于最新版本的Shiro 1.9.1版本,环境要求如下:
- Java8+(java -version 命令查看java版本)
- Maven3.6.3+ (mvn --version 命令查看maven版本)
创建项目结构文件夹
新建一个文件夹shiro-tutorial
,在里面分别创建src/main/java
和src/main/resources
文件夹,结构如下:
shiro-tutorial
|—src/main/java
|—src/main/resources
创建pom.xml
在根路径shiro-tutorial
下创建pom.xml文件,内容如下:
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>org.apache.shiro.tutorials</groupId> <artifactId>shiro-tutorial</artifactId> <version>1.0.0-SNAPSHOT</version> <name>First Apache Shiro Application</name> <packaging>jar</packaging> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> </properties> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.8.0</version> <configuration> <source>1.8</source> <target>1.8</target> </configuration> </plugin> <!-- This plugin is only to test run our little application. It is not needed in most Shiro-enabled applications: --> <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>exec-maven-plugin</artifactId> <version>1.1</version> <executions> <execution> <goals> <goal>java</goal> </goals> </execution> </executions> <configuration> <classpathScope>test</classpathScope> <mainClass>Tutorial</mainClass> </configuration> </plugin> </plugins> </build> <dependencies> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-core</artifactId> <version>1.9.1</version> </dependency> <!-- Shiro uses SLF4J for logging. We'll use the 'simple' binding in this example app. See http://www.slf4j.org for more info. --> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-simple</artifactId> <version>1.7.21</version> <scope>test</scope> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>jcl-over-slf4j</artifactId> <version>1.7.21</version> <scope>test</scope> </dependency> </dependencies> </project>
创建Tutorial测试类
在src/main/java
文件夹下创建一个带有main函数的java类Tutorial.java,内容如下:
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; public class Tutorial { private static final transient Logger log = LoggerFactory.getLogger(Tutorial.class); public static void main(String[] args) { log.info("My First Apache Shiro Application"); System.exit(0); } }
测试运行
使用命令行工具CMD,切换到项目根目录shiro-tutorial
,执行命令mvn compile exec:java
,运行结果如下:
启用Shiro
Shiro支持多种配置方式,如xml、yaml、json等,示例采用ini文件方式配置
在src/main/resources
文件夹内创建文件shiro.ini,并添加以下内容:
# ============================================================================= # Tutorial INI configuration # # Usernames/passwords are based on the classic Mel Brooks' film "Spaceballs" :) # ============================================================================= # ----------------------------------------------------------------------------- # Users and their (optional) assigned roles # username = password, role1, role2, ..., roleN # ----------------------------------------------------------------------------- [users] root = secret, admin guest = guest, guest presidentskroob = 12345, president darkhelmet = ludicrousspeed, darklord, schwartz lonestarr = vespa, goodguy, schwartz # ----------------------------------------------------------------------------- # Roles with assigned permissions # roleName = perm1, perm2, ..., permN # ----------------------------------------------------------------------------- [roles] admin = * schwartz = lightsaber:* goodguy = winnebago:drive:eagle5
上面配置中设置了一小部分静态用户账号。
其中
[users]部分设置了用户的账号、密码、以及用户拥有的角色 格式为: 用户名 = 密码,角色1,角色2,角色3
[roles]部分设置了角色拥有的权限 格式为: 角色名 = 权限1,权限2
其中*代码拥有全部权限
使用Shiro
修改Tutorial.java,内容如下:
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; public class Tutorial { private static final transient Logger log = LoggerFactory.getLogger(Tutorial.class); public static void main(String[] args) { log.info("My First Apache Shiro Application"); //根据配置文件创建SecurityManager工厂 Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro.ini"); //创建securityManager实例 SecurityManager securityManager = factory.getInstance(); //设置securityManager实例 SecurityUtils.setSecurityManager(securityManager); //获取当前用户 Subject currentUser = SecurityUtils.getSubject(); //对Shiro中的session进行一些操作(Shiro的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()) { //登录用户lonestarr,密码为:vespa 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 more exceptions here (maybe custom ones specific to your application? catch (AuthenticationException ae) { //unexpected condition? error? } } //say who they are: //print their identifying principal (in this case, a username): log.info("User [" + currentUser.getPrincipal() + "] logged in successfully."); //判断用户是否具有角色schwartz if (currentUser.hasRole("schwartz")) { log.info("May the Schwartz be with you!"); } else { log.info("Hello, mere mortal."); } //判断用户是否具有权限lightsaber:wield 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."); } //a (very powerful) Instance Level permission: 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!"); } //all done - log out! currentUser.logout(); System.exit(0); } }
切换到项目根目录shiro-tutorial
,执行命令mvn compile exec:java
,运行结果如下:
概括
本教程中介绍了如何在基本应用程序中设置Shiro以及Shiro的主要概念Subject
和SecuriryManager
。