一尘不染

使用sessionId或username + password进行Shiro身份验证

java

一般而言,我在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(客户端应将其存储在本地)登录Subject?
  4. 在进行这种身份验证之前,我还有其他需要知道的事情吗?

提前致谢。


阅读 528

收藏
2020-12-03

共1个答案

一尘不染

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

不,你是对的。这就是Shiro很棒的原因。从文档

Shiro的Session支持比这两种[Web容器或EJB状态会话Bean]机制中的任何一种都更易于使用和管理,并且在任何应用程序中都可以使用它,而与容器无关。

例如

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

引用文档getSession calls work in any application, even non-web applications

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

发送普通的sessionId是一个坏主意。特别是,如果您要通过未加密的网络发送数据。使用HTTPS之类的东西 或使用
NONCE

另外,请注意,如果通过http / s POST数据而不是URL中的数据。

如何使用sessionId(客户端应将其存储在本地)登录Subject?

您的意思是,一旦获得会话ID,如何才能对主题进行身份验证?您可以简单地从文档中

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

在进行这种身份验证之前,我还有其他需要知道的事情吗?

是。

  1. 阅读Shiro的会话管理
  2. 精通MITM攻击
  3. 关于HTTPSSSL
  4. Hash上的某些功能可以这样Apache Commons DigestUtils可能是这个

更新

关于该主题认证部分-它将新创建的主题变成当前已认证的主题吗? 如果不是,我如何使其成为“当前”主题?

如果您在谈论new Subject.Builder().sessionId(sessionId).buildSubject(),它不会。而且我不知道如何将其设置为该线程的
currentUser
。Shiro的JavaDoc说,

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

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

如果您担心事情的SecurityUtils.getSubject();工作原理,那么在Web容器上下文中,它使用简单的cookie来存储您的会话数据。当您的请求通过Shiro过滤器时,它会将当前主题附加到请求的生命周期(当前线程)。而当您getSubject()只是Subject从请求中获取时。我在这里找到了一个有趣的话题。

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

随机部分-脖子上的疼痛。现在重新考虑,我认为做NONCE只是过分杀伤力。反正让我解释一些

  1. 用户首次使用其用户名和密码登录。在客户端设置useridnonce(例如,UUID)和HASH(sessionID+nonce),将其称为hash1。在Cookie中说。将此存储nonce在服务器端,可能在数据库中或在Map中user_id <--> nonce,session_id

  2. 根据后续要求,请确保您传回useridnonce以及HASH

  3. 在服务器端,您要做的第一件事是验证请求。获取sessionIdnonce根据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

2020-12-03