Shiro 使用 sessionId 或用户名+密码进行身份验证

2024-03-09

我在 Java 身份验证框架和身份验证工作流程方面没有太多经验(只有一些理论知识),因此出于教育目的,我尝试为我的 HTTP 应用程序创建这种类型的身份验证:

  1. 客户端将登录名+密码发布到/login.
  2. Shiro 通过给定的凭据登录用户。服务器返回客户端他的sessionId.
  3. 客户端请求某种资源/myresource?sessionId=1234567.
  4. Shiro 通过给定的方式登录主题sessionId。然后服务器执行常规工作流程来获取/myresource(使用 Shiro 管理方法级访问权限)。

基本上我有这些问题:

  1. 我想我不需要 HTTP 会话,也不需要 Servlet 会话。 Shiro 有它自己的会话管理器,足以满足我的需要。我错了吗?
  2. 向客户端提供真实的 sessionId 是一个好习惯还是应该发送某种 sessionToken (在服务器端解析为 sessionId)?
  3. 如何使用 sessionId(客户端应在本地存储)登录主题?
  4. 在进行此类身份验证之前我还需要了解其他信息吗?

提前致谢。


我想我不需要 HTTP 会话,也不需要 Servlet 会话。 Shiro 有它自己的会话管理器,足以满足我的需要。我错了吗?

不,你是对的。这就是为什么四郎很棒。从文档 https://shiro.apache.org/session-management.html:

Shiro 的会话支持比这两种 [Web 容器或 EJB Stateful Session Beans] 机制更易于使用和管理,并且可以在任何应用程序中使用,无论容器如何。

e.g.

Subject currentUser = SecurityUtils.getSubject();    
Session session = currentUser.getSession();
session.setAttribute( "someKey", someValue);

引用自the doc http://shiro.apache.org/session-management.html#SessionManagement-UsingSessions: getSession calls work in any application, even non-web applications

向客户端提供真实的 sessionId 是一个好习惯还是应该发送某种 sessionToken (在服务器端解析为 sessionId)?

发送普通的 sessionId 不是一个好主意。特别是,如果您通过未加密的网络发送数据。要么使用 HTTPS 之类的东西,要么使用某些行NONCE http://en.wikipedia.org/wiki/Cryptographic_nonce罢工>。

并且,旁注,如果通过 http/s POST 数据而不是将其放在 URL 中。

如何使用 sessionId(客户端应在本地存储)登录主题?

您的意思是,一旦有了会话 ID,如何验证主题?你可以简单地, 从文档中,

Subject requestSubject = new Subject.Builder().sessionId(sessionId).buildSubject();

在进行此类身份验证之前我还需要了解其他信息吗?

Yes.

  1. Read Shiro 的会话管理 http://shiro.apache.org/session-management.html
  2. 倾斜一下中间人攻击 http://en.wikipedia.org/wiki/Man-in-the-middle_attack
  3. About HTTPS http://en.wikipedia.org/wiki/HTTP_Secure and SSL http://www.verisign.com/ssl/ssl-information-center/how-ssl-security-works/
  4. 一些关于哈希函数的内容this http://en.wikipedia.org/wiki/Hash_function, Apache Commons DigestUtils http://commons.apache.org/codec/apidocs/org/apache/commons/codec/digest/DigestUtils.html有可能

Updates

关于主题身份验证部分 - 它会使新创建的主题成为当前经过身份验证的主题吗?如果不是,我如何使其成为“当前”主题?

如果你说的是new Subject.Builder().sessionId(sessionId).buildSubject(), 它不会。我不知道如何将其设置为当前用户对于线程。四郎的JavaDoc http://shiro.apache.org/static/current/apidocs/org/apache/shiro/subject/Subject.Builder.html says,

[这样]返回的Subject实例不会自动绑定到应用程序(线程)以供进一步使用。也就是说,SecurityUtils.getSubject() 不会自动返回与构建器返回的实例相同的实例。如果需要,框架开发人员可以绑定构建的主题以供继续使用。

因此,这取决于您如何在当前线程中绑定主题或进一步使用。

如果你担心如何SecurityUtils.getSubject();thingy 在 Web 容器上下文中工作得很好,它使用简单的 cookie 来存储您的会话数据。当您的请求通过 Shiro 过滤器时,它会将当前主题附加到请求的生命周期(当前线程)。当你作为getSubject()它只是得到Subject来自请求。我发现了一个有趣的话题here http://shiro-user.582556.n2.nabble.com/Question-about-SecurityUtils-getSubject-td6952295.html.

