Shiro核心概述
0、写在前面的话
1、Shiro的主要特性
![](https://images2018.cnblogs.com/blog/1007017/201808/1007017-20180801162002538-1797847437.png)
- Authentication - 身份认证 (与登陆相关,确定用户是谁)
- Authorization - 确认权限 (确定用户能访问什么)
- Session Management - 会话管理
- Cryptography - 数据加密
2、Shiro如何工作
2.1 从外部看Shiro
![](https://images2018.cnblogs.com/blog/1007017/201808/1007017-20180801162003081-718624117.png)
- 通过 Subject 来进行认证和授权,而 Subject 又委托给了 SecurityManager 进行管理
- 我们需要给 SecurityManager 注入 Realm 以便其获取用户和权限进行判断
- (也即,Shiro 不提供用户和权限的维护,需要由开发者自行通过 Realm 注入)
2.2 从内部看Shiro
![](https://images2018.cnblogs.com/blog/1007017/201808/1007017-20180801162003795-146976899.png)
3、Shiro身份认证概述
#shiro.ini
[users]
zhang=123
wang=123
#shiro.ini
[users]
zhang=123
wang=123
@Test
public void testHelloWorld() {
//获取SecurityManager工厂,使用shiro.ini配置文件进行初始化
Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro.ini");
//得到SecurityManager实例,并绑定给SecurityUtils
SecurityManager securityManager = factory.getInstance();
SecurityUtils.setSecurityManager(securityManager);
//得到Subject及创建用户名/密码身份验证token(即用户身份/凭证)
Subject subject = SecurityUtils.getSubject();
AuthenticationToken token = new UsernamePasswordToken("zhang", "123");
try {
//登陆
subject.login(token);
} catch (AuthenticationException e) {
//身份验证失败
e.printStackTrace();
}
//断言用户已经登陆
Assert.assertEquals(true, subject.isAuthenticated());
//退出
subject.logout();
}
@Test
public void testHelloWorld() {
//获取SecurityManager工厂,使用shiro.ini配置文件进行初始化
Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro.ini");
//得到SecurityManager实例,并绑定给SecurityUtils
SecurityManager securityManager = factory.getInstance();
SecurityUtils.setSecurityManager(securityManager);
//得到Subject及创建用户名/密码身份验证token(即用户身份/凭证)
Subject subject = SecurityUtils.getSubject();
AuthenticationToken token = new UsernamePasswordToken("zhang", "123");
try {
//登陆
subject.login(token);
} catch (AuthenticationException e) {
//身份验证失败
e.printStackTrace();
}
//断言用户已经登陆
Assert.assertEquals(true, subject.isAuthenticated());
//退出
subject.logout();
}
- 确定 Realm 的数量,根据 Realm 是否单一来确定执行方法 doSingleRealmAuthentication() 或 doMultiRealmAuthentication()
- 不论哪个方法都会要求通过 Realm 和 token(getAuthenticationInfo(AuthenticationToken token)) 返回认证信息 AuthenticationInfo
- 而如何确定并返回这个信息,也即是确认用户登录信息和授权信息的过程,是由开发者自定义(如通过数据库抓取信息对比判断等)
- 自定义 Realm 必须实现 Realm 接口,更简单快捷的方式是继承抽象类 AuthenticatingRealm
- 继承 AuthenticatingRealm 则需要分别实现认证方法doGetAuthenticationInfo() 和 授权方法 doGetAuthorizationInfo()
4、Shiro 的权限控制
- ShiroFilter 执行过滤器链
- 通过原始过滤器链获取新的过滤器链
- FilterChainResolver 解析 url,找到对应的新的 FilterChain 过滤器链
- 执行新的过滤器链
- doFilter //Filter的doFilter
- doFilterInternal //转调doFilterInternal
- executeChain(request, response, chain) //执行过滤器链
- FilterChain chain = getExecutionChain(request, response, origChain) //使用原始过滤器链获取新的过滤器链
- chain.doFilter(request, response) //执行新组装的过滤器链
- getExecutionChain(request, response, origChain) //获取过滤器链流程
- FilterChainResolver resolver = getFilterChainResolver(); //获取相应的FilterChainResolver
- FilterChain resolved = resolver.getChain(request, response, origChain); //通过FilterChainResolver根据当前请求解析到新的FilterChain过滤器链
4.1 默认过滤器
[urls]
#authc 需要通过身份验证
#anon 匿名访问(即不需要登陆)
#roles 有角色限制,如roles[admin]表示需要admin角色才能访问
#perms 有权限限制,如perms["user:create"]表示要有"user:create"权限才能访问
/login=anon
/unauthorized=anon
/static/**=anon
/authenticated=authc
/role=authc,roles[admin]
/permission=authc,perms["user:create"]
[urls]
#authc 需要通过身份验证
#anon 匿名访问(即不需要登陆)
#roles 有角色限制,如roles[admin]表示需要admin角色才能访问
#perms 有权限限制,如perms["user:create"]表示要有"user:create"权限才能访问
/login=anon
/unauthorized=anon
/static/**=anon
/authenticated=authc
/role=authc,roles[admin]
/permission=authc,perms["user:create"]
public DefaultFilterChainManager(FilterConfig filterConfig) {
this.filters = new LinkedHashMap<String, Filter>();
this.filterChains = new LinkedHashMap<String, NamedFilterList>();
setFilterConfig(filterConfig);
//默认添加 DefaultFilter 中声明的过滤器
addDefaultFilters(true);
}
public DefaultFilterChainManager(FilterConfig filterConfig) {
this.filters = new LinkedHashMap<String, Filter>();
this.filterChains = new LinkedHashMap<String, NamedFilterList>();
setFilterConfig(filterConfig);
//默认添加 DefaultFilter 中声明的过滤器
addDefaultFilters(true);
}
public enum DefaultFilter {
anon(AnonymousFilter.class),
authc(FormAuthenticationFilter.class),
authcBasic(BasicHttpAuthenticationFilter.class),
logout(LogoutFilter.class),
noSessionCreation(NoSessionCreationFilter.class),
perms(PermissionsAuthorizationFilter.class),
port(PortFilter.class),
rest(HttpMethodPermissionFilter.class),
roles(RolesAuthorizationFilter.class),
ssl(SslFilter.class),
user(UserFilter.class);
}
public enum DefaultFilter {
anon(AnonymousFilter.class),
authc(FormAuthenticationFilter.class),
authcBasic(BasicHttpAuthenticationFilter.class),
logout(LogoutFilter.class),
noSessionCreation(NoSessionCreationFilter.class),
perms(PermissionsAuthorizationFilter.class),
port(PortFilter.class),
rest(HttpMethodPermissionFilter.class),
roles(RolesAuthorizationFilter.class),
ssl(SslFilter.class),
user(UserFilter.class);
}
4.2 自定义过滤器
- 完成自定义过滤器的编写
- 将自定义过滤器注入到 filterChains 中去
[filters]
myFilter1=com.github.zhangkaitao.shiro.chapter8.web.filter.MyOncePerRequestFilter
myFilter2=com.github.zhangkaitao.shiro.chapter8.web.filter.MyAdviceFilter
[urls]
/**=myFilter1,myFilter2
[filters]
myFilter1=com.github.zhangkaitao.shiro.chapter8.web.filter.MyOncePerRequestFilter
myFilter2=com.github.zhangkaitao.shiro.chapter8.web.filter.MyAdviceFilter
[urls]
/**=myFilter1,myFilter2
<!-- spring -->
<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
<property name="securityManager" ref="securityManager" />
<property name="loginUrl" value="/security/login.html" />
<property name="successUrl" value="/home.html" />
<property name="unauthorizedUrl" value="/security/unauthorized.html" />
<property name="filters">
<map>
<entry key="anyRoles" value-ref="anyRolesAuthorizationFilter" />
</map>
</property>
<property name="filterChainDefinitions">
<value>
/admin = anyRoles[admin1,admin2]
/** = anon
</value>
</property>
</bean>
<!-- spring -->
<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
<property name="securityManager" ref="securityManager" />
<property name="loginUrl" value="/security/login.html" />
<property name="successUrl" value="/home.html" />
<property name="unauthorizedUrl" value="/security/unauthorized.html" />
<property name="filters">
<map>
<entry key="anyRoles" value-ref="anyRolesAuthorizationFilter" />
</map>
</property>
<property name="filterChainDefinitions">
<value>
/admin = anyRoles[admin1,admin2]
/** = anon
</value>
</property>
</bean>
@Bean
public ShiroFilterFactoryBean shirFilter(SecurityManager securityManager){
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
//设置SecurityManager
shiroFilterFactoryBean.setSecurityManager(securityManager);
//自定义过滤器
Map<String, Filter> filtersMap = new LinkedHashMap<String, Filter>();
filtersMap.put("myAccessControlFilter", new MyAccessControlFilter());
shiroFilterFactoryBean.setFilters(filtersMap);
//过滤器
Map<String,String> filterChainDefinitionMap = new LinkedHashMap<String,String>();
filterChainDefinitionMap.put("/createPermission", "anon");
filterChainDefinitionMap.put("/**", "myAccessControlFilter");
shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
return shiroFilterFactoryBean;
}
@Bean
public ShiroFilterFactoryBean shirFilter(SecurityManager securityManager){
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
//设置SecurityManager
shiroFilterFactoryBean.setSecurityManager(securityManager);
//自定义过滤器
Map<String, Filter> filtersMap = new LinkedHashMap<String, Filter>();
filtersMap.put("myAccessControlFilter", new MyAccessControlFilter());
shiroFilterFactoryBean.setFilters(filtersMap);
//过滤器
Map<String,String> filterChainDefinitionMap = new LinkedHashMap<String,String>();
filterChainDefinitionMap.put("/createPermission", "anon");
filterChainDefinitionMap.put("/**", "myAccessControlFilter");
shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
return shiroFilterFactoryBean;
}
5、参考链接
Shiro核心概述的更多相关文章
- Shiro 核心功能案例讲解 基于SpringBoot 有源码
Shiro 核心功能案例讲解 基于SpringBoot 有源码 从实战中学习Shiro的用法.本章使用SpringBoot快速搭建项目.整合SiteMesh框架布局页面.整合Shiro框架实现用身份认 ...
- Apache Shiro 核心概念
转自:http://blog.csdn.net/peterwanghao/article/details/8015571 Shiro框架中有三个核心概念:Subject ,SecurityManage ...
- Shiro——认证概述
认证流程 身份认证流程 首先调用 Subject.login(token) 进行登录,其会自动委托给SecurityManager SecurityManager 负责真正的身份验证逻辑:它会委托给A ...
- Javascript核心概述 - 深入了解javascript
/* 一.执行上下文:堆栈(底部全局上下文+顶部当前活动上下文) */ /* 二.变量对象: 变量根据执行上下文,找到数据存储位置,这种机制叫变量对象 1. 变量都要var定义,且都不能delete ...
- shiro 核心单词
subject [ˈsʌbdʒekt] 主体principal [ˈprɪnsəpəl] 身份信息credential ...
- 编程从入门到放弃(Java)
1.Java入门篇 1.1 基础入门和面向对象 1.1.1 编程基础 [01] Java语言的基本认识 [02] 类和对象 [03] 类的结构和创建对象 [04] 包和访问权限修饰符 [05] 利 ...
- springboot+shiro
作者:纯洁的微笑 出处:http://www.ityouknow.com/ 这篇文章我们来学习如何使用Spring Boot集成Apache Shiro.安全应该是互联网公司的一道生命线,几乎任何的公 ...
- spring boot(十四)shiro登录认证与权限管理
这篇文章我们来学习如何使用Spring Boot集成Apache Shiro.安全应该是互联网公司的一道生命线,几乎任何的公司都会涉及到这方面的需求.在Java领域一般有Spring Security ...
- Spring Cloud之路:(七)SpringBoot+Shiro实现登录认证和权限管理
版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/sage_wang/article/details/79592269一.Shiro介绍1.Shiro是 ...
随机推荐
- Human Motion Analysis with Wearable Inertial Sensors——阅读2
Human Motion Analysis with Wearable Inertial Sensors 实时人体运动跟踪已经应用于生物医学领域的许多应用:临床步态分析,运动康复,跌倒检测,关节生物力 ...
- mybatis 通过实体类进行查询
如果使用实体类进行查询, 不管会不会使用到 主键, 都必须设置主键, 才能查询 <select id="selectByAppidAndServerCode" resultM ...
- 微信小程序中如何获取for循环的item相关值到JS页面的问题
今天小程序开发过程中,遇到了这个棘手的问题.由于我没有前端基础,只是知道一点儿基本的HTML标签,所以卡了好久,特此分享,望后来的你,可以有所收获. measure step 1 *.WXML: ...
- 复杂的字符串数组解析:{"setting":"简单:10:5,一般:5:10,困难:2:20"},使用split多次截取
"[0,{"id":563,"name":"测试题1","dscr":null,"picId&quo ...
- GlusterFS 安装 on centos7
本文演示如何在CentOS7上安装,配置和使用GlusterFS. 1 准备工作 1.1 基础设施 编号 IP OS 主机名 角色 说明 A 192.168.1.101 CentOS7.4 ddc_n ...
- ALTER SYSTEM ARCHIVELOG CURRENT挂起案例
最近两天,一台ORACLE数据库的作业执行delete_ob_get_epps.sh脚本清理过期备份时,执行下面SQL语句就会被阻塞,在监控工具DPA里面部分截图如下(图片分开截断) sql 'alt ...
- linux下objdump应用
<a href="http://www.maomao365.com/?p=952" > linux命令objdump的用法 http://www.maomao365. ...
- Win10家庭版-添加[组策略]
win10家庭版有很多功能都不能用,这一次就碰到了一个找不到‘组策略’的问题,在网上搜索到了一个方法,记录一下: 新建一个txt,将下面内容复制到文本中: =====分隔符====== @echo o ...
- Vue使用枚举类型实现HTML下拉框
下拉框包含option中的Value和用来显示的选项, 一般后台都是使用的Value值,而不是显示在前台的选项 第一步: 编写下拉框需要的枚举类型 StatusEnum.java public enu ...
- C语言 设一个函数process,调用它时,实现不同功能。
//凯鲁嘎吉 - 博客园 http://www.cnblogs.com/kailugaji/ 输入a, b,第一次调用process找最大值,第二次调用process找最小值,第三次调用求和. 方法1 ...