table of Contents
- 1. Download and unzip
- 2. The first Shiro program
- Three, shiro.ini analysis
- Four, Quickstart.java source code analysis
-
- 1. Use the specified class to initialize the log object
- 2. Create a SecurityManager instance through the .ini file
- 3. Get the currently executing user subject
- 4. Get the session access value through the current user and print it
- 5. Test whether the current user is authenticated
- 6. Print the main identity information of the current user
- 7. Determine the current user role
- 8. Determine the permissions of the current user
- 9. Log out and end the system
1. Download and unzip
First download Shiro
: https://github.com/apache/shiro
Unzip after downloading
2. The first Shiro program
Next we write the first Shiro program according to official documents
Official documents:
A 10-minute tutorial on Apache Shiro: http://shiro.apache.org/10-minute-tutorial.html
Your first Apache Shiro application: http://shiro.apache.org/tutorial.html
Create a new ordinary maven project, delete the src
directory, and then create a new one module
:hello-shiro
According to the official document:
Next enter the samples/quickstart
directory, you can see the src directory and the corresponding pom.xml, this is for us to quickly get started with the source code of a maven project in shiro, then we copy the code corresponding to the project to our own creation In the project
1. Import dependencies
Copy
pom.xml
thedependency
dependencies to the pom.xml of the project you created
<dependencies>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-core</artifactId>
</dependency>
<!-- configure logging -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jcl-over-slf4j</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<scope>runtime</scope>
</dependency>
</dependencies>
Then replace it with a dependency with a version number, pay attention to delete the scope
attribute! ! Otherwise the test result cannot be successful
<dependencies>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-core</artifactId>
<version>1.6.0</version>
</dependency>
<!-- configure logging -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jcl-over-slf4j</artifactId>
<version>2.0.0-alpha1</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>2.0.0-alpha1</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
</dependencies>
2. Configure shiro configuration file
The quickstart\src\main\resources
under log4j.properties
and shiro.ini
copied to the project resources directory
where .ini
the file was not highlighted, IDEA prompt us to install the plug-in, we click install plugins
install it
and then click OK
to
complete as soon as there is highlighted
3. Quickstart.java
The
quickstart\src\main\java
directoryQuickstart.java
java directory to your project
If you find a hot spot, import
delete the two hot spots at this time.
4. Start the test
Quickstart
Main method to run
It was found that some log information was printed. So far, our first shiro program quickstart has been completed.
Three, shiro.ini analysis
Let’s analyze the official quick-start INI Realm configuration file, which can be divided into two parts
- Set user name and corresponding role
- Set permissions for roles
#快速入门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
Four, Quickstart.java source code analysis
Let’s analyze the following official
Quickstart.java
1. Use the specified class to initialize the log object
private static final transient Logger log = LoggerFactory.getLogger(Quickstart.class);
By obtaining the log object, print subsequent log information
2. Create a SecurityManager instance through the .ini file
//创建带有realms,users,roles和permissions配置的Shiro SecurityManager的最简单方法是使用简单的ini配置
//我们将使用可提取.ini文件(在类路径的根目录下使用shiro.ini文件)的工厂返回一个SecurityManager实例
Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro.ini");
SecurityManager securityManager = factory.getInstance();
//对于这个简单的示例快速入门,请使SecurityManager作为JVM单例访问。
//大多数应用程序都不会这样做,而在webapps会依靠其容器配置或web.xml进行使用
SecurityUtils.setSecurityManager(securityManager);
At this point, the basic shiro environment has been set up, and the next thing to do is some of my own operations
3. Get the currently executing user subject
//获取当前执行的用户subject
Subject currentUser = SecurityUtils.getSubject();
4. Get the session access value through the current user and print it
//通过当前用户得到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的值
}
5. Test whether the current user is authenticated
//测试当前用户是否被认证
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) {
//意外状况?错误?
}
}
6. Print the main identity information of the current user
//打印当前用户的主要身份信息(本案例中是用户名)
log.info("User [" + currentUser.getPrincipal() + "] logged in successfully.");
7. Determine the current user role
//测试角色
if (currentUser.hasRole("schwartz")) {
log.info("May the Schwartz be with you!");
} else {
log.info("Hello, mere mortal.");
}
8. Determine the permissions of the current user
//测试权限(不是实例级别:粗粒度)
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!");
}
9. Log out and end the system
//注销
currentUser.logout();
//结束系统
System.exit(0);
Complete annotated code:
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<SecurityManager> 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);
}
}