Shiro简介及认证授权过程

时间:2022-07-12 14:27:55
1、是什么?
Apache Shiro 是一个强大而灵活的开源安全框架,它干净利落地处理身份认证,授权,企业会话管理和加密

2、能干嘛?
1)验证用户来核实他们的身份
2)对用户执行访问控制,如:
     判断用户是否被分配了一个确定的安全角色
     判断用户和是否被允许做某事
3)在任何环境下使用session API,即使没有web或ejb容器
4)在身份验证,访问控制期间或在会话的生命周期,对事件作出反应
5)聚集一个或多个用户安全数据的数据源,并作为一个单一的复合用户“视图”
6)启用单点登录(SSO)功能
7)为没有关联到登录的用户启用"Remember Me"服务

3、什么是权限管理?
权限管理是系统的安全范畴,要求必须是合法的用户才可以访问系统(用户认证),且必须具有该 资源的访问权限才可以访问该 资源(授权)

认证:对用户合法身份的校验,要求必须是合法的用户才可以访问系统。

授权:访问控制,必须具有该 资源的访问权限才可以访问该 资源。

权限模型:标准权限数据模型包括 :用户、角色、权限(包括资源和权限)、用户角色关系、角色权限关系。

权限分配:通过UI界面方便给用户分配权限,对上边权限模型进行增、删、改、查操作。

权限控制:
       基于角色的权限控制:根据角色判断是否有操作权限,因为角色的变化 性较高,如果角色修改需要修改控制代码,系统可扩展性不强。

       基于资源的权限控制:根据资源权限判断是否有操作权限,因为资源较为固定,如果角色修改或角色中权限修改不需要修改控制代码,使用此方法系统可维护性很强。建议使用。

权限管理的解决方案:

    对于粗颗粒权限管理:建议在系统架构层面去解决,写系统架构级别统一代码(基础代码)。
    粗颗粒权限:比如对系统的url、菜单、jsp页面、页面上按钮、类方法进行权限管理,即对资源类型进行权限管理
    对于细颗粒权限管理:
    细颗粒权限:比如用户id为001的用户信息(资源实例)、类型为01的商品信息(资源实例),对资源实例进行权限管理,理解对数据级别的权限管理。
    细颗粒权限管理是系统的业务逻辑,业务逻辑代码不方便抽取统一代码,建议在系统业务层进行处理。

4、shiro相关概念简介:

Subject:
    Subject即主体,外部应用与subject进行交互,subject记录了当前操作用户,将用户的概念理解为当前操作的主体,可能是一个通过览器请求的用户,也可能是一个运行的程序。    
    Subject在shiro中是一个接口,接口中定义了很多认证授权相关的方法,外部程序通过subject进行认证授,而subject是通过SecurityManager安全管理器进行认证授权
        
SecurityManager:
     SecurityManager即安全管理器,对全部的subject进行安全管理,它是shiro的核心,负责对所有的subject进行安全管理。通过SecurityManager可以完成subject的认证、授权等,实质上SecurityManager是通过Authenticator进行认证,通过Authorizer进行授权,通过SessionManager
进行会话管理等。
     SecurityManager是一个接口,继承了Authenticator, Authorizer, SessionManager这三个接口。

Authenticator:
     Authenticator即认证器,对用户身份进行认证,Authenticator是一个接口,shiro提供ModularRealmAuthenticator实现类,通过ModularRealmAuthenticator基本上可以满足大多数需求,也可以自定义认证器。

Authorizer:
     Authorizer即授权器,用户通过认证器认证通过,在访问功能时需要通过授权器判断用户是否有此功能的操作权限。

realm:
Realm即领域,相当于datasource数据源,securityManager进行安全认证需要通过Realm获取用户权限数据,比如:如果用户身份数据在数据库那么realm就需要从数据库获取用户身份信息。
     注意:不要把realm理解成只是从数据源取数据,在realm中还有认证授权校验的相关的代码。

sessionManager:
sessionManager即会话管理,shiro框架定义了一套会话管理,它不依赖web容器的session,所以shiro可以使用在非web应用上,也可以将分布式应用的会话集中在一点管理,此特性可使它实现单点登录。

SessionDAO:
SessionDAO即会话dao,是对session会话操作的一套接口,比如要将session存储到数据库,可以通过jdbc将会话存储到数据库。

CacheManager:
CacheManager即缓存管理,将用户权限数据存储在缓存,这样可以提高性能。

Cryptography:
Cryptography即密码管理,shiro提供了一套加密/解密的组件,方便开发。比如提供常用的散列、加/解密等功能。

5、shiro认证执行流程

1)subject(主体)请求认证,调用subject.login(token),token中包含了用户登录的账号和密码。由securityManager通过Authenticator(接口)进行认证

2)Authenticator最终由实现类ModularRealmAuthenticator调用Realm(同时向Realm传入了包含用户信息的token)数据库中获取用户真实的账号和密码。这里的Realm为自定义的。

3)Realm先根据token中的账号去数据库中查找该用户信息(包括账号和密码):
如果找不到则给ModularRealmAuthenticator返回null
如果找到则给ModularRealmAuthenticator返回用户信息(包括账号和密码)

4)ModularRealmAuthenticator接收Realm返回的Anthentication认证信息:
如果返回的信息为null,ModularRealmAuthenticator则抛出异常(UnknownAccountException--账号不存在)

如果返回的信息不为null,说明用户是存在的。ModularRealmAuthenticator再对Realm返回的用户密码(根据返回的用户得到该用户密码)与token中的密码进行对比。如果密码一致则认证通过;如果密码不一致则抛出异常(IncorrectCredentialsException--密码错误)

UnknownAccountException
账号不存在异常如下:(Realm干的活)
org.apache.shiro.authc.UnknownAccountException: No account found for user。。。。

IncorrectCredentialsException
当输入密码错误(账号存在)会抛此异常,如下:(ModularRealmAuthenticator干的活)
org.apache.shiro.authc.IncorrectCredentialsException: Submitted credentials for token [org.apache.shiro.authc.UsernamePasswordToken - zhangsan, rememberMe=false] did not match the expected credentials.

更多如下:
DisabledAccountException(帐号被禁用)
LockedAccountException(帐号被锁定)
ExcessiveAttemptsException(登录失败次数过多)
ExpiredCredentialsException(凭证过期)等

6、shiro授权的执行流程

1)对subject进行授权,调用方法isPermitted("permission串")

2)SecurityManager执行授权,最终通过ModularRealmAuthorizer执行授权

3)ModularRealmAuthorizer执行Realm(自定义的Realm)从数据库查询权限数据调用realm的授权方法:doGetAuthorizationInfo

4)Realm从数据库查询权限数据,返回ModularRealmAuthorizer授权信息

5)ModularRealmAuthorizer调用PermissionResolver进行权限串比对

6、如果比对后,isPermitted中"permission串"在realm从数据库中查询到权限数据中,说明用户访问permission串有权限,否则 没有权限,抛出异常。