我正在开发一个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(用户)的bean(因为我可能会冒着服务器为另一个用户创建新的类似JSESSIONID的风险,然后可能会与JSESSIONID和另一个bean正在服务的用户混合)!
我希望对这个问题有深刻见解的人能写下什么是最佳实践和100%安全的方法(我还认为大多数使用JSF Web应用程序服务器的人都会遇到这个问题,因此了解这个问题的最佳解决方案会对其他人有帮助)。谢谢
我认为您在这里有误解。一个变量驻留在一个托管bean中,然后被"传递"给另一个托管bean,这并不意味着在物理介质中有实际的移动。所有viewscoped bean都在同一个存储区域中实现(我相信它是UIViewRoot
对象)在这个级别上,这些实体之间有一个隐含的信任边界,除非两个bean之间有用户可访问的移动(可能是客户端变量、URL参数或其他HTTP工件),否则我看不到风险。
这意味着,无论变量位于哪个特定的@ViewScoped
bean中,它们都暴露在同一个漏洞中(如果有的话)。在bean之间"传递"变量不会引入任何新的风险。除非您在任何地方向用户显示值(可能在URL或隐藏的HTML表单元素中),否则@ViewScoped
对象本身不会带来新的风险(范围的不当使用是另一回事)。
最终,如果你仍然担心它,在将变量交给另一个实体