戒色诗: 二八佳人体似酥,腰间仗剑斩凡夫。虽然不见人头落,暗里教君骨髓枯。前端
关于Shiro 的教程,推荐你们看 张开涛前辈写得 跟我学Shiro, 写得很是好。数据库
老蝴蝶写得这个 Shiro 系列,侧重于实际应用,因此太深奥的内容不进行讲解,你们看张开涛前辈写的Shiro 文章就好。apache
另,本系列shiro 内容会大量参考张开涛前辈的文章,谢谢!!!缓存
前面,咱们在控制权限,保障数据隐私和安全时,都是本身编写的代码程序进行相应的控制。安全
咱们本身前面实现的 权限验证,操做复杂,功能简单,复用率低, 一些常见的功能,如 单点登陆,记住我,密码加密等,很难实现,还须要根据不一样的框架写不一样的过滤器或者拦截器,本身手动配置静态的和不须要认证的页面url.多线程
咱们但愿能有一个工具,就像 Quartz 实现做业调度同样,实现权限的控制? 咱们只须要把用户,角色,权限的数据交给这个工具,经过简单的配置,这个工具就能自动帮咱们实现认证和受权的操做。架构
有这个工具,这个工具就是 Shiro.并发
Shiro 能够帮咱们快速地实现 认证和受权的功能,保障系统地安全。框架
Shiro 是一个强大的 Java安全框架,愈来愈多的人使用它。适用于 JavaSE 和 JavaEE。maven
能够进行 认证,受权,加密和会话管理 ,也支持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 会咱们提供了这些功能。
功能模块名 | 对应解释 |
---|---|
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 的三大主体, 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 不维护数据,只查询,不更新。
具体的功能组件
名称 | 解释 |
---|---|
Subject | 主体,能够看到主体是任何能够与应用交互的用户 |
SecurityManager | 全部具体的交互都是经过它进行控制的,管理着全部的Subject |
Authenticator | 认证器,负责主体认证的,须要配置认证策略 Strategy |
Authrizer | 受权器,用来决定主体是否有权限进行相应的操做 |
Realm | 安全实体数据源,用于获取数据 |
SessionManager | 会话管理,用于管理Session |
SessionDAO | 用于会话的CRUD |
CacheManager | 缓存管理,用于提升访问的性能,常存储用户,角色,权限 |
Cryptography | 密码模块,用于加密用户的密码等隐私数据 |
身份认证,是在应用中谁能证实他就是他本人。通常提供身份的ID等标识信息来代表他就是他本人,如身份证,用户名/密码等。
包括两个部分,一个 principals(身份),credentials(证实) 两个部分。
即主体的标识属性,能够是任何东西,如用户名、邮箱等,惟一便可。一个主体能够有多个principals,但只有一个Primary principals,通常是用户名/密码/手机号。
即只有主体知道的安全值,如密码/数字证书等
最多见的身份认证就是 用户名和密码。
其中,身份 principals 是用户名,惟一的,
证实 credentials 是密码,只有当前身份的那个用户才知道的凭证。
编写一个小的 Demo,来演示一下 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>
用户的身份密码,角色权限等信息,能够暂时配置在 .ini 文件里面。
Shiro 支持从 .ini 配置文件里面读取数据, 但要保证文件的格式正确。
咱们往里面添加两个用户, yuejl 和yuezl 两个用户,密码均为 1234.
# 配置用户的信息 [users] #用户名=密码 yuejl=1234 yuezl=1234
shiro.ini 文件要放置在 classpath 目录下。
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
谢谢您的观看,我是两个蝴蝶飞, 若是喜欢,请关注我,再次感谢 !!!