简体   繁体   English

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

[英]Shiro authentication with sessionId or username+password

I do not have much experience in Java authentication frameworks and authentication workflow in general (only some theoretical knowledge), so for educational purposes I'm trying to create this type of authentication for my HTTP application: 我在Java身份验证框架和身份验证工作流程方面没有太多经验(只有一些理论知识),所以出于教育目的,我正在尝试为我的HTTP应用程序创建这种类型的身份验证:

  1. Client Posts login+password to /login . 客户端将登录名+密码发布到/login
  2. Shiro logs in the user by given credentials. Shiro通过给定的凭据登录用户。 Server returns client his sessionId . 服务器返回客户端他的sessionId
  3. Client requests some kind of resource /myresource?sessionId=1234567 . 客户端请求某种资源/myresource?sessionId=1234567
  4. Shiro logs in the Subject by given sessionId . Shiro通过给定的sessionId登录主题。 Then server does the regular workflow of getting the /myresource (with Shiro managing method-level access rights). 然后,服务器执行获取/myresource的常规工作流程(使用Shiro管理方法级访问权限)。

Basically I have these questions: 基本上我有这些问题:

  1. I guess I have no need for HTTP sessions nor Servlet sessions. 我想我不需要HTTP会话也不需要Servlet会话。 Shiro has it's own session manager which is enough for my needs. Shiro拥有自己的会话管理器,足以满足我的需求。 Am I wrong? 我错了吗?
  2. Is it good practice to give client the real sessionId or should I send some kind of sessionToken (which is resolved to sessionId on server side)? 给客户端提供真正的sessionId或者我应该发送某种sessionToken(在服务器端解析为sessionId)是一种好的做法吗?
  3. How do I login the Subject using sessionId (which the client should store locally)? 如何使用sessionId(客户端应在本地存储)登录主题?
  4. Are there any other things I need to know before doing this kind of authentication? 在进行这种身份验证之前还有其他我需要知道的事情吗?

Thanks in advance. 提前致谢。

I guess I have no need for HTTP sessions nor Servlet sessions. 我想我不需要HTTP会话也不需要Servlet会话。 Shiro has it's own session manager which is enough for my needs. Shiro拥有自己的会话管理器,足以满足我的需求。 Am I wrong? 我错了吗?

No, you're right. 不,你说得对。 That's why Shiro is awesome. 这就是Shiro很棒的原因。 From documentation : 来自文档

Shiro's Session support is much simpler to use and manage than either of these two [web container or EJB Stateful Session Beans] mechanisms, and it is available in any application, regardless of container. 与这两种[Web容器或EJB有状态会话Bean]机制中的任何一种相比,Shiro的Session支持更易于使用和管理,并且无论容器如何,它都可以在任何应用程序中使用。

eg 例如

Subject currentUser = SecurityUtils.getSubject();    
Session session = currentUser.getSession();
session.setAttribute( "someKey", someValue);

quoting from the doc : getSession calls work in any application, even non-web applications 引用docgetSession calls work in any application, even non-web applications

Is it good practice to give client the real sessionId or should I send some kind of sessionToken (which is resolved to sessionId on server side)? 给客户端提供真正的sessionId或者我应该发送某种sessionToken(在服务器端解析为sessionId)是一种好的做法吗?

It is a bad idea to send plain sessionId. 发送简单的sessionId是个坏主意。 Specially, if you're sending data over unencrypted network. 特别是,如果您通过未加密的网络发送数据。 Either use something like HTTPS or use something line NONCE . 使用类似HTTPS的东西 或使用 NONCE

And, a side note, if over http/s POST data instead of having it in URL. 并且,附注,如果超过http / s POST数据而不是在URL中。

How do I login the Subject using sessionId (which the client should store locally)? 如何使用sessionId(客户端应在本地存储)登录主题?

You meant how could you authenticate the subject once you have session ID? 您的意思是,如果您有会话ID,您如何验证主题? You can simply, from the doc, 你可以简单地从文档中

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

Are there any other things I need to know before doing this kind of authentication? 在进行这种身份验证之前还有其他我需要知道的事情吗?

Yes. 是。

  1. Read Shiro's Session Management 阅读Shiro的会话管理
  2. Lean about MITM Attack 关于MITM攻击的精益
  3. About HTTPS and SSL 关于HTTPSSSL
  4. Some on Hash functions this , Apache Commons DigestUtils and may be this 一些对Hash函数阿帕奇百科全书DigestUtils ,可以是这个

Updates 更新

About that subject authentication part - will it make the newly created Subject the currently authenticated subject? 关于该主题认证部分 - 它是否会使新创建的主题成为当前认证的主题? If not, how do I make it the "current" subject? 如果没有,我如何使其成为“当前”主题?

