阻止对控制器的直接调用

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);
        }}