权限管理框架Shiro源码浅析

权限管理框架Shiro源码浅析

一. Shiro概述

1.1 shiro是什么

Apache Shiro™ is a powerful and easy-to-use Java security framework that performs authentication, authorization, cryptography, and session management. With Shiro’s easy-to-understand API, you can quickly and easily secure any application – from the smallest mobile applications to the largest web and enterprise applications.

  • shiro是一个强大并且容易使用的执行认证、授权、加密、session管理的Java安全框架。
  • 使用shiro的API,你可以快速容易的保护你的任何应用(从最小的移动应用到最大的web企业级应用)。

二. Authentication认证

2.1 executeLogin

  • AuthenticatingFilter中的executeLogin方法
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
  • 调用createToken方法创建一个token令牌,大致步骤:
    • 通过request获取用户名密码
    • 通过isRememberMe和getHost方法分别获得是否记住我(布尔值true/false)和主机
    • 最后通过以上四个参数,创建UsernamePasswordToken对象。
  • 判断令牌Token是否为null,如果为空,抛出异常。
  • 通过getSubject方法获得主体subject(用户或第三方应用)。
    • 实际是通过SecurityUtils类中的getSubject方法来获取主体的。
  • 调用subject对象中的login方法。
  • 认证成功,调用onLoginSuccess方法。
    • 重定位到登录成功页面
  • 认证失败,调用onLoginFailure方法。
    • 返回登录页面

2.2 login

  • DelegatingSubject.login
    在这里插入图片描述
    • 拿到DefaultSecurityManager的login方法返回值subject(登录成功后新创建的主体)
    • 如果subject是DelegatingSubject类型那么就将其造型为DelegatingSubject,并取出principals用户名和host主机分别赋值给principals和host,否则就直接从subject中取出principals赋值给principals。
    • 将authenticated赋值为true,认证成功。
    • 拿到subject中的session
  • DefaultSecurityManager.login
    在这里插入图片描述
    • 通过调用authenticate方法及之后的许多方法得到认证信息info(doAuthenticate)
    • 创建新的subject

2.3 doAuthenticate

  • ModularRealmAuthenticator中的doAuthenticate
    在这里插入图片描述
    • 首先判断是否配置了realm,没有配置抛异常
    • 获取所有的realm
    • 如果realm只有一个那么调用doSingleRealmAuthentication方法,否则调用doMultiRealmAuthentication

2.4 doSingleRealmAuthentication

  • ModularRealmAuthenticator中的doSingleRealmAuthentication方法
    在这里插入图片描述
    • 判断该realm是否支持UsernamePasswordToken,如果不支持抛异常
    • 调用getAuthenticationInfo方法获得认证信息info
    • 如果认证信息info为null,就抛出未知账户异常UnknownAccountException,否则返回info

2.5 getAuthenticationInfo

  • AuthenticatingRealm中的getAuthenticationInfo
    在这里插入图片描述
    • getAuthenticationInfo方法中最重要的是调用我们自定义的Realm对象,比如CustomeRealm,返回info
      在这里插入图片描述
      • 从token中取出用户名
      • 通过用户名从数据库中查出对应的用户信息
      • 从用户信息中取出密码,根据密码、用户名、类名创建SimpleAuthenticationInfo认证信息,并返回到getAuthenticationInfo方法中。
    • 之后匹配密码是否符合,调用assertCredentialsMatch方法
      在这里插入图片描述
      • 通过getCredentialsMatcher方法获得凭证匹配器
      • 凭证匹配器调用doCredentialsMatch方法,判断密码是否一致 在这里插入图片描述
        • 从令牌token和info各自取出密码
        • 通过equals方法来判断密码是否一致,一致返回true,反之,返回false
        • doCredentialsMatch方法返回false,那么就抛出错误凭证异常IncorrectCredentialsException
        • 返回到getAuthenticationInfo中,将info返回

三. Authorization授权

3.1 checkPermission

  • AuthorizingSecurityManager中的checkPermission方法
    在这里插入图片描述
    • 直接调用ModularRealmAuthorizer中的checkPermission方法
    • ModularRealmAuthorizer中的checkPermission方法
      在这里插入图片描述
    • 首先判断是否配置了realm,没有配置抛异常
    • 执行ModularRealmAuthorizer中的isPermitted方法,如果返回false,那么就抛未认证异常UnauthorizedException

3.2 isPermitted

  • ModularRealmAuthorizer中的isPermitted方法
    在这里插入图片描述
    • 首先判断是否配置了realm,没有配置抛异常
    • 判断realm是否实现了Authorizer接口,如果没有继续下一次循环去取出下一个realm
    • 调用AuthorizingRealm中的isPermitted方法
    • AuthorizingRealm中的isPermitted方法 在这里插入图片描述
      • 将字符串permission转换为Permission对象p
      • 然后继续调用该类中isPermitted方法 在这里插入图片描述
        • 调用getAuthorizationInfo方法获得授权信息
        • 继续调用该类中isPermitted方法 在这里插入图片描述
          • 调用getPermissions的到该用户的所有权限
          • 将该用户的所有权限依次取出调用implies方法,跟访问模块所需的permission权限进行比较,如果包含该权限则返回true,否则进行下一次的循环,直到用户拥有的所有权限全部比较完毕,如果依然没有匹配的,那么就返回false,说明该用户并没有访问该模块的权限。

3.3 getAuthorizationInfo

  • getAuthorizationInfo方法中的一部分代码
    在这里插入图片描述
    • 通过doGetAuthorizationInfo方法获得授权信息info。
    • 然后将info返回。

3.4 doGetAuthorizationInfo

  • CustomRealm中的doGetAuthorizationInfo方法 在这里插入图片描述
    • 获取用户名
    • 根据用户名查询出该用户所有的权限。
    • 将每个权限对象中的权限码取出放入权限码集合中。
    • 创建简单授权信息对象,并且将权限码集合设置进去。
    • 将授权信息返回。

3.4 getPermissions

  • AuthorizingRealm中的getPermissions方法
    在这里插入图片描述
    • 判断授权信息是否为空
    • 调用resolvePermissions方法,将info中的字符串权限集合转换为对象权限集合,并返回

3.5 resolvePermissions

  • AuthorizingRealm中的resolvePermissions方法
    在这里插入图片描述
    • 创建一个空的集合
    • 获取权限解析器
    • 依次取出stringPermission(privilegeCode),调用resolvePermission方法返回WidcardPermission权限对象,最后放入集合中。
    • 将集合返回。

3.6 resolvePermission

  • WildcardPermissionResolver中的resolvePermission方法
    在这里插入图片描述
    • 该方法直接创建了一个WidcardPermission权限对象,并返回。

3.7 implies

  • WildcardPermission中的implies方法
    在这里插入图片描述
    • otherParts是访问该模块所需要的权限,part是用户目前拥有的一种权限
    • 该方法举例子最容易明白
      • 假设otherParts集合中的数据是user、list,part集合中的数据是user、modify
      • 第一次进行比较,user==user返回true,取反,进行下一次循环
      • 第二次比较,list != modify返回false,取反,返回false,结束方法。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值