使用存储在会话中的用户ID进行身份验证 - 安全风险/不良做法?

时间:2012-10-18 14:59:36

标签: java security glassfish jersey

我正在为非关键数据开发一个小型REST-web服务,主要由智能手机应用程序访问。为了限制用户对其个人数据的访问(授权不需要组或角色),我需要实现某种基本的身份验证。

由于服务将通过HTTP访问,因此使用HTTP-Authentification似乎不是一个好主意,因为用户名和密码将在每个请求上以明文形式发送,并且需要存储在客户端设备上。

因此,我的想法是通过以下方式实现身份验证:

  1. 用户使用我的webservice的登录方法通过他们的用户名/密码登录
  2. 此方法检查用户名/密码组合的有效性(基于包含盐渍和散列密码的数据库)
  3. 如果登录成功,则用户的ID(数据库表的主键)作为属性存储在会话中
  4. 在以下请求中,此属性用于验证用户
  5. 在代码中,我的登录方法如下所示:

    User user = this.authentificate(username, password);
    HttpSession session = request.getSession(true);
    if (user != null)
       session.setAttribute("UserId", user.getId());
    else
       session.invalidate();
    

    之后,我将能够根据会话验证用户身份:

    int userId = (int) request.getSession().getAttribute("UserId");
    User currentUser = getUserById(userId);
    

    这种方法可以被视为“安全”(不容易进行会话劫持 - 据我所知https://stackoverflow.com/a/5838191/232175,属性的值不会离开服务器)?
    是否有任何缺点或替代方案?

1 个答案:

答案 0 :(得分:2)

关于在会话中存储用户ID,我认为没问题,但是你有另一个问题。

首先,我假设登录方法将通过HTTPS,否则用户名和密码将以明文形式发送到登录方法,您将回到以前遇到的同样问题。

其次,如果登录方法是通过HTTPS,那么会话cookie将是一个HTTPS cookie,所有其他API调用也需要通过HTTPS。如果后续调用是通过HTTP进行的,则会获得新的会话cookie,并且该会话中的用户ID将不可用。

如果您真的想要在没有HTTPS的情况下进行安全身份验证,则需要使用共享密钥签名方案(例如HMAC)或非对称签名系统(如RSA)来让客户端签署请求,然后验证服务器端的签名请求。