我正在为非关键数据开发一个小型REST-web服务,主要由智能手机应用程序访问。为了限制用户对其个人数据的访问(授权不需要组或角色),我需要实现某种基本的身份验证。
由于服务将通过HTTP访问,因此使用HTTP-Authentification似乎不是一个好主意,因为用户名和密码将在每个请求上以明文形式发送,并且需要存储在客户端设备上。
因此,我的想法是通过以下方式实现身份验证:
在代码中,我的登录方法如下所示:
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,属性的值不会离开服务器)?
是否有任何缺点或替代方案?
答案 0 :(得分:2)
关于在会话中存储用户ID,我认为没问题,但是你有另一个问题。
首先,我假设登录方法将通过HTTPS,否则用户名和密码将以明文形式发送到登录方法,您将回到以前遇到的同样问题。
其次,如果登录方法是通过HTTPS,那么会话cookie将是一个HTTPS cookie,所有其他API调用也需要通过HTTPS。如果后续调用是通过HTTP进行的,则会获得新的会话cookie,并且该会话中的用户ID将不可用。
如果您真的想要在没有HTTPS的情况下进行安全身份验证,则需要使用共享密钥签名方案(例如HMAC)或非对称签名系统(如RSA)来让客户端签署请求,然后验证服务器端的签名请求。