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

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

问题描述:

我在Java身份验证框架和身份验证工作流方面没有太多经验(只有一些理论知识),所以出于教育目的,我试图为我的HTTP创建此类身份验证应用:使用sessionId或用户名+密码的Shiro身份验证

  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拥有自己的会话管理器,足以满足我的需求。我错了吗?

不,你说得对。这就是Shiro真棒的原因。从documentation

四郎的会话的支持更简单使用,也比这两种[Web容器或EJB有状态会话Bean]机制的管理,它可在任何应用程序,无论容器。

例如,

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,你怎么能认证主题?你可以简单地, 从DOC,

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

是否还有其他的事情,我需要做这种身份验证之前知道吗?

是的。

  1. 阅读Shiro's Session Management
  2. 精益约MITM Attack
  3. 关于HTTPSSSL
  4. 一些关于Hash函数thisApache Commons DigestUtils并且可以this

更新

关于该主题验证部分 - 它是否会使新创建的主题成为当前验证的主题?如果不是,我该如何使它成为“当前”主题?

如果你正在谈论new Subject.Builder().sessionId(sessionId).buildSubject(),它不会。我不知道如何将它设置为当前用户的线程。 Shiro的JavaDoc说,

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

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

如果您担心的是,在web容器上下文中,它使用简单的cookie来存储会话数据。当您通过Shiro过滤器发出请求时,它会附加当前主题以请求其生命周期(当前线程)。当你作为getSubject()它只是从请求Subject。我发现了一个有趣的线程here

关于nonce部分:如果他向我发送某种散列而不是他的sessionId - 我将无法解码它以获取真正的sessionId(以授权他)。我在这里错过了什么吗?

Nonce部分 - 这是一个痛苦的脖子。现在反思,我认为做NONCE只是矫枉过正。让我解释一些,反正,

  1. 用户第一次用他的用户名和密码登录。设置userid,nonce(比如UUID)和HASH(sessionID+nonce),在客户端称它为hash1。说,在cookie中。存储这个nonce在服务器端,可在DB或在地图作为user_id <--> nonce,session_id

  2. 在随后的请求,请确保您回传useridnonceHASH

  3. 在服务器端,您要做的第一件事是验证请求。根据客户端发送的user_id获取存储在散列表或数据库中的sessionIdnonce。创建一个散列HASH(sessionId_from_db + nonce_from_db),将其称为hash2。

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

如果你经历了1 - 4,你会意识到你不会需要Shiro进行身份验证。 (: 所以,我以我的背单词,杜撰并不在这种情况下,除非你太任性有关安全性的超性能应用

为什么MITM攻击都与我我的客户(JavaScript的Ajax代码)取?所以我不认为我应该关心MITM

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

+0

感谢您的详细解答。关于该主题验证部分 - 它是否会使新创建的“Subject”成为当前验证的主题?如果不是,我该如何使它成为“当前”主题? – bezmax 2011-12-16 09:45:07