shiro简介

官网

Apache Shiro是一个强大且易用的Java安全框架,执行身份验证、授权、密码和会话管理。使用Shiro的易于理解的API,您可以快速、轻松地获得任何应用程序,从最小的移动应用程序到最大的网络和企业应用程序。

框架图说明

官网架构说明

从外部查看shiro框架

>应用代码直接交互的对象是Subject,也就是说Shiro的对外API核心就是Subject

api 说明
Subject 主体,代表当前'用户'。这个用户不一定是一个具体的人,与当前应用交互的任何东西都是Subject,如网络爬虫,机器人等;即一个抽象概念;所有Subject都绑定到SecurityManager,与Subject的所有交互都会委托给SecurityManager;可以把Subject认为是一个门面;SecurityManager才是实际的执行者
Shiro SecurityManager 安全管理器;即所有与安全有关的操作都会与SecurityManager交互;且它管理着所有Subject;可以看出它是Shiro的核心,它负责与后边介绍的其他组件进行交互,可以把它看成DispatcherServlet前端控制器
Realm ,Shiro从从Realm获取安全数据(如用户、角色、权限),就是说SecurityManager要验证用户身份,那么它需要从Realm获取相应的用户进行比较以确定用户身份是否合法;也需要从Realm得到用户相应的角色/权限进行验证用户是否能进行操作;可以把Realm看成DataSource,即安全数据源。

内部结构框架

组件 说明
Subject 主体,可以看到主体可以是任何可以与应用交互的“用户”;
SecurityManager 相当于SpringMVC中的DispatcherServlet或者Struts2中的FilterDispatcher;是Shiro的心脏;所有具体的交互都通过SecurityManager进行控制;它管理着所有Subject、且负责进行认证和授权、及会话、缓存的管理。
Authenticator 认证器,负责主体认证的,这是一个扩展点,如果用户觉得Shiro默认的不好,可以自定义实现;其需要认证策略(Authentication Strategy),即什么情况下算用户认证通过了;
Authrizer 授权器,或者访问控制器,用来决定主体是否有权限进行相应的操作;即控制着用户能访问应用中的哪些功能;
Realm 可以有1个或多个Realm,可以认为是安全实体数据源,即用于获取安全实体的;可以是JDBC实现,也可以是LDAP实现,或者内存实现等等;由用户提供;注意:Shiro不知道你的用户/权限存储在哪及以何种格式存储;所以我们一般在应用中都需要实现自己的Realm;
SessionManager 如果写过Servlet就应该知道Session的概念,Session呢需要有人去管理它的生命周期,这个组件就是SessionManager;而Shiro并不仅仅可以用在Web环境,也可以用在如普通的JavaSE环境、EJB等环境;所有呢,Shiro就抽象了一个自己的Session来管理主体与应用之间交互的数据;这样的话,比如我们在Web环境用,刚开始是一台Web服务器;接着又上了台EJB服务器;这时想把两台服务器的会话数据放到一个地方,这个时候就可以实现自己的分布式会话(如把数据放到Memcached服务器);
SessionDAO DAO大家都用过,数据访问对象,用于会话的CRUD,比如我们想把Session保存到数据库,那么可以实现自己的SessionDAO,通过如JDBC写到数据库;比如想把Session放到Memcached中,可以实现自己的Memcached SessionDAO;另外SessionDAO中可以使用Cache进行缓存,以提高性能;
CacheManager 缓存控制器,来管理如用户、角色、权限等的缓存的;因为这些数据基本上很少去改变,放到缓存中后可以提高访问的性能
Cryptography 密码模块,Shiro提高了一些常见的加密组件用于如密码加密/解密的。

常见单词说明

单词 说明
Subject 主体
Security 完全
Realm 领域、范围
Autherticator 认证器
Authentication 认证
Authorizer 授权器
Authorization 授权
Cryptography 密码、加密
Credential 证书、凭证 密码
Matcher 匹配器
Principal 身份

Shiro中的shiro.ini说明

shiro.ini放置在classpath路径下shiro会自动查找。

ini配置文件中有四大主要配置类

main users roles urls

main

提供了对根对象securityManager及其依赖对象的配置

#创建对象
securityManager=org.apache.shiro.mgt.DefaultSecurityManager

其构造器必须是public空参构造器,通过反射创建相应的实例。

1、对象名=全限定类名 相对于调用public无参构造器创建对象

2、对象名.属性名=值 相当于调用setter方法设置常量值

3、对象名.属性名=$对象引用 相当于调用setter方法设置对象引用

