Shiro安全框架简介
1.Shiro简介
Shiro是apache旗下一个开源安全框架(http://shiro.apache.org/),它将软件系统的安全认证相关的功能抽取出来,实现用户身份认证,权限授权、加密、会话管理等功能,组成了一个通用的安全认证框架。使用shiro就可以非常快速的完成认证、授权等功能的开发,降低系统成本。
用户在进行资源访问时,要求系统要对用户进行权限控制,其具体流程如下图所示:
2.Shiro概要架构
在概念层面,Shiro架构包含三个主要的理念,如下图所示:
说明:
Subject: 主体对象,负责提交用户认证和授权的信息;
SecurityManager: 安全管理体,负责认证,授权等业务实现;
Realm: 领域对象,负责从数据层获取业务数据;
3.Shiro详细架构
Shiro框架进行权限管理时,要涉及到的一些核心对象,主要包括:认证管理对象,授权管理对象,会话管理对象,缓存管理对象,加密管理对象以及Realm管理对象(领域对象:负责处理认证和授权领域的数据访问题)等
其中:
<1> ------Subject(主体):与软件交互的一个特定的实体(用户、第三方服务等)。
<2> ------SecurityManager(安全管理器) :Shiro的核心,用来协调管理组件工作。
<3> ------Authenticator(认证管理器):负责执行认证操作。
<4> ------Authorizer(授权管理器):负责授权检测。
<5> ------SessionManager(会话管理):负责创建并管理用户 Session生命周期,提供一个强有力的 Session 体验。
<6> ------SessionDAO:代表 SessionManager 执行 Session持久(CRUD)动作,它允许任何存储的数据挂接到 session 管理基础上。
<7> ------CacheManager(缓存管理器):主要对session和授权数据进行缓存,比如将授权数据通过cacheManager进行缓存管理,和ehcache整合对缓存数据进行管理。
<8> ------Cryptography(加密管理器):提供了加密方式的设计及管理。比如 md5散列算法
<9> ------Realms(领域对象):是shiro和你的应用程序安全数据之间的桥梁。相当于数据源,通过realm存取认证、授权相关数据。
Shiro框架认证拦截实现
1.Shiro基本环境配置
(1) 使用Shrio框架时,首先需要添加pom.xml依赖:
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>1.5.3</version>
</dependency>
(2)Shiro核心对象的配置:
由于在SpringBoot实现项目中,没有提供shiro的自动化配置,所以需要我们自己配置
第一步:创建SpringShiroConfig类。关键代码如下:
package com.cy.pj.common.config;
/**@Configuration 注解描述的类为一个配置对象,
* 此对象也会交给spring管理
*/
@Configuration
public class SpringShiroConfig {
}
第二步:在Shiro配置类中添加SecurityManager配置(这里一定要使用org.apache.shiro.mgt.SecurityManager这个接口对象),关键代码如下:
@Bean
public SecurityManager securityManager() {
DefaultWebSecurityManager sManager=
new DefaultWebSecurityManager();
return sManager;
}
第三步: 在Shiro配置类中添加ShiroFilterFactoryBean对象的配置。通过此对象设置资源匿名访问、认证访问。关键代码如下:
@Bean
public ShiroFilterFactoryBean shiroFilterFactory (
SecurityManager securityManager) {
ShiroFilterFactoryBean sfBean=
new ShiroFilterFactoryBean();
sfBean.setSecurityManager(securityManager);
//定义map指定请求过滤规则(哪些资源允许匿名访问,哪些必须认证访问)
LinkedHashMap<String,String> map= new LinkedHashMap<>();
//静态资源允许匿名访问:"anon"
map.put("/bower_components/**","anon");
map.put("/build/**","anon");
map.put("/dist/**","anon");
map.put("/plugins/**","anon");
//除了匿名访问的资源,其它都要认证("authc")后访问
map.put("/**","authc");
sfBean.setFilterChainDefinitionMap(map);
return sfBean;
}
再用一个图来了解这个过程:
认证过程
认证执行流程
1、通过ini配置文件创建securityManager
2、调用subject.login方法主体提交认证,提交的token
3、securityManager进行认证,securityManager最终由ModularRealmAuthenticator进行认证。
4、ModularRealmAuthenticator调用IniRealm(给realm传入token) 去ini配置文件中查询用户信息
5、IniRealm根据输入的token(UsernamePasswordToken)从 shiro.ini查询用户信息,根据账号查询用户信息(账号和密码)
如果查询到用户信息,就给ModularRealmAuthenticator返回用户信息(账号和密码)
如果查询不到,就给ModularRealmAuthenticator返回null
6、ModularRealmAuthenticator接收IniRealm返回Authentication认证信息
如果返回的认证信息是null,ModularRealmAuthenticator抛出异常(org.apache.shiro.authc.UnknownAccountException)
如果返回的认证信息不是null(说明inirealm找到了用户),对IniRealm返回用户密码 (在ini文件中存在)和 token中的密码 进行对比,
如果不一致抛出异常(org.apache.shiro.authc.IncorrectCredentialsException)
授权流程
1、对subject进行授权,调用方法isPermitted(“permission串”)
2、SecurityManager执行授权,通过ModularRealmAuthorizer执行授权
3、ModularRealmAuthorizer执行realm(自定义的Realm)从数据库查询权限数据调用realm的授权方法:doGetAuthorizationInfo
4、realm从数据库查询权限数据,返回ModularRealmAuthorizer
5、ModularRealmAuthorizer调用PermissionResolver进行权限串比对
6、如果比对后,isPermitted中"permission串"在realm查询到权限数据中,说明用户访问