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":[]} 表示搭建成功…

03贪心:摆动序列

03贪心&#xff1a;摆动序列 376. 摆动序列 局部最优&#xff1a;删除单调坡度上的节点&#xff08;不包括单调坡度两端的节点&#xff09;&#xff0c;那么这个坡度就可以有两个局部峰值。 整体最优&#xff1a;整个序列有最多的局部峰值&#xff0c;从而达到最长摆动序列。…

zoneinfo

在Linux系统中&#xff0c;zoneinfo是一个包含了世界各地时区信息的目录&#xff0c;通常位于/usr/share/zoneinfo。这个目录下的子目录和文件名对应了各个时区的名称。例如&#xff0c;/usr/share/zoneinfo/America/Los_Angeles文件就包含了美国洛杉矶的时区信息。 你可以通过…

MongoDB(一)

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

Javascript 使用技巧

Javascript 使用技巧 参考文章CUGGZ 数组填充 6 表示数组的长度&#xff0c; fill 表示用什么内容填充 数组 let arr Array(6).fill(",");过滤错误值 filter() let arr [1, 0, undefined, 6, 7, "", false]; arr.filter(Boolean); // [1,6,7] // 下面写法…

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

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

php笔记1

php环境 PHP作为一种服务器端脚本语言&#xff0c;可以在各种操作系统上运行。搭建PHP网站的环境&#xff0c;你需要以下几个要素&#xff1a; Web服务器&#xff1a;常见的选择有Apache、Nginx和IIS。你需要安装和配置其中一个服务器软件。PHP解释器&#xff1a;PHP是一种解…

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) 上面是前…

PyTorch深度学习代码获取内存、显存使用情况

内存使用情况 import os import psutildef get_current_memory_gb():# 获取当前进程内存占用。pid os.getpid()p psutil.Process(pid)info p.memory_full_info()return info.rss / 1024. / 1024. / 1024.显存情况 import torch import pynvml# Total memory of a GPU card…

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

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

IP-guard发布新版本4.82.610.0

IP-guard发布新版本4.82.610.0 新版本下载地址&#xff1a;http://www.tec-development.com/down/IPguard/Release/V4/IPguard4.82.0610.0.zip?s6B2D4226740543769BD8CED2D10FC4B1F64F53298624725C4DF687FFE1DEAC61 新版本升级地址&#xff1a;http://www.tec-development.c…

windbg调试句柄问题

这里写自定义目录标题 winform&#xff0c;句柄资源不够强&#xff0c;程序crash句柄主程序c程序&#xff0c;加载的插件是c# dll&#xff0c;这时候如何用windbg调试dll库如果查看句柄和对象的关系!handle 怎么能知道哪个句柄是Form对话框的句柄如何查看句柄对应的类对象 winf…

代码随想录 动态规划Ⅴ

494. 目标和 给你一个非负整数数组 nums 和一个整数 target 。 向数组中的每个整数前添加 或 - &#xff0c;然后串联起所有整数&#xff0c;可以构造一个 表达式 &#xff1a; 例如&#xff0c;nums [2, 1] &#xff0c;可以在 2 之前添加 &#xff0c;在 1 之前添加 - …