我想我不需要 HTTP 会话或 Servlet 会话。 Shiro 有自己的会话管理器,足以满足我的需求。我错了吗?
不,你是对的。这就是Shiro厉害的原因。来自documentation:
Shiro 的 Session 支持比这两种 [web 容器或 EJB Stateful Session Beans] 机制中的任何一种都更易于使用和管理,并且它适用于任何应用程序,无论容器如何。
例如
Subject currentUser = SecurityUtils.getSubject();
Session session = currentUser.getSession();
session.setAttribute( "someKey", someValue);
引用the doc:getSession calls work in any application, even non-web applications
给客户端真正的 sessionId 是一种好习惯,还是应该发送某种 sessionToken(在服务器端解析为 sessionId)?
发送纯 sessionId 是个坏主意。特别是,如果您通过未加密的网络发送数据。要么使用 HTTPS 之类的东西,要么使用 NONCE 行。
并且,附带说明,如果通过 http/s POST 数据而不是在 URL 中。
如何使用 sessionId(客户端应存储在本地)登录主题?
您的意思是,一旦您拥有会话 ID,您如何验证主题?你可以简单地,
来自文档,
Subject requestSubject = new Subject.Builder().sessionId(sessionId).buildSubject();
在进行此类身份验证之前,我还需要了解其他任何事情吗?
是的。
- 阅读Shiro's Session Management
- 了解MITM Attack
- 关于HTTPS和SSL
- 一些关于哈希函数this,Apache Commons DigestUtils,可能是this
更新
关于主题身份验证部分 - 它会使新创建的主题成为当前经过身份验证的主题吗?如果不是,我如何使它成为“当前”主题?
如果您在谈论new Subject.Builder().sessionId(sessionId).buildSubject(),则不会。而且我不知道如何将其设置为线程的 currentUser。 Shiro 的JavaDoc 说,
[这种方式] 返回的 Subject 实例不会自动绑定到应用程序(线程)以供进一步使用。也就是说,SecurityUtils.getSubject() 不会自动返回与构建器返回的实例相同的实例。如果需要,框架开发人员可以绑定构建的主题以供继续使用。
所以,如何在当前线程中绑定主题或进一步使用取决于您。
如果您担心SecurityUtils.getSubject(); thingy 是如何工作的,那么,在 web 容器上下文中,它使用简单的 cookie 来存储您的会话数据。当您的请求通过 Shiro 过滤器时,它会将当前主题附加到其生命周期(当前线程)的请求中。当您作为getSubject() 时,它只是从请求中获取Subject。我发现了一个有趣的线程here。
关于 nonce 部分:如果他向我发送某种哈希而不是他的 sessionId - 我将无法对其进行解码以获得真正的 sessionId(以授权他)。我在这里遗漏了什么吗?
Nonce 部分 - 脖子疼。现在重新考虑,我认为做 NONCE 只是矫枉过正。让我解释一下,无论如何,
用户第一次使用他的用户名和密码登录。在客户端设置userid、nonce(比如UUID)和HASH(sessionID+nonce),称之为hash1。说,在饼干里。将此nonce 存储在服务器端,可以在数据库或地图中作为user_id <--> nonce,session_id
在后续请求中,确保您回传userid、nonce 和HASH。
在服务器端,您要做的第一件事是验证请求。根据客户端发送的user_id,获取存储在哈希图或数据库中的sessionId 和nonce。创建一个哈希,HASH(sessionId_from_db+nonce_from_db),称之为hash2。
现在,如果 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