关于随机数部分:如果他向我发送某种哈希而不是他的 sessionId - 我将无法对其进行解码以获取真正的 sessionId (以授权他)。我在这里错过了什么吗?

Nonce 部分——令人头疼。现在重新思考,我认为做 NONCE 实在是太过分了。无论如何,让我解释一些,

  1. 用户首次使用其用户名和密码登录。放userid, nonce(例如,UUID),以及HASH(sessionID+nonce),在客户端称之为 hash1。说,在饼干里。储存这个nonce在服务器端,可能位于数据库或地图中user_id <--> nonce,session_id

  2. 在后续请求中,请确保回传userid, nonceHASH.

  3. 在服务器端,您要做的第一件事是验证请求。获取sessionId and nonce存储在 hashmap 或 DB 中基于user_id这是客户发送的。创建一个哈希值 HASH(sessionId_from_db+nonce_from_db),称之为 hash2。

  4. 现在,如果 hash1 与 hash2 匹配,则可以验证请求,并且由于您已在服务器端存储了当前的 sessionId,因此可以使用它。请求完成后,在 cookie 和服务器端设置新的随机数。

如果您完成 1 - 4,您会意识到您不需要 Shiro 进行身份验证。 (: 所以,我收回我的话,NONCE 在这种情况下不适用,除非你太担心安全性而不是性能。

为什么 MITM 攻击对我很重要?我的客户端(javascript ajax 代码)通过 ajax 从服务器获取数据。所以我认为我不应该以任何方式关心 MITM。

我认为这对你来说应该很重要。 MITM 攻击意味着您的请求/响应通过机器 (MITM) 链接到您的路由器。如果是未加密的请求,则对于 MITM 来说都是纯文本。他可以看到您的所有请求...并且可能欺骗请求并可能劫持会话。让我找一些例子......http://michael-coates.blogspot.com/2010/03/man-in-middle-attack-explained.html http://michael-coates.blogspot.com/2010/03/man-in-middle-attack-explained.html

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Shiro 使用 sessionId 或用户名+密码进行身份验证 的相关文章

  • Java将字符串解析为double

    如何解析字符串中的这个 Double 00034800 变成 Double 值 最后两位数字实际上是小数点 所以我正在寻找的结果是348 00 是否有这样的格式可以与十进制格式一起使用 Well String s 00034800 doub
  • 连接外部 Accumulo 实例和 java

    我正在尝试使用 Accumulo 连接到虚拟机 问题是 我无法将其连接到 Java 中 我可以看到 Apache 抛出的网页 但我无法让它与代码一起工作 我认为这是缺乏知识的问题而不是真正的问题 但我找不到这方面的文档 所有示例都使用 lo
  • 使用 proguard 混淆文件名

    我正在使用 proguard 和 Android Studio 混淆我的 apk 当我反编译我的apk时 我可以看到很多文件 例如aaa java aab java ETC 但我项目中的所有文件都有原始名称 有没有办法混淆我的项目的文件名
  • 在不支持 CAS 操作的处理器上进行 CompareAndSet

    今天 我在一次采访中被问到下一个问题 如果您在具有不支持 CAS 操作的处理器的机器上调用 AtomicLong 的compareAndSet 方法 会发生什么情况 您能否帮我解决这个问题 并在可能的情况下提供一些全面描述的链接 From
  • Java 中的 <-- 是什么? [复制]

    这个问题在这里已经有答案了 我遇到了下面的片段 它输出到4 3 2 1 我从来没有遇到过 lt 在爪哇 Is lt 使 var1 的值变为 var2 的运算符 public class Test public static void mai
  • 查看Java Agent修改的Java类的源代码

    我需要了解 Java 代理如何修改我的初始类 以便我能够理解代码的作用 build gradle configurations jar archiveName agent2 jar jar manifest attributes Prema
  • 什么是内部类的合成反向引用

    我正在寻找应用程序中的内存泄漏 我正在使用的探查器告诉我寻找这些类型的引用 但我不知道我在寻找什么 有人可以解释一下吗 Thanks Elliott 您可以对 OUTER 类进行合成反向引用 但不能对内部类实例进行合成 e g class
  • 我对线程失去了理智

    我想要这个类的对象 public class Chromosome implements Runnable Comparable
  • 自定义列表字段点击事件

    我正在编写一个应用程序 其中我创建了用于显示列表视图的自定义列表字段 我的 CustomListField 包含连续的一个图像和文本 我正在通过单击列表字段行获取字段更改侦听器 但我也想将字段更改侦听器放在图像上 谁能告诉我我该怎么做 这是
  • JOOQ 忽略具有默认值的数据库列

    看来JOOQ完全忽略了数据库列的默认值 既不会更新 ActiveRecord 对象 也不会在 INSERT 时跳过此列 相反 它尝试将其设置为 NULL 这在 NOT NULL 列上失败 Example CREATE TABLE bug f
  • 将类转换为 JSONObject

    我有好几堂这样的课 我想将类转换为 JSONObject 格式 import java io Serializable import com google gson annotations SerializedName public cla
  • 如何自定义舍入形式

    我的问题可能看起来很简单 但仍然无法得到有效的东西 我需要自定义 Math round 舍入格式或其他格式以使其工作如下 如果数字是 1 6 他应该四舍五入到 1 如果大于或等于 1 7 他应该四舍五入到 2 0 对于所有其他带有 6 的小
  • 数据库中的持久日期不等于检索日期

    我有一个具有 Date 属性的简单实体类 此属性对应于 MySQL 日期时间列 Entity public class Entity Column name start date Temporal TemporalType TIMESTAM
  • Joshua Bloch 的构建器设计模式有何改进?

    早在 2007 年 我就读过一篇关于 Joshua Blochs 所采用的 构建器模式 的文章 以及如何修改它以改善构造函数和 setter 的过度使用 特别是当对象具有大量属性 其中大部分属性是可选的 时 本文对此设计模式进行了简要总结
  • 按降序排序映射java8 [重复]

    这个问题在这里已经有答案了 private static
  • Tomcat 6 未从 WEB-INF/lib 加载 jar

    我正在尝试找出我的 tomcat 环境中的配置问题 我们的生产服务器正在运行 tomcat 安装并从共享 NFS 挂载读取战争 然而 当我尝试使用独立的盒子 及其配置 进行同样的战争时 我收到下面发布的错误 有趣的是 如果我将 WEB IN
  • 我们如何使用 thymeleaf 绑定对象列表的列表

    我有一个表单 用户可以在其中添加任意数量的内容表对象这也可以包含他想要的列对象 就像在 SQL 中构建表一样 我尝试了下面的代码 但没有任何效果 并且当我尝试绑定两个列表时 表单不再出现 控制器 ModelAttribute page pu
  • Spring Data Rest 多对多 POST

    首先 让我解释一下我的用例 这非常简单 有一个用户实体和一个服务实体 我使用 UserService 作为连接实体 连接表 在用户和服务之间建立多对多关联最初 会有一些用户集和一些服务集 用户可以在任何时间点订阅任何服务 在这种情况下 将向
  • 在 Java 中通过 D-Bus MPRIS 访问 Clementine 实例

    我使用 Clementine 作为音乐播放器 它可以通过 D Bus 命令进行控制 在命令行上 使用 qdbus 我可以 Start Stop 暂停播放器 强制它跳过播放列表中的歌曲 检查播放列表的长度 检查播放列表中当前播放的曲目及其元数
  • 什么是 Java2D 处理程序线程?

    我创建了一个使用 Hibernate 的示例 java 应用程序 当我进行线程转储时 我观察到一个名为 Java2D Disposer 的奇怪线程 有人能告诉我该线程的功能吗 AWT 系统中的某些实体需要最终确定以释放资源 最突出的例子是j

随机推荐

  • 如何用py2exe打包psutil?

    该应用程序在我的开发win8环境中运行良好 但是当它与py2exe打包并在生产机器上运行时 它抛出异常 无法在动态链接库 ntdll dll 中定位过程入口点 RtlIdnToAscii 日志文件的详细内容是 Traceback most
  • 使用文本字段编辑货币

    如何获得 JavaFX TextField 来编辑存储的没有派系数字 例如长整型 的货币 使用数据绑定 TextFormatter 和其他 javaFX 东西 目标应该是 Bo 拥有 LongProperty 货币价值以分为单位 可编辑的文
  • 禁用(删除)WooCommerce 4.3.x 中的营销菜单选项

    自 WooCommerce 发布以来4 3 x 之前修复了删除适用于的 营销 菜单选项的问题4 1 x不再起作用了 我想知道是否有人知道如何删除它4 3 x 我已经尝试了所有这些但没有成功 1 add filter woocommerce
  • C++ 使用 || 检查字符是否不在字符串中不工作

    我正在开发这款游戏 要求玩家再次玩 我习惯于检查条件是否不满足然后返回 false 所以最后我可以简单地添加 return true 这也有助于嵌套 如果我以相反的方式这样做 它会起作用 bool AskToPlayAgain cout l
  • 在 writeln 函数中写入撇号 - Pascal

    如何使用 Pascal 打印撇号writeln功能 例子 writeln My brother s book 行不通 因为s book超出了 写入 功能 因此编译器返回错误 Fatal Syntax error expected but i
  • 有人可以用最通俗的语言向我解释一下如何使用 EventArgs 吗?

    我知道他们和代表有关系 我已经尝试过 但我仍然不明白如何使用它们 我对事件处理程序了解一些 但我真正想知道的是如何使用大多数方法中的普通旧事件参数 下面的例子 void Page Load object sender EventArgs e
  • 使用 PHP Unit 测试特殊字符

    我正在使用 PHPUnit 和类从 Symfony2 测试我的控制器WebTestCase return self client gt request POST withdraw array amount gt 130 array arra
  • 单元测试中的 Xcode 内存泄漏检测

    运行单元测试时是否可以测试是否发生内存泄漏 我想检查我的内存管理是否正确处理 Thanks 您可以尝试使用泄漏检测仪器在仪器下运行单元测试 但是 如果您使用 OCUnit 则这仅适用于应用程序 捆绑包 测试 如果您碰巧使用其他东西 请告诉我
  • 使用Rails 5,如何使FriendlyId附加一个-“count+1”来重复slugs而不是UUID?

    显然 FriendlyId 已经更改了之前将数字序列附加到重复 slugs 的默认方法 这就是我想要的 现在使用 UUID Previous versions of FriendlyId appended a numeric sequenc
  • SwiftUI 通用拉动刷新视图

    我有一个 CustomScrollView 它包装了我的 HomeView 如果你下拉它会获取新数据 它工作正常 但问题是我想在多个视图中重用它 并且我不想为每个视图创建它的副本 我尝试过这样做var rootView View但它抛出一个
  • wordpress: previous_post_link() / next_post_link() 占位符

    我遇到了问题previous post link and next post link 功能 当没有之前的帖子时 该函数previous post link 不显示链接 同样对于next post link 和最后一篇文章 我想要一个占位符
  • 如何使用javascript将图像转换为二进制格式[重复]

    这个问题在这里已经有答案了 通过图像 url 将图像转换为二进制 我的网址如下 D MyProject Image image jpg 我想转换这个 image jpg 使用 JavaScript 转换为二进制格式字符串 在线找到了一个二进
  • 字体大小 1px 与 rem 单位一起使用

    我正在追求一种可以随着缩放而很好地缩放的布局 用户按 ctr cmd plus 为此 我需要尺寸与字体大小一起缩放 使用 em 单位太棘手 所以我正在考虑使用 rem 并复制旧 ie 的每个维度属性 我最初的想法是将 html 元素上的 f
  • 代号一:将图像保存到存储并创建小圆形预览

    我目前的图像有问题 1 我无法将图像保存到存储 因为不支持将其直接存储到存储 我希望用户能够用相机拍照 然后创建的照片必须保存在某个地方 以便我稍后可以再次检索它 你能告诉我怎么做吗 a 保存图像 b 如何检索它 我在 Stackoverf
  • 尝试在 laravel 5.5 中获取非对象的属性

    我试图显示我的变量值以查看页面 但它显示尝试获取非对象属性的错误 请有人帮助我 这是我的控制器 public function myAffiliates Request request if user id Sentinel getUser
  • C中字符数组输入输出的问题

    我编写了以下代码来读取字符数组并打印它 include
  • bcdiv 使用带有科学记数法的非常小的浮点导致“除以零”错误

    使用 bcdiv 我无法使用科学记数法除以小浮点数 工作代码 bcscale 30 a 1 b 0 00000001 result bcdiv a b var dump result 结果是 字符串 20 100000000 0000000
  • 在 google-apps-script 中,有没有办法知道谷歌驱动器的文件夹是否为空?

    我想编写一个谷歌应用程序脚本来将每个空文件夹放入我的谷歌驱动器中 我应该使用哪种方法 属性来检查当前文件夹 我可以写一个循环 是否真的是空的 id est没有任何文件或任何其他里面嵌套文件夹 而且 如果您删除了链接有某些文件的文件夹 会发生
  • 具有关联对象的多对多以及定义的所有关系在删除时崩溃

    当具有描述的所有关系的成熟的多对多时 删除两个主要对象之一会崩溃 描述 Car car ownerships car 汽车保有量 person car ownerships Person Car people cars Person Pro
  • Shiro 使用 sessionId 或用户名+密码进行身份验证

    我在 Java 身份验证框架和身份验证工作流程方面没有太多经验 只有一些理论知识 因此出于教育目的 我尝试为我的 HTTP 应用程序创建这种类型的身份验证 客户端将登录名 密码发布到 login Shiro 通过给定的凭据登录用户 服务器返