If you're talking about new Subject.Builder().sessionId(sessionId).buildSubject() , it will not. 如果你在谈论new Subject.Builder().sessionId(sessionId).buildSubject() ,它就不会。 And I do not know how to set it as currentUser for the thread. 我不知道如何将它设置为线程的currentUser Shiro's JavaDoc says, Shiro的JavaDoc说,

[this way] returned Subject instance is not automatically bound to the application (thread) for further use. [这种方式]返回主题实例不会自动绑定到应用程序(线程)以供进一步使用。 That is, SecurityUtils.getSubject() will not automatically return the same instance as what is returned by the builder. 也就是说,SecurityUtils.getSubject()不会自动返回与构建器返回的实例相同的实例。 It is up to the framework developer to bind the built Subject for continued use if desired. 如果需要,框架开发人员可以绑定构建的Subject以继续使用。

so, it's upto you how you bind the subject in current thread or further use. 所以,你可以在当前线程中如何绑定主题或进一步使用它。

If you were worried about how SecurityUtils.getSubject(); 如果你担心SecurityUtils.getSubject(); thingy works, well, in web-container context, it uses simple cookie to store your session-data. thingy工作,好吧,在Web容器上下文中,它使用简单的cookie来存储会话数据。 When your request comes through Shiro filter, it attached the current subject to request for it's life cycle (current thread). 当您的请求通过Shiro过滤器时,它会附加当前主题以请求其生命周期(当前线程)。 And when you as getSubject() it simply gets the Subject from request. 当你作为getSubject()它只是从请求获取Subject I found an interesting thread here . 我在这里发现了一个有趣的线索

about nonce part: If he sends me some kind of hash instead of his sessionId - I won't be able to decode it to get real sessionId (to authorize him with that). 关于nonce部分:如果他给我发送某种哈希而不是他的sessionId - 我将无法解码它以获得真正的sessionId(用它来授权他)。 Am I missing something here? 我在这里错过了什么吗?

Nonce part -- it's a pain in the neck. Nonce部分 - 这是颈部疼痛。 Now rethinking, I think doing NONCE is just overkill. 现在重新思考,我认为做NONCE只是矫枉过正。 Let me explain some, anyways, 让我解释一下,无论如何,

  1. User logs in first time with his user-name and password. 用户首次使用其用户名和密码登录。 Set userid , nonce (say, UUID), and HASH(sessionID+nonce) ,call it hash1, on client side. 在客户端设置useridnonce (比如说,UUID)和HASH(sessionID+nonce) ,称之为hash1。 Say, in cookie. 说,在cookie中。 Store this nonce on server side, may be in DB or in a Map as user_id <--> nonce,session_id 将此nonce存储在服务器端,可以在DB或Map中作为user_id <--> nonce,session_id

  2. On subsequent request, make sure you passback userid , nonce and the HASH . 在后续请求中,请确保您传回useridnonceHASH

  3. On server side, the first thing you will do is validate the request. 在服务器端,您要做的第一件事就是验证请求。 Get the sessionId and nonce stored in the hashmap or DB based on user_id that was sent by the client. 根据客户端发送的user_id获取存储在hashmap或DB中的sessionIdnonce Create a hash, HASH(sessionId_from_db+nonce_from_db), call it hash2. 创建哈希,HASH(sessionId_from_db + nonce_from_db),将其称为hash2。

  4. Now, if hash1 matches hash2, you can validate the request and since you have stored current sessionId on server side, you can use it. 现在,如果hash1与hash2匹配,则可以验证请求,并且由于您已在服务器端存储了当前的sessionId,因此可以使用它。 On request completion, set new nonce in cookie and on server side. 请求完成后,在cookie和服务器端设置新的nonce。

If you go through 1 -- 4, you'll realize you wouldn't require Shiro for authentication. 如果你经历1 - 4,你会发现你不需要Shiro进行身份验证。 (: So, I am taking my words back, NONCE is not applied in this case unless you are too freaky about security over performance. (:所以,我接受了我的回复,在这种情况下不应用NONCE,除非你对性能的安全性太过怪异。

Why do MITM attack matter to me? 为什么MITM攻击对我很重要? My client (javascript ajax code) fetches data from it's server via ajax. 我的客户端(javascript ajax代码)通过ajax从它的服务器获取数据。 So I do not think I should care about MITM in any way. 所以我认为我不应该以任何方式关心MITM。

I think it should matter to you. 我认为这对你很重要。 MITM Attack means your requests/responses are being chained via a machine (MITM) to your router. MITM攻击意味着您的请求/响应正通过计算机(MITM)链接到您的路由器。 If it's an unencrypted request, it's all plain text to the MITM. 如果这是一个未加密的请求,那么它就是MITM的全部明文。 He can see all your requests... and possibly spoof the requests and may hijack session. 他可以看到你的所有请求......并且可能欺骗请求并可能劫持会话。 let me find some example.... 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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM