views:

49

answers:

3

Hi,

for security reasons, we want to block users by IP adress in our application, if they are trying to login as admin and they type in the a wrong password 3 times.

It is very easy to get the IP Adress of the user trying to login. I use this code snippet to get the IP:

ExternalContext context = FacesContext.getCurrentInstance().getExternalContext();
HttpServletRequest request = (HttpServletRequest)context.getRequest();
String ip = request.getRemoteAddr();

We are using JBoss 5.1.0 GA and Seam 2.2.1.CR2. As far as I know, there is no way to block IP addresses in Seam. But is it possible to call JBoss functions to block a specific IP?

Please let me know if Seam has some support for this :)

+1  A: 

I dont know nothing for that. But you could create a simple Filter (javax.servlet.Filter) and block requests from a set of IPs. It's really simple.

Plínio Pantaleão
+1  A: 

If you have an Apache server in front of your Jboss Server then calling request.getRemoteAddr(); will just give you the IP of the Apache server.

Instead use the X-Forwarded-For header

As Plinio says, you can use a filter. If you don't want to do that then you could also use a page action.

Damo
thanks for the tip with the x-forwarded-for header. Very useful :)
Dominik Obermaier
+1  A: 

This should be very easy to do.

Assuming you have an application scoped Set with all the ip's you want to block you can use this filter:

@Startup
@Scope(ScopeType.APPLICATION)
@Name("ipFilter")
@BypassInterceptors
@Filter(around ="org.jboss.seam.web.ajax4jsfFilter")
public class IpFilter extends AbstractFilter {

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

      if (!(req instanceof HttpServletRequest)) {
          chain.doFilter(req, res);
          return;
      }

      HttpServletRequest request = (HttpServletRequest) req;

      Set<String> ips = (Set<String>)Component.getInstance("blockedIps");
      if(ips.contains(request.getRemoteAddr())) {
        throw new ServletException("Permission denied");
      }

      chain.doFilter(req, res);

    }
}
Shervin
There is probably a better way of denying access instead of throwing exception. Probably using the response to send error, but for simplicity I just showed throwing exception in the code
Shervin
Thanks for this great answer, I'll give it a try. :)
Dominik Obermaier
You're welcome.
Shervin