【发布时间】:2014-10-29 01:19:15
【问题描述】:
我正在开发一个 webprojekt,为了最大程度地减少会话膨胀,我主要使用 ViewScoped bean。但后来我面临的问题是我需要在我的 bean 之间传输客户端用户名和密码(以访问数据库等)。
我已经创建了一个系统,我使用 flash 对象在 bean 之间传输用户名和密码,例如:
public String gotoNextView() {
ExternalContext external = FacesContext.getCurrentInstance().getExternalContext();
external.getFlash().put("user_name", (String) FacesContext.getCurrentInstance().getExternalContext().getFlash().get("user_name"));
external.getFlash().put("password", (String) FacesContext.getCurrentInstance().getExternalContext().getFlash().get("password"));
return "/../../next_view.xhtml";
}
但我担心黑客是否有可能以某种方式操纵客户端,从而欺骗服务器以暴露 Flash 对象!
我正在考虑的另一个解决方案是将 Web 应用程序的所有 JSESSIONID 作为键存储在 Map 中,并将用户名和密码作为值。为了完成这项工作,我想我需要在用户会话结束或过期时调用一个回调方法,以便我可以从 Map 中删除相关的 JSESSIONID。但是该解决方案的问题在于,我怀疑实现回调的最佳方法是什么,以便我可以 100% 确定在服务器创建新的类似 JSESSIONID 之前删除 Map 条目(即使我知道在这么短的时间内发生的可能性非常小)。此外,如果由于某种原因服务器在 bean(以及例如数据库操作)完成之前丢弃了 JSESSIONID(因为我可能会冒新类似的 JSESSIONID 是由服务器为另一个用户创建的,然后可能会与 JSESSIONID 和另一个 bean 正在服务的用户混合在一起)!
我希望对这个问题有深入了解的人会写下什么是最佳实践和 100% 安全的方法(我也认为大多数使用 JSF webapp 服务器的人都会遇到这个问题,因此它会有所帮助让其他人知道问题的最佳解决方案)。谢谢。
【问题讨论】:
-
您不应该将密码存储在任何地方,甚至不在会话或请求范围内。应用程序应该以自己的身份访问数据库,而不是以用户身份访问数据库。
-
是否有您不想为用户名使用会话属性的原因?在会话中仅保留该信息将使您的会话保持较小,并且您可以避免所有问题,不是吗?
-
@Martin Frey:您是在谈论使用 HttpServletRequest 和 HttpServletResposne 对象吗?我只是不知道该怎么做!
-
@EJP 我认为我需要将密码存储在某个地方以验证它们!为什么我不应该把它们储存在豆子里?是否有可能侵入豆类? “应用程序应该以自身身份访问数据库,而不是以用户身份访问数据库”到底是什么意思?
-
密码只能用于身份验证,然后“丢弃”。一旦用户通过身份验证,该用户的整个会话就计算在内,因此不再需要密码。至于
loggedInUser:如果你已经使用它,你可以简单地依赖 Spring Security。 (否则看一下;))-SecurityContextHolder.getContext().getAuthentication().getName();,然后调用您的 dao 从数据库中获取User,如果您需要更多。
标签: spring jsf session jsf-2 flash-scope