shiro的简介(一)
戒色诗: 二八佳人体似酥,腰间仗剑斩凡夫。虽然不见人头落,暗里教君骨髓枯。
关于Shiro 的教程,推荐大家看 张开涛前辈写得 跟我学Shiro, 写得非常好。
老蝴蝶写得这个 Shiro 系列,侧重于实际应用,所以太深奥的内容不进行讲解,大家看张开涛前辈写的Shiro 文章就好。
另,本系列shiro 内容会大量参考张开涛前辈的文章,谢谢!!!
一. Shiro的出现
一.一 为什么要出现 Shiro?
前面,我们在控制权限,保障数据隐私和安全时,都是自己编写的代码程序进行相应的控制。
我们自己前面实现的 权限验证,操作复杂,功能简单,复用率低, 一些常见的功能,如 单点登录,记住我,密码加密等,很难实现,还需要根据不同的框架写不同的过滤器或者拦截器,自己手动配置静态的和不需要认证的页面url.
我们希望能有一个工具,就像 Quartz 实现作业调度一样,实现权限的控制? 我们只需要把用户,角色,权限的数据交给这个工具,通过简单的配置,这个工具就能自动帮我们实现认证和授权的操作。
有这个工具,这个工具就是 Shiro.
Shiro 可以帮我们快速地实现 认证和授权的功能,保障系统地安全。
一.二 Shiro的简介和下载
Shiro 是一个强大的 Java安全框架,越来越多的人使用它。适用于 JavaSE 和 JavaEE。
可以进行 认证,授权,加密和会话管理 ,也支持Web,单点登录,记住我等功能。
Shiro属于Apache 组织下的项目,官网为: http://shiro.apache.org/
我们下载的是经典的 1.2.2 版本
在maven 中直接 引入 shiro-all 的依赖
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-all</artifactId>
<version>1.2.2</version>
</dependency>
相应的jar包为:
在写 shiro 的例子之前,我们需要先了解关于Shiro 的一些概念。(概念摘录于张开涛前辈的shiro文章)
二. Shiro 相关概念介绍
二.一 Shiro 的功能模块
二.一.一 功能模块图片
Shiro 会我们提供了这些功能。
二.一.二 功能模块解释
功能模块名 | 对应解释 |
---|---|
Authentication | 身份认证(通俗讲为登录),验证用户是否是合法的用户 |
Authorization | 授权(通俗讲为权限验证),验证某个已经认证通过的用户是否具有某个权限,用于判断用户是否能做某些事情 |
Session Manager | 会话管理。用户登录后就是一次会话,在没有退出之前,它的所有的信息都会在会话里面。会话可以是 JavaSE环境,也可以是Web环境 |
Cryptography | 加密,用于保护数据的安全性,如密码加密,而不是明文存储 |
Web Support | Web支持,用于集成到 Web环境 |
Caching | 缓存,用户登录之后,其用户信息,拥有的角色和权限不必每次都去查,可以提高效率,如ehcache缓存 |
Concurrency | 多线程并发验证,即如在一个线程中开启另一个线程,就能把权限自动传播过去 |
Testing | 提供测试支持 |
Run As | 允许一个用户假装为另一个用户(如果他们允许)的身份进行访问 |
Remember Me | 记住我,即一次登录后,下次再来的话,就不用重新登录 |
常用的就是,身份认证 Authentication,授权 Authorization,加密 Cryptography和 记住我 Remember Me.
二.二 Shiro 的外部架构
二.二.一 外部架构图片
Shiro 的三大主体, Subject, SecurityManager, Realm 如何进行工作的。
二.二.二 外部架构的名词解释
名称 | 对应解释 |
---|---|
Subject | 主体,代表当前的"用户",但这个用户不一定指具体的人。 |
SecurityManager | 安全管理器,即所有与安全有关的操作都会与Security Manager 进行交互,它管理着所有的 Subject,是 Shiro的核心,负责与Realm 进行交互 |
Realm | 域,Shiro从域中获取安全数据,相当于DataSource 数据源 |
补充: 我们编写的代码里面使用的是 Subject,即应用代码直接交互的对象是 Subject. 所有的Subject 都会绑定到 SecurityManager上,所有的交互也都会委托给SecurityManager, 是一个门面,而Security Manager是实际的执行者。
Security Manager 相当于 SpringMVC的 DispatcherServlet 前端控制器,无处不在,功能强大。
Realm相当于数据源, SecurityManager要验证用户的身份,获取用户的权限,这个数据从哪儿获取呢? 就是通过Realm 进行获取。
总结: 应用代码通过 Subject对象调用方法, 来进行认证和授权,而Subject 又委托SecurityManager处理(即真正干活的是 SecurityManager)
需要给SecurityManager 注入Realm, 从而让SecurityManager得到合法的用户信息和角色/权限数据。
注意,数据是我们开发者提供的,Shiro 不维护数据,只查询,不更新。
二.三 Shiro 的内部架构
二.三.一 Shiro 的内部架构图片
具体的功能组件
二.三.二 内部架构解释
名称 | 解释 |
---|---|
Subject | 主体,可以看到主体是任何可以与应用交互的用户 |
SecurityManager | 所有具体的交互都是通过它进行控制的,管理着所有的Subject |
Authenticator | 认证器,负责主体认证的,需要配置认证策略 Strategy |
Authrizer | 授权器,用来决定主体是否有权限进行相应的操作 |
Realm | 安全实体数据源,用于获取数据 |
SessionManager | 会话管理,用于管理Session |
SessionDAO | 用于会话的CRUD |
CacheManager | 缓存管理,用于提高访问的性能,常存储用户,角色,权限 |
Cryptography | 密码模块,用于加密用户的密码等隐私数据 |
二.四 身份认证
身份认证,是在应用中谁能证明他就是他本人。一般提供身份的ID等标识信息来表明他就是他本人,如身份证,用户名/密码等。
包括两个部分,一个 principals(身份),credentials(证明) 两个部分。
二.四.一 principals 身份
即主体的标识属性,可以是任何东西,如用户名、邮箱等,唯一即可。一个主体可以有多个principals,但只有一个Primary principals,一般是用户名/密码/手机号。
二.四.二 credentials 证明
即只有主体知道的安全值,如密码/数字证书等
最常见的身份认证就是 用户名和密码。
其中,身份 principals 是用户名,唯一的,
证明 credentials 是密码,只有当前身份的那个用户才知道的凭证。
三. Shiro 进行认证实例
编写一个小的 Demo,来演示一下 Shiro 的具体使用。
三.一 添加 Shiro 的依赖
在 pom.xml 文件中,添加shiro 和junit 测试的 依赖
<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.yjl.shiro</groupId>
<artifactId>Shiro_Ini</artifactId>
<version>0.0.1-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-all</artifactId>
<version>1.2.2</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
</dependencies>
<build>
<plugins>
<!-- 编译的jdk版本 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
三.二 创建配置文件 shiro.ini
用户的身份密码,角色权限等信息,可以暂时配置在 .ini 文件里面。
Shiro 支持从 .ini 配置文件里面读取数据, 但要保证文件的格式正确。
我们往里面添加两个用户, yuejl 和yuezl 两个用户,密码均为 1234.
# 配置用户的信息
[users]
#用户名=密码
yuejl=1234
yuezl=1234
shiro.ini 文件要放置在 classpath 目录下。
三.三 编写 测试Demo
package com.yjl.demo;
import org.apache.shiro.SecurityUtils;
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.apache.shiro.util.Factory;
/**
*
* @author 两个蝴蝶飞
* Shiro 的第一个演示文件
*/
public class ShiroDemo1 {
public static void main(String[] args) {
//1. 创建工厂
Factory<SecurityManager> factory=new IniSecurityManagerFactory("classpath:shiro.ini");
//2. 从工厂里面获取 SecurityManager
SecurityManager securityManager=factory.getInstance();
//3. 通过工具类设置 securityManager
SecurityUtils.setSecurityManager(securityManager);
//4. 获取当前登录的用户
Subject subject=SecurityUtils.getSubject();
//5. 拼装用户的身份和密码Token
UsernamePasswordToken token=new UsernamePasswordToken("yuezl","1234"); //1.正确密码
//UsernamePasswordToken token=new UsernamePasswordToken("yuezl","123456"); //2.错误密码
//6. 调用 subject 里面的login 方法,进行登录
try{
subject.login(token);
//7.判断用户是否登录成功
if(subject.isAuthenticated()){
System.out.println("用户:"+token.getUsername()+", 登录成功");
}
}catch(Exception e){
System.out.println("用户登录失败");
}
}
}
正确的密码 1234,进行测试
错误的密码 123456,进行测试
其中, token 对象里面传入的用户名和密码,就是我们以后在前端用户输入的用户名和密码,
shiro.ini 里面的用户名和密码,就是我们从数据库里面读取出来的用户的用户名和密码。
两者是如何进行比较的呢? 是通过 subject.login() 方法进行比较的。
本章节代码链接为:
链接:https://pan.baidu.com/s/1FI_r9DfOhrK84k9ru0zerA
提取码:6z3o
谢谢您的观看,我是两个蝴蝶飞, 如果喜欢,请关注我,再次感谢 !!!