我有一个Spring-mvc应用程序,并且在每个控制器中我向SessionAttributes添加一个表单,以便在保存,删除或执行另一个get请求时保留属性。当我尝试在另一个浏览器选项卡中打开某个链接并尝试提交第一个链接时,会出现主要问题。我尝试了this解决方案但是当我进行重定向时(在控制器中我只有1个返回视图而其他方法进行重定向)它会创建一个新的会话而无法找到前一个会话。
我还有另外一个关于使用春季会议的问题的问题,质疑它here,但我不知道这是否会奏效。
答案 0 :(得分:5)
您是否看过Spring的RedirectAttributes?我自己还没有用过,但听起来应该按照自己的意愿行事。 RedirectAttributes通常用于GET /重定向/ POST模式,而at least one user似乎认为以这种方式传递会话属性是不好的做法,但是他们继续提到它似乎并不是一个更好的解决方案。无论如何,文档中显示的示例:
@RequestMapping(value = "/accounts", method = RequestMethod.POST)
public String handle(Account account, BindingResult result, RedirectAttributes redirectAttrs) {
if (result.hasErrors()) {
return "accounts/new";
}
// Save account ...
redirectAttrs.addAttribute("id", account.getId()).addFlashAttribute("message", "Account created!");
return "redirect:/accounts/{id}";
}
会添加"消息"属性为RedirectModel,如果您的控制器重定向,那么处理重定向的任何方法都可以访问该数据,如下所示:
@RequestMapping(value = "/accounts", method = RequestMethod.POST)
public String handleRedirect(Model model) {
String message = (String) model.asMap().get("message");
return new ModelAndView();
}
因此,应该可以以相同的方式添加会话属性。另一个参考here。
修改强> 我正在查看Spring文档,他们还提到了这个注释@SessionAttributes。来自文档:
类型级@SessionAttributes注释声明特定处理程序使用的会话属性。这通常会列出模型属性的名称或模型属性的类型,这些属性应该透明地存储在会话或某些会话存储中,作为后续请求之间的表单支持bean。
这可能是你需要的吗?
答案 1 :(得分:3)
这是我们提出的解决方案,与Spring无关:
在应用程序的每个html表单上,您必须包含一个隐藏字段。让我们将此字段命名为CSRF_TOKEN。该字段应具有随机生成的值。该值放在会话和隐藏字段中。会话属性的名称是SESSION_CSRF_TOKEN
将表单提交给服务器时,检查会话中的值(SESSION_CSRF_TOKEN)是否等于HTTP请求参数CSRF_TOKEN中发送的值。如果没有,您将显示某种错误消息,并停止处理。如果他们是平等的,继续。
如果用户打开新选项卡或复制选项卡,服务器将重新呈现页面,并将生成新的CSRF_TOKEN。因此,用户只能从新打开的标签中提交表单,而不能从原始标签中提交。
此解决方案提供了额外的奖励:它可以防范CSRF attacks。