一、权限管理的概念
1. 权限管理: 包括用户认证(登录) 和授权两部分,简称为认证授权。对需要访问控制的资源用户先经过身份认证,认证通过的用户才具有改志愿的访问权限。
2. 认证: 就是用户身份认证,判断一个用户是否为合法用户的处理过程。最常用的简单身份认证方式是系统通过核对用户输入的用户名和密码来对其进行判断认证。
抽取对象: Subject (用户主体:User) ; Principal (身份信息:username) ; Credential (凭证信息:password); (Token = Principal + Credential)
**3. 授权:**即控制访问,主体进行身份认证后需要分配权限方可访问系统资源,对于某些资源没有权利无法访问。
抽取对象: 简单理解: Who 对 What(Which)进行How操作; Who: 主体 (Subject),主体需要的资源; What :资源(Resource), 资源类型和资源实例;How:权限/许可 (Permission),规定主体资源的操作许可,权限离开资源没有意义。权限 分为 粗颗粒 (资源类型的权限 )和 细颗粒 ( 资源实例的权限 );
二、权限模型
1.模型分析: 将主体、资源、权限通过数据模型表示为:主体 《= 多对多 =》角色《= 多对多 =》权限 《= 1:1 =》资源
通常在开发中资源和权限为一张表:
三、权限控制
a.基于角色:
RBAC (Role-Based AccessControl) 是以角色为中心进行访问控制,通过角色的唯一标识判断该角色是否有访问的权限。访问控制粒度较粗,系统可扩展性差
b.基于资源:
RBAC (Resource-Based Access Control)是以资源为中心进行访问控制,通过判断角色是否有代表该资源权限的标识来控控制资源的访问权限。判断逻辑简单,系统可扩展性强;
四、Shiro
1、概念:
Shiro 是 Apache 旗下开源的安全认证框架,它将软件系统中安全认证相关的功能抽取出来,独立的实现用户的身份认证、权限授权、加密、回话管理等功能。Shiro可以运行在 Web 和非 Web 应用,集群分布式应用中越来越多用户使用Shiro。 (Spring security 也是开源的权限管理框架,但是依赖 Spring)
2、Shiro 架构:
3.3.1 Subject
Subject即主体,外部应用与subject进行交互,subject记录了当前操作用户,将用户的概念理解为当前操作的主体,可能是一个通过浏览器请求的用户,也可能是一个运行的程序。 Subject在shiro中是一个接口,接口中定义了很多认证授相关的方法,外部程序通过subject进行认证授,而subject是通过SecurityManager安全管理器进行认证授权
3.3.2 SecurityManager
SecurityManager即安全管理器,对全部的subject进行安全管理,它是shiro的核心,负责对所有的subject进行安全管理。通过SecurityManager可以完成subject的认证、授权等,实质上SecurityManager是通过Authenticator进行认证,通过Authorizer进行授权,通过SessionManager进行会话管理等。
SecurityManager是一个接口,继承了Authenticator, Authorizer, SessionManager这三个接口。
3.3.3 Authenticator
Authenticator即认证器,对用户身份进行认证,Authenticator是一个接口,shiro提供ModularRealmAuthenticator实现类,通过ModularRealmAuthenticator基本上可以满足大多数需求,也可以自定义认证器。
3.3.4 Authorizer
Authorizer即授权器,用户通过认证器认证通过,在访问功能时需要通过授权器判断用户是否有此功能的操作权限。
3.3.5 realm
Realm即领域,相当于datasource数据源,securityManager进行安全认证需要通过Realm获取用户权限数据,比如:如果用户身份数据在数据库那么realm就需要从数据库获取用户身份信息。
注意:不要把realm理解成只是从数据源取数据,在realm中还有认证授权校验的相关的代码。
3.3.6 sessionManager
sessionManager即会话管理,shiro框架定义了一套会话管理,它不依赖web容器的session,所以shiro可以使用在非web应用上,也可以将分布式应用的会话集中在一点管理,此特性可使它实现单点登录。
3.3.7 SessionDAO
SessionDAO即会话dao,是对session会话操作的一套接口,比如要将session存储到数据库,可以通过jdbc将会话存储到数据库。
3.3.8 CacheManager
CacheManager即缓存管理,将用户权限数据存储在缓存,这样可以提高性能。
3.3.9 Cryptography
Cryptography即密码管理,shiro提供了一套加密/解密的组件,方便开发。比如提供常用的散列、加/解密等功能。shiro实战
五、Shiro 使用
// 依赖
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring-boot-starter</artifactId>
<version>1.4.2</version>
</dependency>
//代码
@Test
public void contextLoads() {
//IniRealm 从配置文件读取数据
Realm realm = new IniRealm("classpath:shiro.ini");
//1. 获得 securityManagger
SecurityManager securityManager = new DefaultSecurityManager(realm);
//桥梁
SecurityUtils.setSecurityManager(securityManager);
//2. 获得主体
Subject subject = SecurityUtils.getSubject();
AuthenticationToken token = new UsernamePasswordToken("lisi","000000");
//3. 认证\
// 先判断 账号 然后在判断密码
try {
subject.login(token);
} catch (UnknownAccountException e) {
System.out.println("账号有误");
} catch (IncorrectCredentialsException e){
System.out.println("密码有误");
}finally {
// 是否会被认证 true: 被认证 false:未认证
boolean authenticated = subject.isAuthenticated();
System.out.println(authenticated);
}
/*
* UnknownAccountException 账号有误
* IncorrectCredentialsException 密码有误
* */
}
//源码发现
AuthenticatingRealm CredentialsMatcher 凭证匹配器 默认的实现SimpleCredentialsMatcher
//读取数据
protected abstract AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken var1) throws AuthenticationException;
SimpleAccountRealm
//从配置文件中读取数据
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
UsernamePasswordToken upToken = (UsernamePasswordToken)token;
// zhangsan
SimpleAccount account = this.getUser(upToken.getUsername());
if (account <