当前位置: 首页 > news >正文

Shiro核心——Realm

Realm

  • Realm的作用
  • Realm的实现
  • Realm的配置
  • 实例


在Shiro中,Realm是一个非常灵活和强大的安全组件,它能够与各种数据源进行集成,满足各种安全需求。通过实现自定义的Realm,我们可以轻松地定制身份验证、授权和加密逻辑,实现更加细粒度的访问控制。在使用Realm时,我们需要将其配置到SecurityManager中,并通过配置文件或编程方式来指定使用哪些Realm。Shiro提供了多个默认的Realm实现,例如IniRealm和JdbcRealm,我们也可以通过继承AbstractAuthorizingRealm或AbstractAuthenticatingRealm来创建自定义的Realm实现。

Realm的作用

Realm的主要作用是执行身份验证和授权操作。当一个Subject需要进行身份验证时,它会调用SecurityManager中的authenticate方法,该方法会委托给所有配置的Realm来进行身份验证。当验证成功后,Realm会返回一个SimpleAuthenticationInfo对象,其中包含了身份验证信息(如用户名、密码等),这些信息会在会话管理中使用。

当一个Subject需要进行授权操作时,它会调用SecurityManager中的authorize方法,该方法会委托给所有配置的Realm来进行授权操作。Realm会返回一个AuthorizationInfo对象,其中包含了该Subject的所有权限信息(如角色、权限等),这些信息会被用于控制Subject在应用程序中的访问权限。

除了身份验证和授权操作之外,Realm还可以用于加密和解密操作。例如,使用Realm中的CredentialsMatcher接口可以对密码进行加密和验证。

Realm的实现

Realm是一个接口,它定义了一系列方法,用于处理身份验证和授权操作。在实际应用中,我们可以通过实现自定义的Realm来满足不同的安全需求。Shiro提供了多个默认的Realm实现,包括:

  • IniRealm:通过一个INI配置文件来存储用户、角色和权限信息。
  • JdbcRealm:通过JDBC来访问数据库,存储用户、角色和权限信息。
  • ActiveDirectoryRealm:通过LDAP协议来访问Active Directory,存储用户、角色和权限信息。
  • LdapRealm:通过LDAP协议来访问LDAP服务器,存储用户、角色和权限信息。
  • TextConfigurationRealm:通过一个文本文件来存储用户、角色和权限信息。

此外,我们也可以通过继承AbstractAuthorizingRealm或AbstractAuthenticatingRealm来创建自定义的Realm实现。

Realm的配置

在使用Realm时,我们需要将其配置到SecurityManager中。Shiro提供了一个ini配置文件来方便地进行配置。在ini配置文件中,我们可以使用[main]部分来配置SecurityManager,并通过配置securityManager.realms属性来指定使用哪些Realm。
例如,下面的配置文件中使用了IniRealm和JdbcRealm来实现身份验证和授权操作:

[main]
securityManager.realms = $iniRealm, $jdbcRealm[iniRealm]
# IniRealm的配置[jdbcRealm]
# JdbcRealm的配置

在实际应用中,我们也可以通过编程方式来配置Realm,例如:

IniRealm iniRealm = new IniRealm("classpath:shiro.ini");
JdbcRealm jdbcRealm = new JdbcRealm();
securityManager.setRealms(Arrays.asList(iniRealm, jdbcRealm));

实例

下面是一个自定义的Realm实现,该Realm实现基于数据库进行身份验证和授权操作:

public class CustomRealm extends AuthorizingRealm {private UserService userService; // UserService为自定义的用户服务接口public CustomRealm(UserService userService) {this.userService = userService;}/*** 认证方法,用于身份验证*/@Overrideprotected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {UsernamePasswordToken upToken = (UsernamePasswordToken) token;String username = upToken.getUsername();User user = userService.getUserByUsername(username);if (user == null) {throw new UnknownAccountException("用户不存在");}String password = user.getPassword(); // 从数据库中获取密码SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(username, password, getName());return info;}/*** 授权方法,用于权限控制*/@Overrideprotected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {String username = (String) principals.getPrimaryPrincipal();User user = userService.getUserByUsername(username);SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();for (Role role : user.getRoles()) {info.addRole(role.getName()); // 添加角色for (Permission permission : role.getPermissions()) {info.addStringPermission(permission.getName()); // 添加权限}}return info;}
}

上述代码中,CustomRealm继承了AuthorizingRealm类,并实现了doGetAuthenticationInfodoGetAuthorizationInfo方法,用于身份验证和授权操作。在认证方法中,我们首先从传入的token中获取用户名,然后通过userService从数据库中获取用户信息,如果用户不存在则抛出异常,否则将密码信息封装在SimpleAuthenticationInfo对象中返回。

