阻止直接调用控制器

时间:2015-01-29 21:22:33

标签: java spring-mvc

我在使用JAVA Spring mvc的网站上工作。我有一个需要两个控制器的功能。首先,请求由controller1处理,后者使用返回的新ModelAndView(“redirect:controller2.htm”)将其重定向到controller2。一切都很好。但是,我想阻止对controller2的直接访问(阻止来自url“controller2.htm”的调用),因为controller2的表单需要来自controller1的数据。我想要使用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;
                }}

如果直接调用url“controller2.htm”,那么ID参数将为null,并且由于formBackingObject()是处理请求时执行的第一个方法,我认为我可以在其中进行重定向,但它我没有工作,因为我被重定向到controller2的表格是空的。

2 个答案:

答案 0 :(得分:0)

您的问题非常接近Cross Site Request Forgery保护,因此应采用相同的通用解决方案。

您只需在Controller1中生成随机令牌,将其置于任意名称下的模型中(例如"_csrf"),并将其值存储在会话中。然后在Controller2中测试:

  • 参数请求_csrf出现在请求
  • 它等于会话
  • 中存储的值

并立即从会话中删除_csrf值。

如果满足这两个要求,则极有可能通过Controller2的重定向调用Controller1,因为没有其他人能够猜出该值

答案 1 :(得分:0)

我终于找到了解决方案。我重写了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);
        }}