SpringBoot 整合 Shiro 权限框架
创始人
2024-02-09 12:25:49
0

目录

  • Shiro概述
    • Shiro介绍
    • 基本功能
    • Shiro架构
  • SpringBoot整合Shiro
    • 环境搭建
    • 登录、授权、角色认证实现
      • 自定义实现 Realm
      • Shiro配置类
      • controller代码
      • 权限异常处理
    • 多个 realm 的认证策略设置
    • 会话管理
      • 获得session方式

Shiro概述

Shiro介绍

Apache Shiro 是一个功能强大且易于使用的 Java 安全(权限)框架。Shiro 可以完成:认证授权加密会话管理与 Web 集成缓存 等。借助 Shiro 您可以快速轻松地保护任何应用程序——从最小的移动应用程序到最大的 Web 和企业应用程序。
在这里插入图片描述

官方网址: https://shiro.apache.org/

基本功能

在这里插入图片描述

  • Authentication:身份认证/登录,验证用户是不是拥有相应的身份;
  • Authorization:授权,即权限验证,验证某个已认证的用户是否拥有某个权限;
  • Session Manager:会话管理,即用户登录后就是一次会话,在没有退出之前,它的所有 信息都在会话中;会话可以是普通 JavaSE 环境,也可以是 Web 环境的;
  • Cryptography:加密,保护数据的安全性,如密码加密存储到数据库,而不是明文存储;
  • Web Support:Web 支持,可以非常容易的集成到 Web 环境;
  • Caching:缓存,比如用户登录后,其用户信息、拥有的角色/权限不必每次去查,这样可 以提高效率;
  • Concurrency:Shiro 支持多线程应用的并发验证,即如在一个线程中开启另一个线程,能把权限自动传播过去;、
  • Testing:提供测试支持;
  • Run As:允许一个用户假装为另一个用户(如果他们允许)的身份进行访问;
  • Remember Me:记住我,这个是非常常见的功能,即一次登录后,下次再来的话不用登录了

Shiro架构

在这里插入图片描述

  • Subject:任何可以与应用交互的“用户”;
  • SecurityManager :相当于 SpringMVC 中的 DispatcherServlet;是 Shiro 的心脏; 所有具体的交互都通过 SecurityManager 进行控制;它管理着所有 Subject、且负责进 行认证、授权、会话及缓存的管理。
  • Authenticator:负责 Subject 认证,是一个扩展点,可以自定义实现;可以使用认证 策略(Authentication Strategy),即什么情况下算用户认证通过了;
  • Authorizer:授权器、即访问控制器,用来决定主体是否有权限进行相应的操作;即控 制着用户能访问应用中的哪些功能;
  • Realm:可以有 1 个或多个 Realm,可以认为是安全实体数据源,即用于获取安全实体 的;可以是 JDBC 实现,也可以是内存实现等等;由用户提供;所以一般在应用中都需要 实现自己的 Realm;
  • SessionManager:管理 Session 生命周期的组件;而 Shiro 并不仅仅可以用在 Web 环境,也可以用在如普通的 JavaSE 环境
  • CacheManager:缓存控制器,来管理如用户、角色、权限等的缓存的;因为这些数据基本上很少改变,放到缓存中后可以提高访问的性能
  • Cryptography:密码模块,Shiro 提高了一些常见的加密组件用于如密码加密/解密。

SpringBoot整合Shiro

环境搭建

引入依赖

org.apache.shiroshiro-spring-boot-web-starter1.9.0

指定登录路径

shiro:loginUrl: /user/login

创建数据库
user表
在这里插入图片描述
role表
在这里插入图片描述
user_role表
在这里插入图片描述
permissions表
在这里插入图片描述
role_permissions表
在这里插入图片描述

登录、授权、角色认证实现

省略Mybatis查询数据库代码

自定义实现 Realm

