ip address handler
authordmorr <dmorr@ab3bd59b-922f-494d-bb5f-6f0a3c29deca>
Mon, 5 Feb 2007 15:42:55 +0000 (15:42 +0000)
committerdmorr <dmorr@ab3bd59b-922f-494d-bb5f-6f0a3c29deca>
Mon, 5 Feb 2007 15:42:55 +0000 (15:42 +0000)
git-svn-id: https://subversion.switch.ch/svn/shibboleth/java-idp/trunk@2142 ab3bd59b-922f-494d-bb5f-6f0a3c29deca

src/edu/internet2/middleware/shibboleth/idp/authn/impl/IPAddressHandler.java [new file with mode: 0644]

diff --git a/src/edu/internet2/middleware/shibboleth/idp/authn/impl/IPAddressHandler.java b/src/edu/internet2/middleware/shibboleth/idp/authn/impl/IPAddressHandler.java
new file mode 100644 (file)
index 0000000..a8c9240
--- /dev/null
@@ -0,0 +1,199 @@
+/*
+ * Copyright [2006] [University Corporation for Advanced Internet Development, Inc.]
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+package edu.internet2.middleware.shibboleth.idp.authn.impl;
+
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.util.List;
+
+import javax.servlet.RequestDispatcher;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.HttpSession;
+import javax.servlet.ServletRequest;
+
+import javolution.util.FastList;
+
+import edu.internet2.middleware.shibboleth.idp.authn.AuthenticationHandler;
+import edu.internet2.middleware.shibboleth.idp.authn.LoginContext;
+
+import org.apache.log4j.Logger;
+
+import org.joda.time.DateTime;
+
+
+/**
+ * IP Address authentication handler.
+ *
+ * This "authenticates" a user based on their IP address.
+ * It operates in either default deny or default allow mode,
+ * and evaluates a given request against a list of blocked or permitted IPs.
+ * It supports both IPv4 and IPv6.
+ */
+public class IPAddressHandler implements AuthenticationHandler {
+    
+    private static final Logger log =
+           Logger.getLogger(IPAddressHandler.class.getName());
+    
+    /** the URI of the AuthnContextDeclRef or the AuthnContextClass */
+    private String authnMethodURI;
+    
+    /** The return location */
+    private String returnLocation;
+    
+    /** Are the IPs in ipList a permitted list or a deny list */
+    private boolean defaultDeny;
+    
+    /** The list of denied or permitted IPs */
+    private List<InetAddress> ipList;
+    
+    
+    /** Creates a new instance of IPAddressHandler */
+    public IPAddressHandler() {
+    }
+    
+    
+    /**
+     * Set the permitted IP addresses.
+     *
+     * If <code>defaultDeny</code> is <code>true</code> then only the IP
+     * addresses in <code>ipList</code> will be "authenticated." If
+     * <code>defaultDeny</code> is <code>false</code>, then all IP addresses
+     * except those in <code>ipList</code> will be authenticated.
+     *
+     * @param ipList A list of {@link InetAddress}es.
+     * @param defaultDeny Does <code>ipList</code> contain a deny or permit list.
+     */
+    public void setIpList(final List<InetAddress> ipList, boolean defaultDeny) {
+       
+       this.ipList = new FastList(ipList);
+       this.defaultDeny = defaultDeny;
+    }
+    
+    
+    /** {@inheritDoc */
+    public void setReturnLocation(String location) {
+       this.returnLocation = location;
+    }
+    
+    
+    /** @{inheritDoc} */
+    public boolean supportsPassive() {
+       return (true);
+    }
+    
+    
+    /** {@inheritDoc} */
+    public boolean supportsForceAuthentication() {
+       return (true);
+    }
+    
+    
+    /** {@inheritDoc} */
+    public void logout(HttpServletRequest request,
+           HttpServletResponse response, String principal) {
+       
+       RequestDispatcher dispatcher =
+               request.getRequestDispatcher(this.returnLocation);
+       dispatcher.forward(request, response);
+    }
+    
+    
+    /** {@inheritDoc} */
+    public void login(HttpServletRequest request,
+           HttpServletResponse response, boolean passive, boolean force) {
+       
+       HttpSession httpSession = request.getSession();
+       if (httpSession == null) {
+           log.error("Unable to retrieve HttpSession from request.");
+           return;
+       }
+       Object o = httpSession.getAttribute(LoginContext.LOGIN_CONTEXT_KEY);
+       if (! (o instanceof LoginContext)) {
+           log.error("Invalid login context object -- object is not an instance of LoginContext.");
+           return;
+       }
+       LoginContext loginContext = (LoginContext)o;
+       
+       loginContext.setAuthenticationAttempted();
+       loginContext.setAuthenticationInstant(new DateTime());
+       
+       if (this.defaultDeny) {
+           this.handleDefaultDeny(request, response, loginContext);
+       } else {
+           this.handleDefaultAllow(request, response, loginContext);
+       }
+       
+    }
+    
+    
+    private void handleDefaultDeny(HttpServletRequest request,
+           HttpServletResponse response, LoginContext loginCtx) {
+       
+       boolean ipAllowed = this.searchIpList(request);
+       
+       if (ipAllowed) {
+           loginCtx.setAuthenticationOK(true);
+       } else {
+           loginCtx.setAuthenticationOK(false);
+           loginCtx.setAuthenticationFailureMessage("User's IP is not in the permitted list.");
+       }
+    }
+    
+    
+    private void handleDefaultAllow(HttpServletRequest request,
+           HttpServletResponse response, LoginContext loginCtx) {
+       
+       boolean ipDenied = this.searchIpList(request);
+       
+       if (ipDenied) {
+           loginCtx.setAuthenticationOK(false);
+           loginCtx.setAuthenticationFailureMessage("Users's IP is in the deny list.");
+       } else {
+           loginCtx.setAuthenticationOK(true);
+       }
+    }
+    
+    
+    /**
+     * Search the list of InetAddresses for the client's address.
+     *
+     * @param request The ServletReqeust
+     *
+     * @return <code>true</code> if the client's address is in <code>this.ipList</code>
+     */
+    private boolean searchIpList(final ServletRequest request) {
+       
+       boolean found = false;
+       
+       try {
+           InetAddress[] addrs = InetAddress.getAllByName(request.getRemoteAddr());
+           for (InetAddress a : addrs) {
+               if (this.ipList.contains(a)) {
+                   found = true;
+                   break;
+               }
+           }
+       } catch (UnknownHostException ex) {
+           log.error("Error resolving hostname: ", ex);
+       }
+       
+       return (found);
+    }
+    
+}