我想我不需要 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.
- Read Shiro 的会话管理 http://shiro.apache.org/session-management.html
- 倾斜一下中间人攻击 http://en.wikipedia.org/wiki/Man-in-the-middle_attack
- About HTTPS http://en.wikipedia.org/wiki/HTTP_Secure and SSL http://www.verisign.com/ssl/ssl-information-center/how-ssl-security-works/
- 一些关于哈希函数的内容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 实在是太过分了。无论如何,让我解释一些,
用户首次使用其用户名和密码登录。放userid
, nonce
(例如,UUID),以及HASH(sessionID+nonce)
,在客户端称之为 hash1。说,在饼干里。储存这个nonce
在服务器端,可能位于数据库或地图中user_id <--> nonce,session_id
在后续请求中,请确保回传userid
, nonce
和HASH
.
在服务器端,您要做的第一件事是验证请求。获取sessionId
and nonce
存储在 hashmap 或 DB 中基于user_id
这是客户发送的。创建一个哈希值 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 http://michael-coates.blogspot.com/2010/03/man-in-middle-attack-explained.html