From fcad646a7c912463c53de946b2586e4a49a6e1ff Mon Sep 17 00:00:00 2001 From: developerKurt Date: Wed, 1 Jan 2020 13:42:05 +0300 Subject: As requested in issue #4393, added logging IP address functionality when login attempts fail. --- .../org/traccar/api/resource/SessionResource.java | 2 + src/main/java/org/traccar/helper/IpRetriever.java | 48 ++++++++++++++++++++++ src/main/java/org/traccar/helper/LogAction.java | 16 ++++++++ 3 files changed, 66 insertions(+) create mode 100644 src/main/java/org/traccar/helper/IpRetriever.java (limited to 'src/main/java/org') diff --git a/src/main/java/org/traccar/api/resource/SessionResource.java b/src/main/java/org/traccar/api/resource/SessionResource.java index fd331c766..65e05a4a2 100644 --- a/src/main/java/org/traccar/api/resource/SessionResource.java +++ b/src/main/java/org/traccar/api/resource/SessionResource.java @@ -18,6 +18,7 @@ package org.traccar.api.resource; import org.traccar.Context; import org.traccar.api.BaseResource; import org.traccar.helper.DataConverter; +import org.traccar.helper.IpRetriever; import org.traccar.helper.LogAction; import org.traccar.model.User; @@ -106,6 +107,7 @@ public class SessionResource extends BaseResource { LogAction.login(user.getId()); return user; } else { + LogAction.failedLogin(IpRetriever.retrieveIP(request)); throw new WebApplicationException(Response.status(Response.Status.UNAUTHORIZED).build()); } } diff --git a/src/main/java/org/traccar/helper/IpRetriever.java b/src/main/java/org/traccar/helper/IpRetriever.java new file mode 100644 index 000000000..37a1e8662 --- /dev/null +++ b/src/main/java/org/traccar/helper/IpRetriever.java @@ -0,0 +1,48 @@ +package org.traccar.helper; + +import javax.servlet.http.HttpServletRequest; + +/** + * Gets the client's IP address regardless of whether the server is behind a proxy server or a load balancer. + * + */ +public final class IpRetriever + { + + + /** + * Retrieves the client's IP address. + * Handles the cases like whether the server is behind a proxy server or a load balancer + * also if the request is being made by using a reverse proxy. + * + * @param request {@link HttpServletRequest} instance + * @return client's IP address + */ + public static String retrieveIP(HttpServletRequest request) { + + if(request != null){ + String ipAddress = request.getHeader("X-FORWARDED-FOR"); + + if (ipAddress != null && !ipAddress.isEmpty()) { + return removeUnwantedData(ipAddress); + } + else{ + ipAddress = request.getRemoteAddr(); + return ipAddress; + } + + } else return null; + + } + + /** + * If the request uses a reverse proxy, the header value will also contain load balancer and reverse proxy server IPs + * This method gets rid of them. + * + * @param ipAddress IP address value from the header + * @return IP address of the client + */ + private static String removeUnwantedData(String ipAddress){ + return ipAddress.contains(",") ? ipAddress.split(",")[0] : ipAddress; + } +} diff --git a/src/main/java/org/traccar/helper/LogAction.java b/src/main/java/org/traccar/helper/LogAction.java index db13337b8..1fbd78c4d 100644 --- a/src/main/java/org/traccar/helper/LogAction.java +++ b/src/main/java/org/traccar/helper/LogAction.java @@ -38,12 +38,14 @@ public final class LogAction { private static final String ACTION_LOGIN = "login"; private static final String ACTION_LOGOUT = "logout"; + private static final String ACTION_FAILED_LOGIN_NO_IP = "Failed Login Attempt. IP address: failed to retrieve"; private static final String ACTION_DEVICE_ACCUMULATORS = "resetDeviceAccumulators"; private static final String PATTERN_OBJECT = "user: %d, action: %s, object: %s, id: %d"; private static final String PATTERN_LINK = "user: %d, action: %s, owner: %s, id: %d, property: %s, id: %d"; private static final String PATTERN_LOGIN = "user: %d, action: %s"; + private static final String PATTERN_FAILED_LOGIN = "Failed Login Attempt. IP address: %s"; private static final String PATTERN_DEVICE_ACCUMULATORS = "user: %d, action: %s, deviceId: %d"; public static void create(long userId, BaseModel object) { @@ -74,6 +76,20 @@ public final class LogAction { logLoginAction(ACTION_LOGOUT, userId); } + public static void failedLogin(String ipAddress) { + + if(ipAddress == null || ipAddress.isEmpty()) { + LOGGER.info(ACTION_FAILED_LOGIN_NO_IP); + } + + else{ + LOGGER.info(String.format( + PATTERN_FAILED_LOGIN, ipAddress)); + } + + } + + public static void resetDeviceAccumulators(long userId, long deviceId) { LOGGER.info(String.format( PATTERN_DEVICE_ACCUMULATORS, userId, ACTION_DEVICE_ACCUMULATORS, deviceId)); -- cgit v1.2.3