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

时间:2011-12-14 07:54:17

标签: java authentication shiro

我在Java身份验证框架和身份验证工作流程方面没有太多经验(只有一些理论知识),所以出于教育目的,我正在尝试为我的HTTP应用程序创建这种类型的身份验证:

  1. 客户端将登录名+密码发布到/login
  2. Shiro通过给定的凭据登录用户。服务器返回客户端sessionId
  3. 客户请求某种资源/myresource?sessionId=1234567
  4. Shiro按给定的sessionId登录主题。然后,服务器执行获取/myresource的常规工作流程(使用Shiro管理方法级访问权限)。
  5. 基本上我有这些问题:

    1. 我想我不需要HTTP会话也不需要Servlet会话。 Shiro拥有自己的会话管理器,足以满足我的需求。我错了吗?
    2. 向客户端提供真正的sessionId或者我应该发送某种sessionToken(在服务器端解析为sessionId)是不错的做法?
    3. 如何使用sessionId(客户端应在本地存储)登录主题?
    4. 在进行此类身份验证之前,还有其他需要了解的事情吗?
    5. 提前致谢。

1 个答案:

答案 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 docgetSession 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();

在进行此类身份验证之前是否还需要了解其他事项?

  1. 阅读Shiro's Session Management
  2. 精益约MITM Attack
  3. 关于HTTPSSSL
  4. 部分关于哈希函数thisApache Commons DigestUtils,可能是this

  5. <强>更新

    关于该主题认证部分 - 它是否会使新创建的主题成为当前经过身份验证的主题?如果没有,我如何使其成为“当前”主题?

    如果你在谈论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只是矫枉过正。让我解释一下,无论如何,

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

    2. 在后续请求中,请确保您传回useridnonceHASH

    3. 在服务器端,您要做的第一件事就是验证请求。根据客户端发送的sessionId获取存储在hashmap或DB中的nonceuser_id。创建哈希,HASH(sessionId_from_db + nonce_from_db),将其称为hash2。

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

    5. 如果你经历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