阻止对控制器的直接调用
block a direct call to a controller
我正在使用 JAVA Spring mvc 开发网站。我有一个需要两个控制器的功能。首先,请求由 controller1 处理,controller1 使用 return new ModelAndView ("redirect:controller2.htm") 将请求重定向到 controller2。一切正常。但是,我想阻止对 controller2 的直接访问(阻止来自 url "controller2.htm" 的调用),因为 controller2 的表单需要来自 controller1.I 的数据,这是唯一的情况controller2 用于从 controller1 重定向。我想要一个没有提前 annotations.Thanks 的解决方案来帮助你。
这是代码:
控制器 1:
public class controller1 extends SimpleFormController implements Serializable {
private PersonManager pManager ;
@Override
public ModelAndView onSubmit(Object command) {
CommandPerson cmd = (CommandPerson) command;
Person p = null;
String viewName = "redirect:controller2.htm";
try {
p = pManager.getPersonbyID(cmd.getID());
} catch (EmptyResultDataAccessException ex) {
viewName="NosuchPerson";
}
ModelAndView mav = new ModelAndView(viewName);
mav.addObject("ID",cmd.getID());
return mav;
}
控制器 2:
public class controller2 extends SimpleFormController implements Serializable {
private PersonManager pManager ;
@Override
public ModelAndView onSubmit (Object command) throws ServletException, IOException {
Person p = (Person) command;
Map<String,Object> model = new HashMap<String,Object>();
pManager.UpdatePerson(p);
model.put("person", p);
return new ModelAndView("SuccesfulUpdate","model",model);
}
protected Object formBackingObject(HttpServletRequest request,HttpServletResponse response)
throws ServletException, IOException {
String id = request.getParameter("ID");
if(id==null) {
response.sendRedirect("controller1.htm");
return null;
} else{
Personne p = pManager.getPersonbyID(id);
return p;
}}
如果直接调用 url "controller2.htm" 则 ID 参数将为空,并且由于 formBackingObject() 是处理请求时执行的第一个方法,我想我可以做一个重定向,但它不起作用,因为我被重定向到 controller2 的表单是空的。
您的问题与跨站点请求伪造保护非常接近,因此应该应用相同的通用解决方案。
您只需在 Controller1
中生成一个随机标记,将其放入模型中的任意名称(比如 "_csrf"
),并将其值存储在会话中。然后在 Controller2
中测试:
- 参数请求
_csrf
存在于请求 中
- 等于session中存储的值
并立即从会话中删除 _csrf
值。
如果满足这两个要求,则很可能 Controller2
是通过 Controller1
的重定向调用的,因为没有其他人应该能够猜出值
我终于找到了解决办法。我覆盖了 showForm 方法。在这个方法中,我可以测试参数是否存在于请求中。如果存在,则调用 formBackingObject 方法并显示 controller2 的表单,否则将重定向到 controller1。
控制器 1:
public class controller1 extends SimpleFormController implements Serializable {
private PersonManager pManager ;
@Override
public ModelAndView onSubmit(Object command) {
CommandPerson cmd = (CommandPerson) command;
Person p = null;
String viewName = "redirect:controller2.htm";
try {
p = pManager.getPersonbyID(cmd.getID());
} catch (EmptyResultDataAccessException ex) {
viewName="NosuchPerson";
}
ModelAndView mav = new ModelAndView(viewName);
mav.addObject("ID",cmd.getID());
return mav;
}
控制器 2:
public class controller2 extends SimpleFormController implements Serializable {
private PersonManager pManager ;
@Override
public ModelAndView onSubmit (Object command) throws ServletException, IOException {
Person p = (Person) command;
Map<String,Object> model = new HashMap<String,Object>();
pManager.UpdatePerson(p);
model.put("person", p);
return new ModelAndView("SuccesfulUpdate","model",model);
}
protected Object formBackingObject(HttpServletRequest request,HttpServletResponse response)
throws ServletException, IOException {
String id = request.getParameter("ID");
if(id==null) {
response.sendRedirect("controller1.htm");
return null;
} else{
Personne p = pManager.getPersonbyID(id);
return p;
}}
protected ModelAndView showForm(HttpServletRequest request, HttpServletResponse response, BindException errors)throws Exception {
String id = request.getParameter("ID");
if (id==null) return new ModelAndView("redirect:controller1.htm");
else{
Personn p = (Personne) formBackingObject(request, response);
return new ModelAndView("UpdatePersonForm","Person",p);
}}
我正在使用 JAVA Spring mvc 开发网站。我有一个需要两个控制器的功能。首先,请求由 controller1 处理,controller1 使用 return new ModelAndView ("redirect:controller2.htm") 将请求重定向到 controller2。一切正常。但是,我想阻止对 controller2 的直接访问(阻止来自 url "controller2.htm" 的调用),因为 controller2 的表单需要来自 controller1.I 的数据,这是唯一的情况controller2 用于从 controller1 重定向。我想要一个没有提前 annotations.Thanks 的解决方案来帮助你。 这是代码: 控制器 1:
public class controller1 extends SimpleFormController implements Serializable {
private PersonManager pManager ;
@Override
public ModelAndView onSubmit(Object command) {
CommandPerson cmd = (CommandPerson) command;
Person p = null;
String viewName = "redirect:controller2.htm";
try {
p = pManager.getPersonbyID(cmd.getID());
} catch (EmptyResultDataAccessException ex) {
viewName="NosuchPerson";
}
ModelAndView mav = new ModelAndView(viewName);
mav.addObject("ID",cmd.getID());
return mav;
}
控制器 2:
public class controller2 extends SimpleFormController implements Serializable {
private PersonManager pManager ;
@Override
public ModelAndView onSubmit (Object command) throws ServletException, IOException {
Person p = (Person) command;
Map<String,Object> model = new HashMap<String,Object>();
pManager.UpdatePerson(p);
model.put("person", p);
return new ModelAndView("SuccesfulUpdate","model",model);
}
protected Object formBackingObject(HttpServletRequest request,HttpServletResponse response)
throws ServletException, IOException {
String id = request.getParameter("ID");
if(id==null) {
response.sendRedirect("controller1.htm");
return null;
} else{
Personne p = pManager.getPersonbyID(id);
return p;
}}
如果直接调用 url "controller2.htm" 则 ID 参数将为空,并且由于 formBackingObject() 是处理请求时执行的第一个方法,我想我可以做一个重定向,但它不起作用,因为我被重定向到 controller2 的表单是空的。
您的问题与跨站点请求伪造保护非常接近,因此应该应用相同的通用解决方案。
您只需在 Controller1
中生成一个随机标记,将其放入模型中的任意名称(比如 "_csrf"
),并将其值存储在会话中。然后在 Controller2
中测试:
- 参数请求
_csrf
存在于请求 中
- 等于session中存储的值
并立即从会话中删除 _csrf
值。
如果满足这两个要求,则很可能 Controller2
是通过 Controller1
的重定向调用的,因为没有其他人应该能够猜出值
我终于找到了解决办法。我覆盖了 showForm 方法。在这个方法中,我可以测试参数是否存在于请求中。如果存在,则调用 formBackingObject 方法并显示 controller2 的表单,否则将重定向到 controller1。
控制器 1:
public class controller1 extends SimpleFormController implements Serializable {
private PersonManager pManager ;
@Override
public ModelAndView onSubmit(Object command) {
CommandPerson cmd = (CommandPerson) command;
Person p = null;
String viewName = "redirect:controller2.htm";
try {
p = pManager.getPersonbyID(cmd.getID());
} catch (EmptyResultDataAccessException ex) {
viewName="NosuchPerson";
}
ModelAndView mav = new ModelAndView(viewName);
mav.addObject("ID",cmd.getID());
return mav;
}
控制器 2:
public class controller2 extends SimpleFormController implements Serializable {
private PersonManager pManager ;
@Override
public ModelAndView onSubmit (Object command) throws ServletException, IOException {
Person p = (Person) command;
Map<String,Object> model = new HashMap<String,Object>();
pManager.UpdatePerson(p);
model.put("person", p);
return new ModelAndView("SuccesfulUpdate","model",model);
}
protected Object formBackingObject(HttpServletRequest request,HttpServletResponse response)
throws ServletException, IOException {
String id = request.getParameter("ID");
if(id==null) {
response.sendRedirect("controller1.htm");
return null;
} else{
Personne p = pManager.getPersonbyID(id);
return p;
}}
protected ModelAndView showForm(HttpServletRequest request, HttpServletResponse response, BindException errors)throws Exception {
String id = request.getParameter("ID");
if (id==null) return new ModelAndView("redirect:controller1.htm");
else{
Personn p = (Personne) formBackingObject(request, response);
return new ModelAndView("UpdatePersonForm","Person",p);
}}