Shiro简介
什么是shiro
- Apache Shiro是java的一个安全框架。Shiro可以非常容易的开发出足够好的应用,其不仅可以用在JavaSE环境,也可以用在JavaEE环境。Shiro可以帮助我们完成:认证、授权、加密、会话管理、与web集成、缓存等
- Shiro官方网站:https://shiro.apache.org
为什么要学shiro
- 既然shiro将安全认证相关的功能抽取出来组成一个框架。使用shiro就可以非常快速的完成认证、授权等功能的开发,降低系统成本。(开发和维护)
- shiro使用广泛,shiro可以运行在web应用,非web应用,集群分布式应用中越来越多的用户开始使用shiro。
基本功能
Authentication
身份认证/登录,验证用户是不是拥有相应的身份
Authorization
授权,即权限授权,验证某个已认证的用户是否拥有某个权限:即判断用不是否能做事情,常见的如:验证某个用户是否拥有某个教师。或者细粒度的验证某个用户对某个资源是否具有某个权限
Session Manager
- 会话管理,即用户登录后就是一次护花,在没有退出之前,他的所有信息都在会话中;会话可以是普通javaSe环境的,也可以是如Web环境的;
- Cryptography: 加密,保护数据的安全性,如密码加密存储到数据库,而不是明文存储;
- Web Support: Web支持,可以非常容易的集成到web环境中
- Caching: 缓存,比如用户登录后,其用户信息,拥有的角色/权限不必每次去查,这样可以提高效率;
- Concurrency: shiro支持多线程应用的并发验证,即如在一个县城中开启另一个线程,能把权限自动传播出去;
- Testing: 提供测试支持
- Run As: 允许一个用户假装成另一个用户(如果他们允许)的身份进行访问;
- Remember Me: 记住我,这个是非常常见的功能,及一次登录后,下次再来的话不用登录了
说明: shiro不会去维护用户、维护权限;这些需要我们自己去设计/提供;然后通过相应的接口注入给shiro即可
Shiro认证
基本概念
身份验证
即在应用中谁能证明他就是他本人。一般提供如他们的身份ID,一些标识信息来表名他就说他本人,如通过身份证,用户名/密码来证明。
在shiro中,用户需要提供principals(身份)和cradentials(证明)给shiro,从而应用能验证用户身份;
principals
身份,即主体的标识属性,可以是任何东西,如用户名、邮箱等,唯一即可。
一个主体可以有多个principals,但只有一个Primary principals,一般是用户名/密码/手机号
credentials
证明/凭证,即只有主体知道的安全值,如密码/数字证书等
最常见的principals和credentials组合就是用户名/密码了。接下来先进行一个基本的身份认证
认证流程
shiro入门程序工程 环境
- 新建一个名为shiro-test的空项目,再创建一个shiro-demo01的module
- 在pom.xml中导入坐标
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-core</artifactId>
<version>1.3.2</version>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-web</artifactId>
<version>1.3.2</version>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>1.3.2</version>
</dependency>
<!-- 日志 -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.32</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.32</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
<scope>test</scope>
</dependency> - 在src/main/resources下新建shiro.ini文件,注意创建方式选择properties
# 配置用户
[users]
# 用户名=密码
lucy=abc123
lili=321 - 编写测试类,在test/java下新建com.shiro.test.ShiroTest.java
package com.shiro;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.config.IniSecurityManagerFactory;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.subject.Subject;
import org.junit.Test;
public class ShiroTest {
@Test
public void shiroTest() {
// 1.读取配置文件,创建安全管理器:SecurityManager
IniSecurityManagerFactory factory = new IniSecurityManagerFactory("classpath:shiro.ini");
SecurityManager securityManager = factory.createInstance();
// 2.将工厂对象和当前线程绑定
SecurityUtils.setSecurityManager(securityManager);
// 3.从当前线程获取主体对象:Subject
Subject subject = SecurityUtils.getSubject();
// 4.判断是否认证
boolean authenticated = subject.isAuthenticated();
System.out.println("认证前:"+authenticated);
if(!authenticated) {
// 5.创建Token(令牌):封装身份(账号)和凭证(密码)
UsernamePasswordToken usernamePasswordToken = new UsernamePasswordToken("lucy", "abc123");
try{
// 6. 认证(登录)
subject.login(usernamePasswordToken);
authenticated = subject.isAuthenticated();
System.out.println("认证后:"+authenticated);
}catch (UnknownAccountException e) {
System.out.println("亲,账号不存在");
} catch(IncorrectCredentialsException e) {
System.out.println("亲,账号错误");
}
// 获取身份信息
Object principal = subject.getPrincipal();
System.out.println(principal);
// 退出认证
subject.logout();
}
}
}
自定义realm
什么是reaml?
Reaml: 领域,范围,通俗讲,你可以理解为一个特殊的dao,他主要用于对认证信息和授权信息的存取和操作,实际开发总主要调用开发者开发操作数据库相关service获取dao来进行授权认证
将来实际开发需要realm从数据库中查询用户信息