users

提供了对用户/密码及其角色的配置,用户名=密码,角色1,角色2

username=password,role1,role2

例如:

配置用户名/密码及其角色,格式:“用户名=密码,角色1,角色2”,角色部分可省略。如:

[users]
zhang=123,role1,role2
wang=123

roles

提供了角色及权限之间关系的配置,角色=权限1,权限2

role1=permission1,permission2

例如:

配置角色及权限之间的关系,格式:“角色=权限1,权限2”;如:

[roles]
role1=user:create,user:update
role2=*

如果只有角色没有对应的权限,可以不配roles

urls

用于web,提供了对web url拦截相关的配置,url=拦截器[参数],拦截器

/index.html = anon
/admin/** = authc, roles[admin],perms["permission1"]

第一个案例

官方教程

添加对应的依赖

<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-core</artifactId>
<version>1.1.0</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>1.6.1</version>
<scope>test</scope>
</dependency> <dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.2</version>
</dependency>

添加shiro.ini文件

src/main/resource下添加



添加内容如下

[users]
root = 123456
# 账号为root 密码是 123456

认证操作

@Test
public void test() {
// 1.获取SecurityManager工厂对象
Factory<SecurityManager> factory =
new IniSecurityManagerFactory("classpath:shiro.ini");
// 2.通过Factory对象获取SecurityManager对象
SecurityManager securityManager = factory.getInstance();
// 3.将SecurityManager对象添加到当前运行环境中
SecurityUtils.setSecurityManager(securityManager); // 4.获取Subject对象
Subject subject = SecurityUtils.getSubject();
AuthenticationToken token = new UsernamePasswordToken("root", "123456");
// 登录操作
subject.login(token);
// 获取登录的状态
System.out.println(subject.isAuthenticated());
}

测试

账号密码正确

账号错误

账号错误抛 UnknownAccountException异常

密码错误



密码错误会抛 IncorrectCredentialsException异常

所以代码可以调整下:

	@Test
public void test() {
// 1.获取SecurityManager工厂对象
Factory<SecurityManager> factory =
new IniSecurityManagerFactory("classpath:shiro.ini");
// 2.通过Factory对象获取SecurityManager对象
SecurityManager securityManager = factory.getInstance();
// 3.将SecurityManager对象添加到当前运行环境中
SecurityUtils.setSecurityManager(securityManager); // 4.获取Subject对象
Subject subject = SecurityUtils.getSubject();
AuthenticationToken token = new UsernamePasswordToken("root", "111");
// 登录操作
try {
subject.login(token);
} catch (UnknownAccountException e) {
System.out.println("账号出错...");
} catch(IncorrectCredentialsException e){
System.out.println("密码出错...");
}
// 获取登录的状态
System.out.println(subject.isAuthenticated());
}

认证流程总结

login方法

DelegatingSubject中的login方法

在此方法中我们看到是 SecurityManager来管理认证操作的

继续进入

进入DefaultSecurityManager的login方法

此方法中调用Authenticator认证

AbstractAuthenticator认证

ModularRealmAuthenticator

在该方法中获取ini文件中的信息,加载解析不是在次方法中。

AuthenticatingRealm

流程描述

1、创建token令牌,token中有用户提交的认证信息即账号和密码

2、执行subject.login(token),最终由securityManager通过Authenticator进行认证

3、Authenticator的实现ModularRealmAuthenticator调用realm从ini配置文件取用户真实的账号和密码,这里使用的是IniRealm(shiro自带)

4、IniRealm先根据token中的账号去ini中找该账号,如果找不到则给ModularRealmAuthenticator返回null,如果找到则匹配密码,匹配密码成功则认证通过。

shiro教程1(HelloWorld)的更多相关文章

  1. shiro教程2(自定义Realm)

    通过shiro教程1我们发现仅仅将数据源信息定义在ini文件中与我们实际开发环境有很大不兼容,所以我们希望能够自定义Realm. 自定义Realm的实现 创建自定义Realmjava类 创建一个jav ...

  2. 2017.4.12 开涛shiro教程-第十八章-并发登录人数控制

    原博客地址:http://jinnianshilongnian.iteye.com/blog/2018398 根据下载的pdf学习. 开涛shiro教程-第十八章-并发登录人数控制 shiro中没有提 ...

  3. 2017.2.16 开涛shiro教程-第十七章-OAuth2集成(二)客户端

    原博客地址:http://jinnianshilongnian.iteye.com/blog/2018398 根据下载的pdf学习. 开涛shiro教程-第十七章-OAuth2集成 3.客户端 客户端 ...

  4. 2017.2.16 开涛shiro教程-第十七章-OAuth2集成(一)服务器端

    原博客地址:http://jinnianshilongnian.iteye.com/blog/2018398 根据下载的pdf学习. 开涛shiro教程-第十七章-OAuth2集成 1.OAuth2介 ...

  5. 2017.2.15 开涛shiro教程-第二十一章-授予身份与切换身份(二) controller

    原博客地址:http://jinnianshilongnian.iteye.com/blog/2018398 根据下载的pdf学习. 开涛shiro教程-第二十一章-授予身份与切换身份(二) 1.回顾 ...

  6. 2017.2.15 开涛shiro教程-第二十一章-授予身份与切换身份(一) table、entity、service、dao

    原博客地址:http://jinnianshilongnian.iteye.com/blog/2018398 根据下载的pdf学习. 第二十一章 授予身份与切换身份(一) 1.使用场景 某个领导因为某 ...

  7. 2017.2.12 开涛shiro教程-第七章-与Web集成

    2017.2.9 开涛shiro教程-第七章-与Web集成(一) 原博客地址:http://jinnianshilongnian.iteye.com/blog/2018398 根据下载的pdf学习. ...

  8. Apache Shiro教程

    跟开涛学系列: 来自开涛的Apache Shiro教程:http://jinnianshilongnian.iteye.com/blog/2018398 附带的代码例子:https://github. ...

  9. Spring Boot 教程(1) - HelloWorld

    Spring Boot 教程 - HelloWorld 1. Spring Boot 的由来 大家都知道,Spring框架是Java生态中举足轻重的轻量型框架,帮助我们广大的大佬们进行Java开发.S ...

随机推荐

  1. 设置DataGridView中表头颜色

    默认的DataGridView表头颜色实在不是太好看,想设置下,上google搜了一通, 都说这样设置 this.dataGridView1.ColumnHeadersDefaultCellStyle ...

  2. 第五次spring会议

    昨天所做之事: 昨天我对软件加上了换肤和透明度等功能. 今天所做之事: 我对软件加上了保密功能. private void 一键转密文ToolStripMenuItem_Click(object se ...

  3. 【Mysql】事务的四种特性和隔离级别

    四种特性: 原子性(Atomicity):事务里所有操作视为一个整理,要么全部完成,要么全回滚. 一致性(Consistency):操作前后,数据库内数据逻辑上一致.比如:1w元转账给不同的人,转出去 ...

  4. 使用Shell脚本对Linux系统和进程资源进行监控

    ShellLinux脚本 摘要:Shell语言对于接触Linux的人来说都比较熟悉,它是系统的用户界面,提供了用户与内核进行交互操作的一种接口.本文我们以Bash做为实例总结了使用Shell对系统和进 ...

  5. 11.5 vmstat:虚拟内存统计

    vmstat vmstat是Virtual Memory Statistics(虚拟内存统计)的缩写,利用vmstat命令可以对操作系统的内存信息.进程状态和CPU活动等进行监视.但是只能对系统的整体 ...

  6. php SQL 防注入的一些经验

    产生原因 一方面自己没这方面的意识,有些数据没有经过严格的验证,然后直接拼接 SQL 去查询.导致漏洞产生,比如: $id = $_GET['id']; $sql = "SELECT nam ...

  7. iOS逆向之Reveal

    Reveal是一个强大的UI分析工具,使用它可以查看各个界面的视图层级,在解决界面显示问题时非常有用.它最大的特点就是非常直观,查看UI布局的时候非常方便. 我们知道,Reveal官网提供的方法只能监 ...

  8. 背水一战 Windows 10 (72) - 控件(控件基类): UIElement - UIElement 的位置, UIElement 的布局, UIElement 的其他特性

    [源码下载] 背水一战 Windows 10 (72) - 控件(控件基类): UIElement - UIElement 的位置, UIElement 的布局, UIElement 的其他特性 作者 ...

  9. 优化版小程序canvas,增加失败逻辑,及完善文字

    wxml <view class="shareBox" style="backgound:{{isShow ? '#000' : '#fff'}}" wx ...

  10. Vue自定义指令,ref ,sync,slot

    一.自定义指令 vue中可以自己设置指令,通过directive来实现,有2种创建方式,一种是局部创建,一种是全局创建. 第一种:局部创建 如果想注册局部指令,组件中也接受一个 directives  ...