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

bez*_*max 15 java authentication shiro

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

  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. 在进行这种身份验证之前还有其他我需要知道的事情吗?

提前致谢.

Nis*_*ant 34

我想我不需要HTTP会话也不需要Servlet会话.Shiro拥有自己的会话管理器,足以满足我的需求.我错了吗?

不,你说得对.这就是Shiro很棒的原因.来自文档:

Shiro的Session支持比这两个[Web容器或EJB有状态会话Bean]机制中的任何一个都更容易使用和管理,并且无论容器如何,它都可以在任何应用程序中使用.

例如

Subject currentUser = SecurityUtils.getSubject();    
Session session = currentUser.getSession();
session.setAttribute( "someKey", someValue);
Run Code Online (Sandbox Code Playgroud)

引用文件: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();
Run Code Online (Sandbox Code Playgroud)

在进行这种身份验证之前还有其他我需要知道的事情吗?

是.

  1. 阅读Shiro的会话管理
  2. 关于MITM攻击的精益
  3. 关于HTTPSSSL
  4. 一些对Hash函数,阿帕奇百科全书DigestUtils,可以是这个

更新

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

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

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

所以,你可以在当前线程中如何绑定主题或进一步使用它.

如果您担心如何SecurityUtils.getSubject();工作,那么,在Web容器上下文中,它使用简单的cookie来存储会话数据.当您的请求通过Shiro过滤器时,它会附加当前主题以请求其生命周期(当前线程).当你因为getSubject()它只是得到了Subject来自请求.我发现一个有趣的线程在这里.

关于nonce部分:如果他给我发送某种哈希而不是他的sessionId - 我将无法解码它以获得真正的sessionId(用它来授权他).我在这里错过了什么吗?

Nonce部分 - 这是颈部疼痛.现在重新思考,我认为做NONCE只是矫枉过正.让我解释一下,无论如何,

  1. 用户首次使用其用户名和密码登录.集userid,nonce(比方说,UUID),并且HASH(sessionID+nonce),把它HASH1,在客户端.说,在cookie中.将其存储nonce在服务器端,可以在DB中,也可以在Map中存储user_id <--> nonce,session_id

  2. 在后续请求中,请确保您回传userid,nonce并且HASH.

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

  4. 现在,如果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