2

I have an enterprise application with an EJB module and a web application module(a servlet). I am accessing the servlet URL from EJB using URLConnection but want to protect the URL with some security. I do not want to use username and password to authenticate because I can not use any single sign-on solution so I want to if there is a way to restrict the URL to be accessed only from its enterprise application. Please help.

krish
  • 21
  • 1
  • 5
  • I have tried refactoring the common classes into another jar but there seem to be too many dependencies on the other classes so its still failing and I am still investigating on this. But is it advisable to move the whole jar file from WEB-INF/lib to APP-INF/lib so that these classes can be accessed by both EJB and webapp modules? Are there going to be any classloader related issues or any issues with servlet initialization by the container? – krish Mar 01 '11 at 04:36
  • Please let me know if my question in the comment above should be made a separate question? – krish Mar 01 '11 at 04:38

3 Answers3

3

There is a lot of information you've left out:

  • Is the servlet used only by your EJB module, or is it also used by other clients?
  • Are the servlet and EJB module running in the same container? The same physical machine?
  • What web server/servlet container/J2EE container are you using?

If the servlet is used only by the EJB module, and they are both on the same machine, then you can just configure your web container to only accept connections from localhost and change the URL your EJB module uses to point at localhost instead of a public domain name or IP address.

If they are on different machines, or if your servlet is used by other clients, then you will need to authenticate the EJB module somehow. You can use SSL client certificates (see this question) or configure your servlet container to allow connections from the EJB module's IP address.

EDIT

Using a servlet filter to control access is fairly straightforward. In your case, you want to verify that the request is coming from the localhost. If not, send an unauthorized message back to the client.

Here is a very simple doFilter method implementation that should do that:

public void doFilter(ServletRequest request,
                     ServletResponse response,
                     FilterChain chain)
   throws ServletException, IOException
{
    if (!request.getRemoteAddr().equals("127.0.0.1")) {
        HttpServletResponse rsp = (HttpServletResponse) response;
        rsp.sendError(HttpServletResponse.SC_FORBIDDEN, "You are not authorized to access this resource.");
    }

    chain.doFilter(request, response);
}

Add the filter to your web.xml with something like the following:

<filter>
    <filter-name>AuthorizationFilter</filter-name>
    <filter-class>com.foo.bar.AuthorizationFilter</filter-class>
</filter>

<filter-mapping>
    <filter-name>AuthorizationFilter</filter-name>
    <servlet-name>RestrictedServlet</servlet-name>
</filter-mapping>

Filters are executed in the order they appear in web.xml, so make sure the authorization filter is the first one listed.

Having said all this, I am in agreement with BalusC here. If at all possible, you should refactor your code so that the EJB module executes the code directly rather than making a servlet call.

Community
  • 1
  • 1
Jason Day
  • 8,809
  • 1
  • 41
  • 46
  • 1. This servlet in question is going to be used by EJB while other servlets in the same web application are used by other clients 2. Servlet and EJB are in same application running on same container 3. This application is running on Web Logic Server The web application has other servlets as well that are accessed from other clients from(from remote machines) so can WLS be configured to accept connections only from localhost for a prticular servlet? If yes, how to configure it on WLS? – krish Feb 01 '11 at 17:15
  • I don't know if WLS can be configured to do host-based accessed per servlet. You can configure the container to only listen on the localhost, but that would affect all servlets and webapps in the container. You could use a servlet filter to control access to a single servlet. – Jason Day Feb 02 '11 at 03:06
  • can you please let me know how to use (any sample would be of great help) servlet filters to control access to the servlet. I have looked at filters before but could not figure any way to control access. – krish Feb 02 '11 at 04:46
1

If they runs at the same machine, the normal practice is to refactor the business job the servlet is doing into another Java class which can then be imported/used by both the EJB and the servlet.

BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • It could be a good practice to refactor the code in this kind of scenario but in my case the job servlet is doing has to be performed in the servlet's context. – krish Feb 01 '11 at 12:28
  • What exactly do you need the servlet context for? – BalusC Feb 01 '11 at 12:29
  • The code was using the servlet context to get the application name and updating it somewhere else but a way to remove that dependency. It looks like your advise of refactoring the code to another java class and use it in both EJB servlet makes more sense so I am working on this solution. Thanks. – krish Feb 23 '11 at 04:51
1

You can create user credentials in the Application Server you use to deploy your servlet application and protect the application using that user (using for instance BASIC auth):

<security-constraint>
  <web-resource-collection>
    <web-resource-name>
      Entire Application
    </web-resource-name>
    <url-pattern>/*</url-pattern>
  </web-resource-collection>
  <auth-constraint>
      <role-name>member</role-name>
  </auth-constraint>
</security-constraint>

You can then use authenticate from your EJB.

Luciano Fiandesio
  • 10,037
  • 10
  • 48
  • 56
  • Thanks for your answer. Creating a user in Application Server to protect the URL and authenticating it from EJB means I will have to hard-code the username and password in the EJB which I want to avoid. – krish Feb 01 '11 at 12:24