Shiro 框架基本使用

文章目录

  • Shiro框架介绍
  • Shiro 基本使用
    • SimpleAccountRealm
    • IniRealm
    • JdbcRealm
    • CustomRealm(自定义Realm)

Shiro框架介绍

Apache Shiro是一个强大且易用的Java安全框架,它执行身份验证、授权、密码和会话管理。Shiro框架通过其三个核心组件:Subject、SecurityManager和Realms,提供了一个通用的安全认证框架。

Shiro官方:http://shiro.apache.org

Shiro的核心架构图

image.png

Shiro 基本使用

认证流程:

image.png

授权流程:

image.png

SimpleAccountRealm

认证代码:

@Test
public void authen() {//认证的发起者(subject),   SecurityManager,   Realm//1. 准备Realm(基于内存存储用户信息)SimpleAccountRealm realm = new SimpleAccountRealm();realm.addAccount("admin", "admin", "超级管理员", "商家");//2. 准备SecurityManagerDefaultSecurityManager securityManager = new DefaultSecurityManager();//3. SecurityManager和Realm建立连接securityManager.setRealm(realm);//4. subject和SecurityManager建立联系SecurityUtils.setSecurityManager(securityManager);//5. 声明subjectSubject subject = SecurityUtils.getSubject();//6. 发起认证subject.login(new UsernamePasswordToken("admin", "admin"));// 如果认证时,用户名错误,抛出:org.apache.shiro.authc.UnknownAccountException异常// 如果认证时,密码错误,抛出:org.apache.shiro.authc.IncorrectCredentialsException://7. 判断是否认证成功System.out.println(subject.isAuthenticated());//8. 退出登录后再判断//        subject.logout();//        System.out.println("logout方法执行后,认证的状态:" + subject.isAuthenticated());//9. 授权是在认证成功之后的操作!!!// SimpleAccountRealm只支持角色的授权System.out.println("是否拥有超级管理员角色:" + subject.hasRole("超级管理员"));subject.checkRole("商家");// check方法校验角色时,如果没有指定角色,会抛出异常:org.apache.shiro.authz.UnauthorizedException: Subject does not have role [角色信息]
}

IniRealm

基于文件存储用户名、密码、角色等信息

准备一个.ini文件,存储用户信息,并且IniRealm支持权限校验

[users]
username=password,role1,role2
admin=admin,超级管理员,运营
[roles]
role1=perm1,perm2
超级管理员=user:add,user:update,user:delete

代码:

@Test
public void authen(){//1. 构建IniRealmIniRealm realm = new IniRealm("classpath:shiro.ini");//2. 构建SecurityManager绑定RealmDefaultSecurityManager securityManager = new DefaultSecurityManager();securityManager.setRealm(realm);//3. 基于SecurityUtils绑定SecurityManager并声明subjectSecurityUtils.setSecurityManager(securityManager);Subject subject = SecurityUtils.getSubject();//4. 认证操作subject.login(new UsernamePasswordToken("admin","admin"));//5. 角色校验// 超级管理员System.out.println(subject.hasRole("超级管理员"));subject.checkRole("运营");//6. 权限校验System.out.println(subject.isPermitted("user:update"));// 如果没有响应的权限,就抛出异常:UnauthorizedException: Subject does not have permission [user:select]subject.checkPermission("user:delete");
}

JdbcRealm

基于数据库存储用户名、密码、角色等信息。

用户认证、授权时推荐的表结构设计,经典五张表!

image.png

代码:

