我在Java身份验证框架和身份验证工作流程方面没有太多经验(只有一些理论知识),所以出于教育目的,我正在尝试为我的HTTP应用程序创建这种类型的身份验证:
/login
。 sessionId
。/myresource?sessionId=1234567
。sessionId
登录主题。然后,服务器执行获取/myresource
的常规工作流程(使用Shiro管理方法级访问权限)。基本上我有这些问题:
提前致谢。
答案 0 :(得分:33)
我想我不需要HTTP会话也不需要Servlet会话。 Shiro拥有自己的会话管理器,足以满足我的需求。我错了吗?
不,你是对的。这就是Shiro很棒的原因。来自documentation:
Shiro的Session支持比这两个[Web容器或EJB有状态会话Bean]机制更容易使用和管理,并且无论容器如何,它都可以在任何应用程序中使用。
e.g。
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();
在进行此类身份验证之前是否还需要了解其他事项?
是
<强>更新强>
关于该主题认证部分 - 它是否会使新创建的主题成为当前经过身份验证的主题?如果没有,我如何使其成为“当前”主题?
如果你在谈论new Subject.Builder().sessionId(sessionId).buildSubject()
,那就不会。而且我不知道如何将它设置为线程的 currentUser 。 Shiro的JavaDoc说,
[这种方式]返回主题实例不会自动绑定到应用程序(线程)以供进一步使用。也就是说,SecurityUtils.getSubject()不会自动返回与构建器返回的实例相同的实例。如果需要,框架开发人员可以绑定构建的Subject以继续使用。
因此,您可以在当前线程中如何绑定主题或进一步使用。
如果您担心SecurityUtils.getSubject();
如何工作,那么,在Web容器上下文中,它使用简单的cookie来存储会话数据。当您的请求通过Shiro过滤器时,它会附加当前主题以请求其生命周期(当前线程)。当您getSubject()
时,它只是从请求中获取Subject
。我找到了一个有趣的帖子here。
关于nonce部分:如果他给我发送某种哈希而不是他的sessionId - 我将无法解码它以获得真正的sessionId(用它来授权他)。我在这里遗漏了什么吗?
Nonce部分 - 这是颈部疼痛。现在重新思考,我认为做NONCE只是矫枉过正。让我解释一下,无论如何,
用户首次使用其用户名和密码登录。在客户端设置userid
,nonce
(例如,UUID)和HASH(sessionID+nonce)
,将其称为hash1。说,在cookie中。将此nonce
存储在服务器端,可以位于数据库中,也可以存储在地图中user_id <--> nonce,session_id
在后续请求中,请确保您传回userid
,nonce
和HASH
。
在服务器端,您要做的第一件事就是验证请求。根据客户端发送的sessionId
获取存储在hashmap或DB中的nonce
和user_id
。创建哈希,HASH(sessionId_from_db + nonce_from_db),将其称为hash2。
现在,如果hash1与hash2匹配,您可以验证请求,并且由于您已在服务器端存储了当前的sessionId,因此您可以使用它。请求完成后,在cookie和服务器端设置新的nonce。
如果你经历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