介绍
概述
Apache Shiro 是 Java 的一个安全(权限)框架。
Shiro 不仅可以用在 JavaSE 环境,也可以用在 JavaEE 环境。
Shiro 可以完成:认证、授权、加密、会话管理、与 Web 集成、缓存等。
Shiro 官网:https://shiro.apache.org | 关注文章首部微信公众号发送 #116_shiro
下载源码包
功能
Apache Shiro是一个具有许多功能的综合应用程序安全框架,基本的功能如下:
Authentication:身份验证。
Authorization:授权,即访问控制的过程,指定“谁”可以访问“什么资源”。
Session Management:会话管理,即使在非 Web 或 EJB 应用程序中,也可以管理特定于用户的会话。
Cryptography:加密,使用加密算法保持数据安全,同时仍然易于使用。
快速开始
下面代码是 shiro 提供的快速开始示例,这里对其注释及提示做了中文替换易于理解,路径为
shiro-root-1.3.2\samples\quickstart
。
1、使用 Maven 创建 Java 工程,导入如下依赖:
<!-- 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/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.zze.shiro</groupId>
<artifactId>shiro_test</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-all</artifactId>
<version>1.3.2</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.16</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.6.2</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.6.2</version>
</dependency>
</dependencies>
</project>
2、引入配置文件:
# shiro.ini
[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
# log4j.properties
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
3、示例代码:
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 Quickstart {
private static final transient Logger log = LoggerFactory.getLogger(Quickstart.class);
public static void main(String[] args) {
// 加载 shiro.ini 创建 SecurityManagerFactory
Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro.ini");
// 获取 SecurityManager 实例
SecurityManager securityManager = factory.getInstance();
// 通过 SecurityUtils 操作 SecurityManager 实例
SecurityUtils.setSecurityManager(securityManager);
// 获得 Subject,相当于获取到当前用户
Subject currentUser = SecurityUtils.getSubject();
// 获得 Session
Session session = currentUser.getSession();
// Session 中存值
session.setAttribute("someKey", "aValue");
// Session 中取值
String value = (String) session.getAttribute("someKey");
// 判断是否取到值
if (value.equals("aValue")) {
log.info("获取到正确的值:[" + value + "]");
}
// 通过 Subject.isAuthenticated() 判断当前用户是否以认证
if (!currentUser.isAuthenticated()) { // 如果未认证
// 创建用户名密码Token,与 shiro.ini 中 users 下配置比对
UsernamePasswordToken token = new UsernamePasswordToken("lonestarr", "vespa");
// 记住我
token.setRememberMe(true);
try {
// 执行登陆操作
currentUser.login(token);
} catch (UnknownAccountException uae) {// 用户名不存在
log.info("没有这个用户名的用户: " + token.getPrincipal());
} catch (IncorrectCredentialsException ice) { // 密码错误
log.info(token.getPrincipal() + "的密码错误");
} catch (LockedAccountException lae) { // 账户已锁定
log.info("用户名为" + token.getPrincipal() + "账户已锁定");
} catch (AuthenticationException ae) { // 上面三个异常的父类
}
}
// 如果已认证,currentUser.getPrincipal() 不为空
if (currentUser.getPrincipal() != null) {
log.info("用户 [" + currentUser.getPrincipal() + "] 登录成功");
// 通过 Subject.hasRole() 方法判断当前用户是否拥有某个角色
if (currentUser.hasRole("schwartz")) {
log.info("你有[schwartz]这个角色");
} else {
log.info("你没有[schwartz]这个角色");
}
// 判断当前用户是否拥有某个权限
// schwartz 角色对应的权限为 lightsaber:*,即可以对 lightsaber 做任何操作
if (currentUser.isPermitted("lightsaber:weild")) {
log.info("你可以对[lightsaber]使用[weild]");
} else {
log.info("对不起,[lightsaber]权限只有[schwartz]拥有");
}
// 更细粒度的判断当前用户是否拥有某个权限
if (currentUser.isPermitted("winnebago:drive:eagle5")) {
log.info("你可以[drive]标识为[eagle5]的[winnebago]");
} else {
log.info("对不起,你不允许[drive]标识未[eagle5]的[winnebago]");
}
}
// 登出
currentUser.logout();
System.exit(0);
}
}
评论区