@Test
public void authen(){//1. 构建IniRealmJdbcRealm realm = new JdbcRealm();DruidDataSource dataSource = new DruidDataSource();dataSource.setDriverClassName("com.mysql.jdbc.Driver");dataSource.setUrl("jdbc:mysql:///shiro");dataSource.setUsername("root");dataSource.setPassword("root");realm.setDataSource(dataSource);realm.setPermissionsLookupEnabled(true);//2. 构建SecurityManager绑定RealmDefaultSecurityManager securityManager = new DefaultSecurityManager();securityManager.setRealm(realm);//3. 基于SecurityUtils绑定SecurityManager并声明subjectSecurityUtils.setSecurityManager(securityManager);Subject subject = SecurityUtils.getSubject();//4. 认证操作subject.login(new UsernamePasswordToken("admin","admin"));//5. 授权操作(角色)System.out.println(subject.hasRole("超级管1理员"));//6. 授权操作(权限)System.out.println(subject.isPermitted("user:add"));}

SQL构建代码

DROP TABLE IF EXISTS `roles_permissions`;
CREATE TABLE `roles_permissions` (`id` int(11) NOT NULL AUTO_INCREMENT,`permission` varchar(128) NOT NULL,`role_name` varchar(128) NOT NULL,PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4;-- ----------------------------
-- Records of roles_permissions
-- ----------------------------
INSERT INTO `roles_permissions` VALUES ('1', 'user:add', '超级管理员');
INSERT INTO `roles_permissions` VALUES ('2', 'user:update', '超级管理员');
INSERT INTO `roles_permissions` VALUES ('3', 'user:select', '运营');-- ----------------------------
-- Table structure for `users`
-- ----------------------------
DROP TABLE IF EXISTS `users`;
CREATE TABLE `users` (`id` int(11) NOT NULL AUTO_INCREMENT,`username` varchar(32) NOT NULL,`password` varchar(32) NOT NULL,PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4;-- ----------------------------
-- Records of users
-- ----------------------------
INSERT INTO `users` VALUES ('1', 'admin', 'admin');-- ----------------------------
-- Table structure for `user_roles`
-- ----------------------------
DROP TABLE IF EXISTS `user_roles`;
CREATE TABLE `user_roles` (`id` int(11) NOT NULL AUTO_INCREMENT,`role_name` varchar(128) NOT NULL,`username` varchar(32) NOT NULL,PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4;-- ----------------------------
-- Records of user_roles
-- ----------------------------
INSERT INTO `user_roles` VALUES ('1', '超级管理员', 'admin');
INSERT INTO `user_roles` VALUES ('2', '运营', 'admin');

CustomRealm(自定义Realm)

仿照JdbcRealm实现一个自定义的Realm对象

  • 声明POJO类,继承AuthorizingRealm
      public class CustomRealm extends AuthorizingRealm {……………………}
    
  • 重写doGetAuthenticationInfo方法(认证)
      /*** 认证方法,只需要完成用户名校验即可,密码校验由Shiro内部完成* @param token  用户传入的用户名和密码* @return* @throws AuthenticationException*/@Overrideprotected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {//1. 基于Token获取用户名String username = (String) token.getPrincipal();//2. 判断用户名(非空)if(StringUtils.isEmpty(username)){// 返回null,会默认抛出一个异常,org.apache.shiro.authc.UnknownAccountExceptionreturn null;}//3. 如果用户名不为null,基于用户名查询用户信息User user = this.findUserByUsername(username);//4. 判断user对象是否为nullif(user == null){return null;}//5. 声明AuthenticationInfo对象,并填充用户信息SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(user,user.getPassword(),"CustomRealm!!");//6. 返回inforeturn info;}// 模拟数据库操作private User findUserByUsername(String username) {if("admin".equals(username)){User user = new User();user.setId(1);user.setUsername("admin");user.setPassword("admin");return user;}return null;}
    
  • 重写doGetAuthenticationInfo方法(密码加密加盐)
      {HashedCredentialsMatcher matcher = new HashedCredentialsMatcher();matcher.setHashAlgorithmName("MD5");matcher.setHashIterations(1024);this.setCredentialsMatcher(matcher);}/*** 认证方法,只需要完成用户名校验即可,密码校验由Shiro内部完成* @param token  用户传入的用户名和密码* @return* @throws AuthenticationException*/@Overrideprotected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {//1. 基于Token获取用户名String username = (String) token.getPrincipal();//2. 判断用户名(非空)if(StringUtils.isEmpty(username)){// 返回null,会默认抛出一个异常,org.apache.shiro.authc.UnknownAccountExceptionreturn null;}//3. 如果用户名不为null,基于用户名查询用户信息User user = this.findUserByUsername(username);//4. 判断user对象是否为nullif(user == null){return null;}//5. 声明AuthenticationInfo对象,并填充用户信息SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(user,user.getPassword(),"CustomRealm!!");// 设置盐!info.setCredentialsSalt(ByteSource.Util.bytes(user.getSalt()));//6. 返回inforeturn info;}// 模拟数据库操作private User findUserByUsername(String username) {if("admin".equals(username)){User user = new User();user.setId(1);user.setUsername("admin");user.setPassword("1ebc4dcaf1e21b814ece65f27531f1a9");user.setSalt("weruiothergjkdfnbgjkdfngjkdf");return user;}return null;}
    
  • 重写doGetAuthorizationInfo方法(授权)
    // 授权方法,授权是在认证之后的操作
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {//1. 获取认证用户的信息User user = (User) principals.getPrimaryPrincipal();//2. 基于用户信息获取当前用户拥有的角色。Set<String> roleSet = this.findRolesByUser();//3. 基于用户拥有的角色查询权限信息Set<String> permSet = this.findPermsByRoleSet(roleSet);//4. 声明AuthorizationInfo对象作为返回值,传入角色信息和权限信息SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();info.setRoles(roleSet);info.setStringPermissions(permSet);//5. 返回return info;
    }private Set<String> findPermsByRoleSet(Set<String> roleSet) {Set<String> set = new HashSet<>();set.add("user:add");set.add("user:update");return set;
    }private Set<String> findRolesByUser() {Set<String> set = new HashSet<>();set.add("超级管理员");set.add("运营");return set;
    }
    

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/83346.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ASP.NET dotnet 3.5 实验室信息管理系统LIMS源码

技术架构&#xff1a;ASP.NET dotnet 3.5 LIMS作为一个信息管理系统&#xff0c;它有着和ERP、MIS之类管理软件的共性&#xff0c;如它是通过现代管理模式与计算机管理信息系统支持企业或单位合理、系统地管理经营与生产&#xff0c;最大限度地发挥现有设备、资源、人、技术的…

OpenCV Series : Target Box Outline Border

角点 P1 [0] (255, 000, 000) P2 [1] (000, 255, 000) P3 [2] (000, 000, 255) P4 [3] (000, 000, 000)垂直矩形框 rect cv2.minAreaRect(cnt)targetColor roi_colortargetThickness 1targetColor (255, 255, 255)if lineVerbose:if …

深度探讨丨区块链领域企业的未来之路

发表时间&#xff1a;2022年8月4日 信息来源&#xff1a;bsvblockchain.org 随着公司越来越多地采用区块链和人工智能等新技术&#xff0c;他们也应当注意其中的一些机遇与挑战。这是近期在波兰华沙举行的“明日技术大会”上的一个主要圆桌讨论议题。 在圆桌讨论中&#xff0c…

基于SSM+Vue的乐购游戏商城系统

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;采用Vue技术开发 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#x…

【自动化测试】如何提高自动化脚本的健壮性和稳定性?

自动化脚本可能出错的原因&#xff1f; 配置环境引起 自动化测试脚本的配置。对测试程序进行配置。如&#xff1a;是否还原初始设置、是否删除某些数据。对浏览器进行配置。对与测试程序有关的程序或影响脚本稳定性的程序进行配置。 非配置环境引起 网络延时&#xff0c;识…

Docker搭建私有仓库

Docker搭建私有仓库 一、私有仓库搭建 # 1、拉取私有仓库镜像 docker pull registry # 2、启动私有仓库容器 docker run --nameregistry -p 5000:5000 registry # 3、打开浏览器输入 http://你的服务器地址:5000/v2/_catalog 看到 {"repositories":[]} 表示搭建成功…

MongoDB(一)

数据库分类 一、关系型数据库&#xff08;RDBMS&#xff09; mysql 、Oracle、DB2、SQL Server 关系数据库中全都是表 二、非关系型数据库&#xff08;NO SQL&#xff09; MongoDB、Redis 键值对数据库 文档数据库MongoDB 下载 mongoDB https://www.mongodb.com/try/downloa…

软考高级之系统架构师之企业应用集成EAI

概述 在企业信息化建设的过程中&#xff0c;由于缺乏统一规划和总体布局&#xff0c;往往形成多个信息孤岛。信息孤岛使数据的一致性无法得到保证&#xff0c;信息无法共享和反馈&#xff0c;需要重复多次的采集和输入。信息孤岛是企业信息化一个重要的负面因素&#xff0c;其…

OpenAI开发系列(二):大语言模型发展史及Transformer架构详解

全文共1.8w余字&#xff0c;预计阅读时间约60分钟 | 满满干货&#xff0c;建议收藏&#xff01; 一、介绍 在2020年秋季&#xff0c;GPT-3因其在社交媒体上病毒式的传播而引发了广泛关注。这款拥有超过1.75亿参数和每秒运行成本达到100万美元的大型语言模型&#xff08;Large …

Linux服务器占用处理手记

磁盘占用定位处理 查看磁盘占用情况&#xff1a; df -h 查看每个目录的占用情况&#xff1a; du -h -x --max-depth1 查找大文件和目录 du -sh /* du -sh /home/* 可参考&#xff1a; Linux垃圾清理指北_linux 清理垃圾_智商二五零_的博客-CSDN博客 查看CPU和内存占用情…

javascript使用正则表达式去除字符串中括号的方法

如下面的例子&#xff1a; (fb6d4f10-79ed-4aff-a915-4ce29dc9c7e1,39996f34-013c-4fc6-b1b3-0c1036c47119,39996f34-013c-4fc6-b1b3-0c1036c47169,39996f34-013c-4fc6-b1b3-0c1036c47111,2430bf64-fd56-460c-8b75-da0a1d1cd74c,39996f34-013c-4fc6-b1b3-0c1036c47112) 上面是前…

【踩坑篇】代码中使用 Long 作为 Map的Key存在的问题

本周的工作结束&#xff0c;详述一些在项目代码中实际遇到的一些坑。 代码中遇到这样一个场景&#xff1a; 有个业务接口&#xff0c;接口返回的值是一个JSON格式的字符串&#xff0c;通过JSON解析的方式&#xff0c;解析为格式为&#xff1a; Map<Long, Map<String, O…

优维低代码实践:菜单

优维低代码技术专栏&#xff0c;是一个全新的、技术为主的专栏&#xff0c;由优维技术委员会成员执笔&#xff0c;基于优维7年低代码技术研发及运维成果&#xff0c;主要介绍低代码相关的技术原理及架构逻辑&#xff0c;目的是给广大运维人提供一个技术交流与学习的平台。 优维…

基于Gradio/Stable Diffusion/Midjourney的AIGC自动图像绘画生成软件 - Fooocus

0.参考 本项目&#xff1a;GitHub - lllyasviel/Fooocus: Focus on prompting and generating 作者&#xff1a;Lvmin Zhang ​编辑 lllyasviel 另一杰作 ContorlNet https://github.com/lllyasviel/ControlNet 模型&#xff1a;https://huggingface.co/stabilityai/stab…

cpolar内网穿透

1、下载地址 https://www.cpolar.com/ windows系统可以在cpolar官网下载最新的安装包&#xff0c;然后解压默认安装即可。 2、地址配置 创建隧道映射内网端口&#xff0c;双击安装的软件&#xff0c;即可进入浏览器配置界面 http://localhost:9200/#/dashboard cpolar安装…

Vue中的生命周期钩子

生命周期钩子 :::warning 注意 所有生命周期钩子的 this 上下文将自动绑定至实例中&#xff0c;因此你可以利用 this 访问 props、data、computed 和 methods 等选项内的数据/函数。这意味着你不应该使用箭头函数来定义一个生命周期方法&#xff0c;因为箭头函数中没有 this&a…

实时车辆行人多目标检测与跟踪系统(含UI界面,Python代码)

算法架构&#xff1a; 目标检测&#xff1a;yolov5 目标跟踪&#xff1a;OCSort其中&#xff0c; Yolov5 带有详细的训练步骤&#xff0c;可以根据训练文档&#xff0c;训练自己的数据集&#xff0c;及其方便。 另外后续 目标检测会添加 yolov7 、yolox&#xff0c;目标跟踪会…

node_modules/XXX/index.js:XXX;XX ||= XXX?.[level];SyntaxError: Une

这个语法是 ECMAScript 2021的语法 还挺新的 对node版本要求会比较高 这里这个 icon || this.options.icon?.[level];意思就是 如果this.options.icon [level] 拿得到值 就等于它 否则 如果拿不到 icon 就等于自己 要解决这个问题 一个是你可以提高node版本 但我不建议 还是…

AlexNet——训练花数据集

目录 一、网络结构 二、创新点分析 三、知识点 1. nn.ReLU(inplace) 2. os.getcwd与os.path.abspath 3. 使用torchvision下的datasets包 4. items()与dict()用法 5. json文件 6. tqdm 7. net.train()与net.val() 四、代码 AlexNet是由Alex Krizhevsky、Ilya S…

NLP技术如何为搜索引擎赋能

目录 1. NLP关键词提取与匹配在搜索引擎中的应用1. 关键词提取例子 2. 关键词匹配例子 Python实现 2. NLP语义搜索在搜索引擎中的应用1. 语义搜索的定义例子 2. 语义搜索的重要性例子 Python/PyTorch实现 3. NLP个性化搜索建议在搜索引擎中的应用1. 个性化搜索建议的定义例子 2…