我正在开发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条目(即使我我知道在如此短的时间内发生的可能性极小。此外,我对使用JSESSIONID(用户)的bean有什么疑问,如果由于某种原因服务器在bean(以及例如数据库操作)完成之前丢弃JSESSIONID(因为我可能会冒新的风险)类似的JSESSIONID是由服务器为另一个用户创建的,然后可能与JSESSIONID和其他bean正在服务的用户混在一起)!
我希望有深入了解问题的人会写出什么是最佳做法以及100%安全的方法(我也认为大多数使用JSF webapp服务器的人都会遇到这个问题因此会有所帮助让其他人知道问题的最佳解决方案)。感谢。
答案 0 :(得分:1)
我认为你在这里存在误解。变量驻留在一个托管bean中,然后“传递”到另一个托管bean这一事实并不意味着实际在物理介质上移动。所有viewcoped bean都在同一存储区域中实现(我相信它是UIViewRoot
对象)。 在此级别,这些实体之间存在隐式Boundary of Trust ,除非两个bean之间存在用户可访问的移动(可能是客户端变量,URL参数或其他HTTP工件),不要看风险。
这意味着,无论变量所在的特定@ViewScoped
bean是什么,它们都会暴露于同一个漏洞(如果有的话)。在bean之间“传递”变量不会带来任何新的风险。除非您在用户的任何位置显示值(可能在URL或隐藏的HTML表单元素中),否则@ViewScoped
对象本身不会引入新的风险(不正确地使用范围是一个不同的事情)。
最终,如果你仍然关注它,只需在将变量交给另一个实体之前加密你的东西(考虑开销)