shiro(一):shiro基本概念及基本使用(认证、授权)
1. 权限的管理
1.1 什么是权限管理
基本上涉及到用户参与的系统都要进行权限管理,权限管理属于系统安全的范畴,权限管理实现对用户访问系统的控制
,按照安全规则或者安全策略控制用户可以访问而且只能访问自己被授权的资源。
权限管理包括用户身份认证
和授权
两部分,简称认证授权。对于需要访问控制的资源用户首先经过身份认证,认证通过后用户具有该资源的访问权限方可访问。
1.2 什么是身份认证
身份认证,就是判断一个用户是否为合法用户的处理过程。最常用的简单身份认证方式是系统通过核对用户输入的用户名和口令,看其是否与系统中存储的该用户的用户名和口令一致,来判断用户身份是否正确。对于采用指纹等系统,则出示指纹;对于硬件Key等刷卡系统,则需要刷卡。
1.3 什么是授权
授权,即访问控制,控制谁能访问哪些资源。主体进行身份认证后需要分配权限方可访问系统的资源,对于某些资源没有权限是无法访问的
2. 什么是shiro
Shiro是apache旗下一个开源框架,它将软件系统的安全认证相关的功能抽取出来,实现用户身份认证,权限授权、加密、会话管理等功能,组成了一个通用的安全认证框架。
3. shiro的核心架构
3.1 Subject:主体
外部应用与subject进行交互,subject记录了当前操作用户,将用户的概念理解为当前操作的主体,可能是一个通过浏览器请求的用户,也可能是一个运行的程序。
Subject在shiro中是一个接口,接口中定义了很多认证授相关的方法,外部程序通过subject进行认证授,而subject是通过SecurityManager安全管理器进行认证授权
3.2 SecurityManager:安全管理器
对全部的subject进行安全管理,它是shiro的核心,负责对所有的subject进行安全管理。通过SecurityManager可以完成subject的认证、授权等,实质上SecurityManager是通过Authenticator进行认证,通过Authorizer进行授权,通过SessionManager进行会话管理等。
SecurityManager是一个接口,继承了Authenticator, Authorizer, SessionManager这三个接口。
3.3 Authenticator:认证器
对用户身份进行认证,Authenticator是一个接口,shiro提供ModularRealmAuthenticator实现类,通过ModularRealmAuthenticator基本上可以满足大多数需求,也可以自定义认证器。
3.4 Authorizer:授权器
用户通过认证器认证通过,在访问功能时需要通过授权器判断用户是否有此功能的操作权限。
3.5 Realm:领域
相当于datasource数据源,securityManager进行安全认证需要通过Realm获取用户权限数据,比如:如果用户身份数据在数据库那么realm就需要从数据库获取用户身份信息。
注意:不要把realm理解成只是从数据源取数据,在realm中还有认证授权校验的相关的代码。
3.6 SessionManager:会话管理
shiro框架定义了一套会话管理,它不依赖web容器的session,所以shiro可以使用在非web应用上,也可以将分布式应用的会话集中在一点管理,此特性可使它实现单点登录。
3.7 SessionDAO:会话dao
是对session会话操作的一套接口,比如要将session存储到数据库,可以通过jdbc将会话存储到数据库。
3.8 CacheManager:缓存管理
将用户权限数据存储在缓存,这样可以提高性能。
3.9 Cryptography:密码管理
shiro提供了一套加密/解密的组件,方便开发。比如提供常用的散列、加/解密等功能。
4. shiro中的认证
4.1 认证
身份认证,就是判断一个用户是否为合法用户的处理过程。最常用的简单身份认证方式是系统通过核对用户输入的用户名和口令,看其是否与系统中存储的该用户的用户名和口令一致,来判断用户身份是否正确。
4.2 shiro中认证的关键对象
4.2.1 Subject:主体
访问系统的用户,主体可以是用户、程序等,进行认证的都称为主体;
4.2.2 Principal:身份信息
是主体(subject)进行身份认证的标识,标识必须具有唯一性,如用户名、手机号、邮箱地址等,一个主体可以有多个身份,但是必须有一个主身份(Primary Principal)。
4.2.2 credential:凭证信息
是只有主体自己知道的安全信息,如密码、证书等。
4.3 认证流程
- shiro将用户名(身份信息)和密码(凭证信息)打包成一个token(令牌)
- 然后通过token去通过shiro核心架构中的安全管理器进行认证
- 安全管理器调用认证器,认证器调用任务去获取数据
- 如果获取到的数据与系统存储(数据库等)的一致,则认证通过,否则认证失败
4.4 认证的简单开发
4.4.1 引入依赖
<dependency><groupId>org.apache.shiro</groupId><artifactId>shiro-core</artifactId><version>1.5.3</version>
</dependency>
4.4.2 引入shiro配置文件
配置文件:名称随意,以 .ini 结尾,放在 resources 目录下;后续用了springboot就不需要此配置文件了,是前期方便我们学习shiro书写我们系统中相关权限数据
注意:在实际的项目开发中并不会使用这种方式,这种方法可以用来初学时练手
[users]
zhangsan=123456
lisi=456789
4.4.3 开发认证代码
public class test01 {public static void main(String[] args) {//1.创建安全管理器对象DefaultSecurityManager securityManager = new DefaultSecurityManager();//2.给安全管理器设置realmsecurityManager.setRealm(new IniRealm("classpath:shiro.ini"));//3.SecurityUtils给全局安全工具类设置安全管理器SecurityUtils.setSecurityManager(securityManager);//4.关键对象subject主体Subject subject = SecurityUtils.getSubject();//5.创建令牌UsernamePasswordToken token = new UsernamePasswordToken("zhangsan","123456");try {System.out.println("认证状态"+subject.isAuthenticated());//fasle//用户认证subject.login(token);System.out.println("认证状态"+subject.isAuthenticated());}catch (UnknownAccountException e){e.printStackTrace();System.out.println("认证失败,用户名不存在");}catch (IncorrectCredentialsException e){e.printStackTrace();System.out.println("认证失败,密码错误");}}
}
4.4.4 .常见的异常类型
- DisabledAccountException(帐号被禁用)
- LockedAccountException(帐号被锁定)
- ExcessiveAttemptsException(登录失败次数过多)
- ExpiredCredentialsException(凭证过期)等
4.4.5 认证过程源码解析
可见:shiro相关源码解析
4.5 自定义Realm
通过分析源码可得:
- 认证:
- 最终执行用户名比较是 在SimpleAccountRealm类 的 doGetAuthenticationInfo 方法中完成用户名校验
- 最终密码校验是在 AuthenticatingRealm类 的 assertCredentialsMatch方法 中
- 总结:
- AuthenticatingRealm 认证realm doGetAuthenticationInfo
- AuthorizingRealm 授权realm doGetAuthorizationInfo
自定义Realm的作用:放弃使用.ini文件,使用数据库查询
上边的程序使用的是Shiro自带的IniRealm,IniRealm从ini配置文件中读取用户的信息,大部分情况下需要从系统的数据库中读取用户信息,所以需要自定义realm。