Apache Shiro 是一个功能强大且易于使用的 Java 安全(权限)框架 。Shiro 可以完 成: 认证、授权、加密、会话管理、与 Web 集成、缓存 等。借助 Shiro 您可以快速轻松 地保护任何应用程序——从最小的移动应用程序到最大的 Web 和企业应用程序。
官网:https://shiro.apache.org/
- shrio开源自 2003 年,到目前为止框架格局发生了相当大的变化,因此今天仍然有很多系统在使用 Shiro。这与 Shiro 的特性密不可分。
- 易于使用:使用 Shiro 构建系统安全框架非常简单。
- 全面:Shiro 包含系统安全框架需要的功能,满足安全需求的“一站式服务”。
- 灵活:Shiro 可以在任何应用程序环境中工作。虽然它可以在 Web、EJB 和 IoC 环境中工作,但不需要依赖它们。Shiro 也没有强制要求任何规范,甚至没有很多依赖项。
- 强力支持 Web:Shiro 具有出色的 Web 应用程序支持,可以基于应用程序 URL 和
- Web 协议(例如 REST)创建灵活的安全策略,同时还提供一组 JSP 库来控制页面输出。
- 兼容性强:Shiro 的设计模式使其易于与其他框架和应用程序集成。Shiro 与
- Spring、Grails、Wicket、Tapestry、Mule、Apache Camel、Vaadin 等框架无缝集成。社区支持:Shiro 是 Apache 软件基金会的一个开源项目,有完备的社区支
- Shiro 的配置和使用比较简单。
- Shiro 依赖性低,不需要任何框架和容器,可以独立运行.Spring Security 依赖 Spring 容器;
- shiro 不仅仅可以使用在 web 中,它可以工作在任何应用环境中。在集群会话时 Shiro最重要的一个好处或许就是它的会话是独立于容器的。
- Authentication:身份验证也可以叫做登录,是验证用户对应的身份;
- Authorization:授权,即权限验证,验证用户是否有需要的权限,也就是判断权限够不够格能不能操作
- Session Manager:会话管理,即用户登录后就是一次会话,在没有退出之前,它的
- 所有 信息都在会话中;
- Cryptography:加密,保护数据的安全性。可以设置加密方式如MD5加密
- Web Support:Web 支持,可以非常容易的集成到 Web 环境
- Caching:缓存,登录过一次之后就缓存 之后再去判断权限之类的直接拿缓存
- Concurrency:Shiro 支持多线程应用的并发验证
- Testing:提供测试支持;
- Subject:在Shiro中所做的几乎所有事情都基于当前执行的用户,称为Subject。
- Remember Me:内置“记住我”–Shiro API中的标准功能是在用户返回应用程序时记住他们。
我们需要先创建一个maven依赖,因为上面说了shiro是不依赖容器的,在导入依赖
org.apache.shiro
shiro-core
1.9.0
commons-logging
commons-logging
1.2
Shiro 获取权限相关信息可以通过数据库获取,也可以通过 ini 配置文件获取
[users]
name1=abc123
name2=nb666
name1就是账号 abc123就是密码 格式是账号=密码
package com.project.shiro;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.config.IniSecurityManagerFactory;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.subject.Subject;
public class ShiroRun {
public static void main(String[] args) {
// 初始化获取SecurityManger
IniSecurityManagerFactory factory = new IniSecurityManagerFactory("classpath:shiro.ini");
// 获取数据
SecurityManager securityManager = factory.getInstance();
// 使用工具类设置数据
SecurityUtils.setSecurityManager(securityManager);
// 获取Subject对象
Subject subject = SecurityUtils.getSubject();
// 创建token对象 web应用用户名密码从页面传递 这里是从shiro.ini中获取的账号密码
AuthenticationToken token = new UsernamePasswordToken("name1","abc123");
// 完成登录
try {
// 此方法是进行登录
subject.login(token);
System.out.println("登录成功");
} catch (Exception e) {
e.printStackTrace();
System.out.println("登录失败");
}
}
}
这样子我们就算是创建好了。接下来点击运行即可
这里我们需要去在ini中给用户指定角色 name1=abc123,admin
// 完成登录
try {
// 此方法是进行登录
subject.login(token);
System.out.println("登录成功");
// hasRole这个api是判断角色
if (subject.hasRole("admin")){
System.out.println("恭喜admin用户访问");
}else {
System.out.println("不是admin不允许访问");
}
} catch (Exception e) {
e.printStackTrace();
System.out.println("登录失败");
}
这里我们还需要给角色设置权限
[roles]
admin=user:delete
// 判断有没有权限
if (subject.isPermitted("user:delete")){
System.out.println("允许删除");
}else {
System.out.println("没有权限不允许删除");
}
因为我们给了权限那么肯定是运行删除的 运行一下看看:
package com.project.shiro;
import org.apache.shiro.crypto.hash.Md5Hash;
public class ShiroMd5 {
public static void main(String[] args) {
// 明文 设置我们的密码
String password = "abc123";
// 加密
Md5Hash md5Hash = new Md5Hash(password);
System.out.println("MD5加密的密文=" + md5Hash);
// 加盐加密
Md5Hash md5Hash1 = new Md5Hash(password, "abc");
System.out.println("MD5加盐加密的密文=" + md5Hash1);
// 三层加密
Md5Hash md5Hash2 = new Md5Hash(password, "abc", 3);
System.out.println("MD5三层加密的密文=" + md5Hash2);
}
}
因为我们日常写的密码肯定是需要通过加密传输的,但是因为有些用户设置密码过于简单那么我们可以给设置加密,如果觉得还不安全可以设置加盐加密,如果还是不满足,那么直接使用这个三层加密,让密码更安全更不会被窃取
因为默认的登录认证是不带加密的,想要实现加密的话我们可以自己写一个Realm类,首先要设置自定义的话呢我们必须要继承AuthenticatingRealm然后在这个类中做自己需要的业务和认证条件。
package com.project.shiro;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.realm.AuthenticatingRealm;
import org.apache.shiro.util.ByteSource;
// 必须要继承AuthenticatingRealm 这里我们就模拟一下就行
public class MyRealm extends AuthenticatingRealm {
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws
AuthenticationException {
//1 获取身份信息
String principal = authenticationToken.getPrincipal().toString();
//2 获取凭证信息
String password = new String((char[]) authenticationToken.getCredentials());
System.out.println("认证用户信息:" + principal + "---" + password);
//3 获取数据库中存储的用户信息
if (principal.equals("name1")) {
//3.1 设置三层加密之后的密码
Md5Hash md5Hash2 = new Md5Hash(password, "abc", 3);
//3.2 创建封装了校验逻辑的对象,将要比较的数据给该对象
AuthenticationInfo info = new SimpleAuthenticationInfo(
// 身份信息
authenticationToken.getPrincipal(),
// 加密后的密码
pwdInfo,
// 加盐的方式
ByteSource.Util.bytes("abc"),
// 信息
authenticationToken.getPrincipal().toString());
// 必须要返回
return info;
}
// 如果不符合用户信息直接返回空
return null;
}
}
还需要去shiro.ini中添加代码 注意: myrealm=自己的Realm的绝对路径 ,还需要把密码改成加密的密码哟
[main]
md5CredentialsMatcher=org.apache.shiro.authc.credential.Md5CredentialsMatcher
md5CredentialsMatcher.hashIterations=3
myrealm=com.project.shiro.MyRealm
myrealm.credentialsMatcher=$md5CredentialsMatcher
securityManager.realms=$myrealm
运行
至此我们的案例也就结束了。shiro是一个让我们写项目上手更简单更容易上手的一个安全框架.让我们一起期待一下下一篇文章吧。