2 * Licensed to the University Corporation for Advanced Internet Development,
3 * Inc. (UCAID) under one or more contributor license agreements. See the
4 * NOTICE file distributed with this work for additional information regarding
5 * copyright ownership. The UCAID licenses this file to You under the Apache
6 * License, Version 2.0 (the "License"); you may not use this file except in
7 * compliance with the License. You may obtain a copy of the License at
9 * http://www.apache.org/licenses/LICENSE-2.0
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
18 package edu.internet2.middleware.shibboleth.idp.authn.provider;
20 import java.net.InetAddress;
21 import java.net.UnknownHostException;
22 import java.util.ArrayList;
23 import java.util.List;
25 import javax.servlet.http.HttpServletRequest;
26 import javax.servlet.http.HttpServletResponse;
28 import org.opensaml.saml2.core.AuthnContext;
29 import org.opensaml.xml.util.DatatypeHelper;
30 import org.slf4j.Logger;
31 import org.slf4j.LoggerFactory;
33 import edu.internet2.middleware.shibboleth.idp.authn.AuthenticationEngine;
34 import edu.internet2.middleware.shibboleth.idp.authn.LoginHandler;
35 import edu.internet2.middleware.shibboleth.idp.util.IPRange;
38 * IP Address authentication handler.
40 * This "authenticates" a user based on their IP address. It operates in either default deny or default allow mode, and
41 * evaluates a given request against a list of blocked or permitted IPs. It supports both IPv4 and IPv6.
43 public class IPAddressLoginHandler extends AbstractLoginHandler {
46 private final Logger log = LoggerFactory.getLogger(IPAddressLoginHandler.class);
48 /** The username to use for IP-address "authenticated" users. */
49 private String authenticatedUser;
51 /** List of configured IP ranged. */
52 private List<IPRange> ipRanges;
54 /** Whether a user is "authenticated" if their IP address is within a configured IP range. */
55 private boolean ipInRangeIsAuthenticated;
60 * @param user username to return upon successful "authentication"
61 * @param ranges range of IP addresses specified
62 * @param isIpInRangeAuthenticated whether the specified IP address range represent those that are authenticated or
65 public IPAddressLoginHandler(String user, List<IPRange> ranges, boolean isIpInRangeAuthenticated) {
66 authenticatedUser = DatatypeHelper.safeTrimOrNullString(user);
67 if (authenticatedUser == null) {
68 throw new IllegalArgumentException("The authenticated user ID may not be null or empty");
71 if (ranges == null || ranges.isEmpty()) {
72 throw new IllegalArgumentException("The list of IP ranges may not be null or empty");
74 ipRanges = new ArrayList<IPRange>(ranges);
76 this.ipInRangeIsAuthenticated = isIpInRangeAuthenticated;
80 public boolean supportsPassive() {
85 public boolean supportsForceAuthentication() {
90 public void login(HttpServletRequest httpRequest, HttpServletResponse httpResponse) {
91 log.debug("Attempting to authenticated client '{}'", httpRequest.getRemoteAddr());
93 InetAddress clientAddress = InetAddress.getByName(httpRequest.getRemoteAddr());
94 if (authenticate(clientAddress)) {
95 log.debug("Authenticated user by IP address");
96 httpRequest.setAttribute(LoginHandler.PRINCIPAL_NAME_KEY, authenticatedUser);
97 httpRequest.setAttribute(LoginHandler.AUTHENTICATION_METHOD_KEY, AuthnContext.IP_AUTHN_CTX);
99 log.debug("Client IP address {} failed authentication.", httpRequest.getRemoteAddr());
100 httpRequest.setAttribute(LoginHandler.AUTHENTICATION_ERROR_KEY,
101 "Client failed IP address authentication");
103 } catch (UnknownHostException e) {
104 String msg = "Unable to resolve " + httpRequest.getRemoteAddr() + " in to an IP address";
106 httpRequest.setAttribute(LoginHandler.AUTHENTICATION_ERROR_KEY, msg);
109 AuthenticationEngine.returnToAuthenticationEngine(httpRequest, httpResponse);
113 * Authenticates the client address.
115 * @param clientAddress the client address
117 * @return true if the client address is authenticated, false it not
119 protected boolean authenticate(InetAddress clientAddress) {
120 if (ipInRangeIsAuthenticated) {
121 for (IPRange range : ipRanges) {
122 if (range.contains(clientAddress)) {
127 for (IPRange range : ipRanges) {
128 if (!range.contains(clientAddress)) {