在授权方法中,我们首先从PrincipalCollection中获取用户名,然后通过userService从数据库中获取用户信息。我们将用户的所有角色和权限信息添加到SimpleAuthorizationInfo对象中,并将该对象返回。这样,当Subject需要进行授权操作时,CustomRealm就会被调用,返回该Subject的所有权限信息。

需要注意的是,CustomRealm中的userService需要通过构造函数进行注入,以便从外部获取用户信息。另外,在使用CustomRealm时,我们需要将其配置到SecurityManager中。例如,下面的代码演示了如何将CustomRealm配置到SecurityManager中:

CustomRealm customRealm = new CustomRealm(userService);
DefaultSecurityManager securityManager = new DefaultSecurityManager();
securityManager.setRealm(customRealm);
SecurityUtils.setSecurityManager(securityManager);

通过上述代码,我们可以将CustomRealm配置到SecurityManager中,并使用该SecurityManager进行身份验证和授权操作。
除了上述示例中的基于数据库的自定义Realm实现,我们还可以根据具体的业务需求,实现各种自定义Realm,例如:

  • 基于LDAP的Realm:通过LDAP协议验证用户身份和获取用户授权信息。
  • 基于OAuth的Realm:通过OAuth协议验证用户身份和获取用户授权信息。
  • 基于第三方API的Realm:通过调用第三方API验证用户身份和获取用户授权信息。

下面是一个基于LDAP的自定义Realm示例:

public class LdapRealm extends AuthenticatingRealm {private LdapContextFactory contextFactory;public LdapRealm(LdapContextFactory contextFactory) {this.contextFactory = contextFactory;}@Overrideprotected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {UsernamePasswordToken upToken = (UsernamePasswordToken) token;String username = upToken.getUsername();String password = new String(upToken.getPassword());try {LdapContext ldapContext = contextFactory.getLdapContext(username, password);ldapContext.close();} catch (AuthenticationException e) {throw new IncorrectCredentialsException("用户名或密码不正确");} catch (NamingException e) {throw new AuthenticationException("无法连接到LDAP服务器");}return new SimpleAuthenticationInfo(username, password, getName());}
}

在上述代码中,我们实现了基于LDAP协议的身份验证逻辑。我们通过 LdapContextFactory获取LDAP连接,并使用用户名和密码进行身份验证。如果验证失败,则抛出异常;否则将用户名和密码封装在SimpleAuthenticationInfo对象中返回。

需要注意的是,LdapContextFactory是一个自定义的工厂类,用于创建LDAP连接。该工厂类需要根据具体的LDAP服务器配置进行实现。

通过自定义Realm实现,我们可以灵活地扩展Shiro的功能,满足各种不同的安全需求。

相关文章:

Shiro核心——Realm

RealmRealm的作用Realm的实现Realm的配置实例在Shiro中,Realm是一个非常灵活和强大的安全组件,它能够与各种数据源进行集成,满足各种安全需求。通过实现自定义的Realm,我们可以轻松地定制身份验证、授权和加密逻辑,实现…...

开发钉钉微应用,实现免登+调试

1.创建h5微应用 https://open.dingtalk.com/document/orgapp/develop-org-h5-micro-applications 根据里面的三个步骤,创建h5微应用 2.免登之前必须要先进行JSAPI的授权 文档说明: https://open.dingtalk.com/document/orgapp/jsapi-authentication 根据文档中的说明 步骤…...

0308java基础-注解,反射

