Amzi
Amzi

Reputation: 399

how to prevent servlet from being invoked directly through browser

I was working on a web project using java servlet and jsp pages. In one of the servlet we have RequestDispatcher method and which is calling another servlet.

@WebServlet("/Demo")
public class DemoServlet extends HttpServlet {  

    public void doGet(HttpServletRequest req, HttpServletResponse res)  
            throws ServletException, IOException {  
        res.sendRedirect("testing"); //calling other servlet 
    }  
}  



    @WebServlet("/testing")
    public class TestingServlet extends HttpServlet {  

        public void doGet(HttpServletRequest req, HttpServletResponse res)  
                throws ServletException, IOException {  
                response.setContentType("text/html;charset=UTF-8");  
                PrintWriter out = response.getWriter();
                out.println("Hello World");

        }  
    }  

So, now I wanted to prevent contextRoot/testing from being invoked directly from the browser but instead only let it invoked from the other servlet(Demo)

Please suggest me if there is any way to do that.

Upvotes: 4

Views: 3062

Answers (3)

Aditya C S
Aditya C S

Reputation: 679

Answer given by "Romin" is correct. You have to use Filters for this. what you can do is, you can set a new session variable whenever "/Demo" url is accessed and in the filter check for the condition that session exists, if it exists allow the url or else throw error. You could do something similar like this. In "Demo" servlet

@WebServlet("/Demo")
public class DemoServlet extends HttpServlet {  

    public void doGet(HttpServletRequest req, HttpServletResponse res)  
            throws ServletException, IOException {  
        HttpSession session = request.getSession() //get new session
        res.sendRedirect("testing"); //calling other servlet 
    }  
}  

In Filter class add the below code

 @WebFilter("/login")
 public class MyFilter implements Filter{  

    public void init(FilterConfig arg0) throws ServletException {}  

    public void doFilter(ServletRequest req, ServletResponse resp,  
        FilterChain chain) throws IOException, ServletException {  

        HttpRequest request = (HttpRequest) req;
        HttpResponse respone = (HttpResponse) res;

        HttpSession session = request.getSession(false) //get the existing session object
        if(null != session) {
         chain.doFilter(req, resp);
        } else {
           "redirect to some error page or home page"
        }  
    }
        public void destroy() {}  
}  

Upvotes: 1

gerrytan
gerrytan

Reputation: 41123

One approach is to check the caller's ip using ServletRequest.getRemoteAddr() and rejects it if it's not called locally

public void doGet(HttpServletRequest req, HttpServletResponse res)  
            throws ServletException, IOException {  
  if(!req.getRemoteAddr().equals("127.0.0.1")) { // reject }
}

However this method wouldn't work legitimate caller (eg: proxy) is also using the same ip.

Upvotes: 0

Romin
Romin

Reputation: 8816

Couple of techniques exist:

  • Look at writing a HTTP Request Filter. You can then inspect the incoming request and the url and reject it if the pattern matches the servlet paths that you do not want to be invoked directly.

  • Another mechanism is to use the security constraints in your web.xml to allow access to various paths in your application only to authorized users/roles. Look at <security-constraint> tag in web.xml

Upvotes: 4

Related Questions