@Component("authorizer")
public class MyRealm extends AuthorizingRealm {@Autowiredprivate UserService userService;/*** 自定义授权方法* @param principalCollection* @return*/@Overrideprotected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {//1 创建对象,存储当前登录的用户的权限和角色SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();//2 获取当前用户身份信息String name = principalCollection.getPrimaryPrincipal().toString();List roles = userService.getUserRoles(name);//3 存储角色info.addRoles(roles);//4 获取用户角色的权限信息List permissions=new ArrayList<>();for (String role : roles) {List ps = userService.getUserPermission(role);permissions.addAll(permissions);}//5 存储权限信息info.addStringPermissions(permissions);//6 返回return info;}/*** 自定义登录方法* @param authenticationToken* @return* @throws AuthenticationException*/@Overrideprotected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {//获取用户身份信息String name = authenticationToken.getPrincipal().toString();//查询用户信息User user = userService.getUserByName(name);if (user!=null){AuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(name,//用户名user.getPwd(),//密码ByteSource.Util.bytes("salt"),//加盐字符getName()//realm名称);return authenticationInfo;}return null;}}

Shiro配置类

@Configuration
public class ShiroConfig {//配置自定义Realm@Beanpublic MyRealm myRealm(){return new MyRealm();}//配置 SecurityManager@Beanpublic DefaultWebSecurityManager defaultWebSecurityManager(){//1 创建 defaultWebSecurityManager 对象DefaultWebSecurityManager manager = new DefaultWebSecurityManager();//2 创建加密对象,并设置相关属性HashedCredentialsMatcher matcher = new HashedCredentialsMatcher();//2.1 采用 md5 加密matcher.setHashAlgorithmName("md5");//2.2 迭代加密次数matcher.setHashIterations(3);//3 将加密对象存储到 myRealm 中myRealm().setCredentialsMatcher(matcher);//4 将 myRealm 存入 defaultWebSecurityManager 对象manager.setRealm(myRealm());//5 返回 defaultWebSecurityManager 对象return manager;}//配置 Shiro 内置过滤器拦截范围@Beanpublic DefaultShiroFilterChainDefinition shiroFilterChainDefinition(){DefaultShiroFilterChainDefinition definition = new DefaultShiroFilterChainDefinition();//设置不认证可以访问的资源definition.addPathDefinition("/user/login","anon");//配置退出过滤器definition.addPathDefinition("/logout","logout");//设置需要进行登录认证的拦截范围definition.addPathDefinition("/**","authc");return definition;}
}

controller代码

@RestController
@RequestMapping("/user")
@ResponseBody
public class UserController {@PostMapping(path = "/login",produces = "application/json")public String login(@RequestBody User user){try {//1 获取 Subject 对象Subject subject = SecurityUtils.getSubject();//2 封装请求数据到 token 对象中UsernamePasswordToken token = new UsernamePasswordToken(user.getName(),user.getPwd());subject.login(token);return "登录成功!";}catch (LockedAccountException e){return "账号封禁";}catch (UnknownAccountException e) {e.printStackTrace();return  "用户不存在";}catch (IncorrectCredentialsException e) {e.printStackTrace();return  "密码错误";}catch (AuthenticationException e) {e.printStackTrace();return "登录失败!";}}//登录认证验证角色@RequiresRoles("admin")@GetMapping("/roles")public String userLoginRoles() {return "验证角色成功";}//登录认证验证权限@RequiresPermissions("user:delete")@GetMapping("/permissions")public String userLoginPermissions() {return "验证权限成功";}
}

权限异常处理

@ControllerAdvice
@ResponseBody
public class PermissionsException {@ExceptionHandler(UnauthorizedException.class)public String unauthorizedException(Exception ex){return "无权限";}}

多个 realm 的认证策略设置

AuthenticationStrategy class描述
AtLeastOneSuccessfulStrategy只要有一个(或更多)的 Realm 验证成功,那么认证将视为成功
FirstSuccessfulStrategy第一个 Realm 验证成功,整体认证将视为成功,且后续 Realm 将被忽略
AllSuccessfulStrategy所有 Realm 成功,认证才视为成功

ModularRealmAuthenticator 内置的认证策略默认实现是 AtLeastOneSuccessfulStrategy 方式。

//配置 SecurityManager
@Bean
public DefaultWebSecurityManager defaultWebSecurityManager(){//1 创建 defaultWebSecurityManager 对象DefaultWebSecurityManager defaultWebSecurityManager = new DefaultWebSecurityManager();//2 创建认证对象,并设置认证策略ModularRealmAuthenticator modularRealmAuthenticator = new ModularRealmAuthenticator();modularRealmAuthenticator.setAuthenticationStrategy(new AllSuccessfulStrategy());defaultWebSecurityManager.setAuthenticator(modularRealmAuthenticator);//3 封装 myRealm 集合List list = new ArrayList<>();list.add(myRealm1);list.add(myRealm2);//4 将 myRealm 存入 defaultWebSecurityManager 对象defaultWebSecurityManager.setRealms(list);//5 返回return defaultWebSecurityManager;

会话管理

SessionManager由SecurityManager管理。Shiro提供了三种实现:

  • DefaultSessionManager:用于JavaSE环境
  • ServletContainerSessionManager:用于web环境,直接使用Servlet容器的会话
  • DefaultWebSessionManager:用于web环境,自己维护会话(不使用Servlet容器的
    会话管理)

获得session方式

Session session = SecurityUtils.getSubject().getSession();
session.setAttribute(“key”,”value”)
  • Controller 中的 request,在 shiro 过滤器中的 doFilerInternal 方法,被包装成
    ShiroHttpServletRequest。
  • SecurityManager 和 SessionManager 会话管理器决定 session 来源于ServletRequest还是由 Shiro 管理的会话。无论是通过 request.getSession 或subject.getSession 获取到 session,操作session,两者都是等价的。

学习内容来自尚硅谷

相关内容

热门资讯

龙应台作品经典语录 龙应台作品经典语录大全  在生活、工作和学习中,大家都听说过或者使用过一些比较经典的语录吧,语录是言...
唯美语录 关于唯美语录大全  1、尘世有花香,总有一种香息,是穿越了灵魂悠悠而来的。这就是知己的默契,无须太多...
庆六一儿童节园长致辞 2021年庆六一儿童节园长致辞(通用10篇)  无论在学习、工作或是生活中,说到致辞,大家肯定都不陌...
晚安心语正能量带图片带字 晚安心语正能量带图片带字  在这个世界上,最能让你依靠的人是自己,能拯救你的人也只能是自己,晚安心语...
幼儿园园长新年寄语 幼儿园园长新年寄语尊敬的家长、亲爱的老师、可爱的孩子们:  充满着爱心、感动与不平凡的马年和我们渐行...
大年初八开工大吉祝福语录 大年初八开工大吉祝福语录  在我们平凡的日常里,要用到祝福语的情况还是蛮多的,祝福语的种类很多,可分...
每天一句话经典心情语录大全精...   有时候,眼睛看不到的心却看得到;有时候,你给别人最简单的建议,却是自己最难做到的。下面是小编为大...
新年寄语:新年空间留言寄语 新年寄语:新年空间留言寄语(精选80句)  在生活、工作和学习中,大家都用到过寄语吧,借助寄语人们可...
唯美晚安寄语 常用唯美晚安寄语汇总(精选115句)  挫折是一块石头,对于弱者来说它是拌脚石,让你停步不前。而对于...
大学老师评语 大学老师评语大学老师评语13.你朴实无华,思想健康,积极上进,你身处逆境,却永不退缩,你不追求享受、...
说谎的经典语录 说谎的经典语录  语录指一个人的说话记录,一般用于正式文体,通常为了说明一段时间内某人的所说句子和语...
新人入职感言 新人入职感言(通用10篇)  在平日的学习、工作或生活中,我们常常会对人或者事物有新的思考,这时就可...
几米 《地下铁》经典语录   1、我努力寻找希望,生怕幸运就在身边,却被我粗心错过  ——几米《地下铁》  2、在这个城市里,...
《我的前半生》经典台词语录   《我的前半生》,台词美到足以改写后半生,以下是CN人才小编搜集并整理的有关内容,希望对大家有所帮...
小学三年级学生期末评语 小学三年级学生期末评语(通用200句)  在日常学习、工作和生活中,大家都用到过评语吧,评语能帮助被...
期末教师给学生的评语 期末教师给学生的评语15篇  在现实生活或工作学习中,许多人都有过写评语的经历,对评语都不陌生吧,评...
初一班主任寄语 初一班主任寄语  无论是身处学校还是步入社会,要用到寄语的情况还是蛮多的,通过寄语人们可以心中的所思...
学习进步的励志语录 学习进步的励志语录  在日复一日的学习、工作或生活中,大家都听说过或者使用过一些比较经典的语录吧,语...
安全的文章美文 有关安全的文章美文  安全是人与生俱来的追求,是人民群众安居乐业的前提,是维持社会稳定和经济发展的保...
在教师节发的朋友圈文案 在教师节发的朋友圈文案(精选270句)  随着社交网络的普及,越来越多人会在社交平台上发布文案,文案...