zoukankan      html  css  js  c++  java
  • Shiro授权认证原理和流程

    先来张图:

    这是一张shiro的功能图:

    • Authentication: 身份认证/登录,验证用户是否拥有相应的身份
    • Authorization: 授权/权限验证,验证某个已认证的用户是否拥有某个权限,包括验证用户是否拥有某个角色,或拥有某个操作权限
    • Session Management: 会话管理,shiro拥有自己的session(不需要web环境下就能使用)
    • Cryptography: 加密
    • Web Support: web支持,针对web应用提供一些功能
    • Caching: 缓存
    • Concurrency: shiro支持多线程应用的并发验证,即在一个线程中开启另一个线程,能把权限自动传播过去
    • Testing: 测试支持
    • Run As: 允许一个用户假装成为另一个用户(如果允许)的省份进行访问
    • Remember Me: 记住用户身份

    再来一张图:

    • Subject: 与应用交互的用户,Subject在shiro中是一个接口,定义了很多认证授权的方法,外部程序通过Subject进行认证授权,而Subject通过SecurityManager进行认证授权
      注意: Subject只是一个门面,SecurityManager才是实际的执行者
    • SecurityManager: 安全管理器,所有与安全有关的操作都会与SecurityManager交互,且管理着所有的Subject,是shiro的核心,负责与shiro其他组件进行交互,如通过Authenticator进行认证通过Authorizer进行授权通过SessionManager进行会话管理
      补充: SecurityManager是一个接口,继承了Authenticator,Authorizer,SessionManager三个接口
    • Realm: Shiro从Realm获取安全数据(如用户,角色,权限);也就是说SecurityManager要验证用户身份或操作权限,需要从Realm获取相应数据来判断(用户是否能登录,是否拥有什么权限等)
      注意: realm也是由SecurityManager控制

    再来一张图:

    • Subject: 与应用交互的用户
    • SecurityManager: 相当于SpringMVC中的DispatcherServlet,所有具体的交互都由SecurityManager控制;它管理着所有的Subject,且负责进行认证,授权,会话和缓存的管理
    • Authenticator: 认证器, 对用户身份进行验证;Authenticator是一个接口,shiro提供ModularRealmAuthenticator实现类,也可以自定义
    • Authorizer: 授权器,决定用户是否有权限进行某种操作,控制着用户能访问应用中的哪些功能
    • Realm: 安全实体数据源,可以有1个或多个
    • SessionManager: 管理session的生命周期(可以实现单点登录
    • CacheManager: 缓存管理器
    • Cryptography: 密码管理模块

    认证流程

    1. 创建token令牌,token中有用户提交的认证信息即帐号和密码
    2. 执行Subject.login(token),Subject实例通常是DelegatingSubject类(或子类)的实例对象;在认证开始时,通过SecurityManager实例来调用securityManager.login(token)方法
    3. SecurityManager接受到token(令牌)信息后委托Authenticator实例进行认证Authenticator通过实现类ModularRealmAuthenticator来调用anthenticator.authenticate(token)方法ModularRealmAuthenticator在认证过程中会对一个或多个Realm实例进行适配(可插拔)
    4. 如果配置了多个Realm,ModularRealmAuthenticator会根据配置的AuthenticationStrategy(认证策略)来进行多Realm的认证过程;在Realm被调用后,AuthenticationStrategy将对每一个Realm的结果做出响应
      注意: 如果只有一个Realm,Realm将直接调用而无需再配置认证策略
    5. 判断每一个Realm是否都支持提交的token,如果支持,Realm调用getAuthenticationInfo(token),该方法就是实际的认证处理,我们通过覆盖Realm的doGetAuthenticationInfo方法来编写我们自定义的认证处理
    6. shiro中有三种认证策略的具体实现:
      • AtleastOneSuccessfulStrategy: 只要有一个realm验证成功,则成功
      • FirstSuccessfulStrategy: 第一个realm验证成功,则成功,后续realm将被忽略
      • AllSuccessfulStrategy: 所有realm成功,验证才成功

    补充: 认证失败后抛出的一些异常:

    • UnknownAccountException  帐号不存在
    • IncorrectCredentialsException  密码错误
    • DisabledAccountException   帐号被禁用
    • LockedAccountException  帐号被锁定
    • ExcessiveAttemptsException  登录失败次数过多
    • ExpiredCredentialsException  凭证过期

    自定义Realm

    shiro自带的Realm接口,CachingRealm负责缓存处理AuthenticationRealm负责认证AuthorizingRealm负责授权等,但是通常情况下,正确的用户信息都是从数据库中取出,所以需要自定义realm,通常自定义的realm继承AuthorizingRealm,认证是重写doGetAuthenticationInfo(AuthenticationToken token)方法,授权是重写doGetAuthorizationInfo(PrincipalCollection principals)方法

    授权流程

    1. 调用授权验证方法Subject.isPermitted()Subject.hasRole()等)
    2. Subject实例通常是DelegatingSubject类(或子类)的实例对象;在认证开始时,通过SecurityManager实例来调用securityManager.isPermitted(string)方法/security.hasRole(string)方法
    3. SecurityManager委托Authorizer的实例(默认是ModularRealmAuthorizer类的实例,同样支持多个realm)调用相应的授权方法
    4. 每一个Realm将检查是否实现了相同的Authorizer接口,然后调用Realm自己的相应的授权验证方法
    5. 使用多个Realm时,不同于认证策略处理方式,授权处理过程中:
      • 当调用Realm出现异常时,立即抛出,结束授权验证
      • 只要一个Realm验证成功,则认为授权成功,立即返回,结束验证
  • 相关阅读:
    [Javascript] property function && Enumeration
    [Javascript]3. Improve you speed! Performance Tips
    [Ember] Wraming up
    [Javascript] How to write a Javascript libarary
    [Regex Expression] Tagline --- {0, } {1,10}
    [Regex Expression] Confirmative -- World bundry
    [Regex Expression] Match mutli-line number, number range
    成都-地点-文创-锦里:锦里
    成都-地点-文创-宽窄巷子:宽窄巷子
    地点-文创-田子坊-上海:田子坊
  • 原文地址:https://www.cnblogs.com/yushangzuiyue/p/8379286.html
Copyright © 2011-2022 走看看