一,注解 1.什么是注解: Annotation是从jdk5.0开始引入的新技术作用: 不是程序本身,可以对程序作出解释可以被其他程序读取格式: 以注释名在代码中存在,还可以添加一些参数值SuppressWarnings(value"…...

【鸿蒙应用ArkTS开发系列】- 页面跳转及传参

先看下效果图 大致实现的功能点: 从Indext页面跳转到Second页面,传递两个参数,一个字符串,一个数量;Second获取Index页面传递的数据;Second页面点击返回弹窗;Second页面返回携带参数数据&#…...

StringBuilder 类

Java StringBuilder类是一个可变字符串缓冲区,它提供了丰富的方法可以方便地进行字符串操作。与Java StringBuffer类类似,Java StringBuilder类的主要作用是优化字符串的拼接操作,提高代码的效率。在本篇文章中,我们将详细介绍Jav…...

kubectl-k8s用户切换

kubernetes默认使用$HOME/.kube/config配置文件。可以在配置文件中定义多个USER和Cluster的上下文。所以就有两种方式切换用户同一个config中,切换不同用户上下文切换不同的config配置文件同config切换不同用户上下文查看config文件kubeconfig config view查看当前上…...

【面试题】三道面试题让你掌握JavaScript中的执行上下文与作用域以及闭包

前言大厂面试题分享 面试题库前后端面试题库 (面试必备) 推荐:★★★★★地址:前端面试题库大家好,笔者呢最近再回顾JavaScript知识时,又看到了JavaScript的一些较为常见的内容,仔细看了之后发现…...

计算机网络-- 应用层(day08)

计算机网络两种方式 网络应用程序运行再处于网络边缘的不同端系统上,通过彼此间的通信来共同完成某项任务。 开发一种新的网络应用首先要考虑的问题就是网络应用程序在各种端系统上的组织方式和它们之间的关系。 目前流行的主要有以下两种: 客户/服务器…...

English Learning - L2-5 英音地道语音语调 弹力双元音 [ɪə] [ʊə] [eə] 2023.03.6 周一

English Learning - L2-5 英音地道语音语调 弹力双元音 [ɪə] [ʊə] [eə] 2023.03.6 周一朗读节奏元音的长度元音发音在清辅音和浊辅音前的区别元音发音跟后面浊辅音节数的区别元音在重读音节中复习大小元音发音对比/ʌ/ 舌中音/ɒ/ 舌后音/ʊ/ 舌后音/ɪ/ 舌前音[ɑ:] VS […...

SpringBoot——统一功能处理

处理登陆拦截 上一片博客中讲到SpringAOP可以对页面进行拦截,我们可以用SpringAOP实现对登陆的拦截 但是由于拦截需要HttpSession对象,并且之后还需要页面重定向,因此在实际应用中,并不用SpringAOP进行登陆拦截,而是…...

ORACLE SQL格式化小数点

ORACLE SQL格式化小数点 select CONCAT(TO_CHAR(0.00100,‘990.999’),‘%’) as a0 , CONCAT(TO_CHAR(1100,‘990.999’),‘%’) as a1 , CONCAT(TO_CHAR(0.236100,‘990.999’),‘%’) as a2 , CONCAT(TO_CHAR(0.0200100,‘990.999’),‘%’) as a3 , CONCAT(TO_CHAR(1.0310…...

【信息学奥数】—— 第一部分 C++语言 知识总结

【信息学奥数】—— 第一部分 C语言 知识总结C语言一、C语言入门二、顺序结构程序设计运算符和表达式常量和变量标准数据类型数据输入输出三、控制结构程序设计if语句switch语句四、循环结构程序设计for语句while语句do-while语句五、数组一维数组二维数组字符数组六、函数七、…...

video层级过高,以及界面使用多个video时,在安卓APP上同时播放的问题(uniapp)

1、video层级过高的问题 问题一: 我的界面由于是自定义导航栏,所以使用video时,上滑界面video会直在最上层,盖着 头部导航栏 解决方法:使用cover-view,自定义头部使用cover-view替换view 问题二:自定义…...

C++基础了解-14-C++ 字符串

C 字符串 一、C 风格字符串 C 风格的字符串起源于 C 语言,并在 C 中继续得到支持。字符串实际上是使用 null 字符 \0 终止的一维字符数组。因此,一个以 null 结尾的字符串,包含了组成字符串的字符。 下面的声明和初始化创建了一个 RUNOOB …...

浅谈几种网络攻击及攻防原理

HTTP Flood攻击 https://zhuanlan.zhihu.com/p/337399808 HTTP Flood攻击是针对Web服务在第七层协议发起的攻击。第七层主要是应用层,是一些终端的应用,比如(各种文件下载)、浏览器、QQ等,可以将其理解为在电脑屏幕上可…...

Kafka消息中间件(Kafka与MQTT区别)

文章目录KafkaKafka重要原理Topic 主题Partition 分区Producer 生产者Consumer 消费者Broker 中间件Offset 偏移量Kafka与mqtt区别Kafka Kafka是一个分布式流处理平台,它可以快速地处理大量的数据流。Kafka的核心原理是基于发布/订阅模式的消息队列。Kafka允许多个…...

Go垃圾回收原理

术语介绍 赋值器:说白了就是你写的程序代码,在程序的执行过程中,可能会改变对象的引用关系,或者创建新的引用。 回收器:垃圾回收器的责任就是去干掉那些程序中不再被引用得对象。 STW:全称是stop the word,GC期间某个阶段会停止…...

Coredump-N: stack 空间被临时变量吃满,导致内存访问出现问题

文章目录 代码寄存器汇编代码 int main() {fun(0); #define S 0x0019fd08UL 、、 乘5 等0x81F128 char buff4[S]; char buff3[S]; char buff2[S]; char buff1[S]; char buff[S]; memset(buff, 0, sizeof(buff)); memset(buff4, 0, sizeof(buff)); memset(buff3, 0, sizeof(buf…...

GO中使用viper读取配置文件

文章目录 viper的使用例子一:例子二:viper的使用 ​ viper的源码地址https://github.com/spf13/viper,它是一个可以用来读取配置文件的工具。在项目中可以通过下面指令安装: go get github.com/spf13/viper​ 下面我们通过两个例子,来介绍一下viper在项目中应该如何使用…...

webpack dll 提升构建速度

DLL,动态链接库(Dynamic Link Library 或者 Dynamic-link Library),由微软公司提出。目的是为了节约应用程序所需的磁盘和内存空间。 在一个传统的非共享库中,如果两个程序调用同一个子程序,就会出现两份那…...

C++面向对象编程之三:初始化列表、类对象作为类成员、静态成员

初始化列表C提供了初始化列表语法,可以用于成员属性初始化。语法规则:无参构造函数():属性1(值1), 属性2(值2), ... { }有参构造函数(形参1, 形参2, ...):属性1(形参1), 属性2(形参2), ... { }example:写一个怪物类,有怪物id和血量…...

跨域问题解决方案

目录 1.同源策略 2.解决方案(后端) (1)在后端方法添加CrossOrigin (2)添加CORS过滤器 (3)实现WebMvcConfigure接口,重写addCorsMappings方法 3.解决方案(前端) (1)前端配置代理 1.同源策略 同源策略(Same origin policy)是一种约定&am…...

Vue3电商项目实战-购物车模块7【20-登录后-批量删除、21-登录后-选中状态修改数量、22-登录后-全选反选、23-登录后-修改规格、24-下单结算】

文章目录20-登录后-批量删除21-登录后-选中状态&修改数量22-登录后-全选反选23-登录后-修改规格24-下单结算20-登录后-批量删除 目标:完成批量删除选中商品,完成清空失效的商品 大概步骤: 完成cart.js模块中的批量删除actions的登录状态…...

软件测试之快速熟悉项目

快速熟悉项目 1、了解项目架构 C/S架构 C/S 代表的是客户端/服务器(client/server),这类软件的使用者需要在本地电脑安装客户端程序,例如:QQ。 优点:安全性高。 缺点:一旦软件有更新,用户需要手动下载&am…...

软考高级信息系统项目管理师系列之二十一:项目风险管理

软考高级信息系统项目管理师系列之二十一:项目风险管理 一、项目风险管理内容整理二、项目风险管理1.风险及项目风险管理定义2.项目风险的特点3.风险的分类4.风险成本5.项目风险管理与其他管理的关系三、规划风险管理1.规划风险管理2.输入3.工具与技术4.输出四、识别风险1.识别…...

打包成JAR文件和WAR文件,到底有什么区别?

Spring Boot是一种基于Spring框架的快速开发应用程序的工具,可以轻松地构建可部署的独立应用程序。在使用Spring Boot时,你可能会注意到有两种不同的部署选项:打包成JAR文件和WAR文件。在这篇文章中,我们将深入探讨这两种部署选项…...

STM32 OTA应用开发——通过串口/RS485实现OTA升级(方式1)

STM32 OTA应用开发——通过串口/RS485实现OTA升级(方式1) 目录STM32 OTA应用开发——通过串口/RS485实现OTA升级(方式1)前言1 环境搭建2 功能描述3 程序编写3.1 BootLoader部分3.2 APP的制作4 修改工程中的内存配置4.1 Bootloader…...

在教学中常被问到的几个vue3.x与typescript的问题,统一解答

在教学当中,学生在学习vue3.x时,常常会问到typescript和vue3.x之间的关系,感觉这两个技术总是绑在一起的,下面老赵来统一解答一下: 那学vue3.x,为什么要求也要掌握typescript Vue 3.x是一个使用TypeScript编…...

纯css实现超炫酷的星空背景按钮

也是在制作项目时发现的,找了很多demo,一点一点测试,发现这个按钮也是非常的炫酷 用到了几个属性,keyframes,::after,::before 先了解一下他们分别都是干嘛的 keyframes 关键帧 keyframes at-rule 规则通过在动画序…...

openpnp - 贴片前, 放入一块新板子后, 对板子的坐标矫正

文章目录openpnp - 贴片前, 放入一块新板子后, 对板子的坐标矫正概述笔记实验前置条件实验开始建立自己板子上的Mark点封装, 用于自己人工圈定判断Mark点位置是否正确建立mark点封装根据多个mark点, 来精确定位板子左下角原点坐标ENDopenpnp - 贴片前, 放入一块新板子后, 对板子…...