Commit 92f2d40f authored by Matija Obreza's avatar Matija Obreza
Browse files

Account lockout

parent b1594cf8
/*
* Copyright 2017 Global Crop Diversity Trust
*
* 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 org.genesys.blocks.security.lockout;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class AccountLockoutConfig {
@Bean
public AccountLockoutManager accountLockountManager() {
return new AccountLockoutManager();
}
@Bean
public AuthenticationSuccessListener authenticationSuccessListener() {
return new AuthenticationSuccessListener();
}
@Bean
public AuthenticationFailureBadCredentialsListener authenticationFailureListener() {
return new AuthenticationFailureBadCredentialsListener();
}
}
......@@ -23,10 +23,11 @@ import java.util.Map;
import javax.annotation.Resource;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.genesys.blocks.security.NoUserFoundException;
import org.genesys.blocks.security.model.BasicUser;
import org.genesys.blocks.security.service.BasicUserService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
......@@ -39,7 +40,7 @@ import org.springframework.stereotype.Component;
*/
@Component
public class AccountLockoutManager {
private final Log _log = LogFactory.getLog(getClass());
private static final Logger LOG = LoggerFactory.getLogger(AccountLockoutManager.class);
@Resource(name = "accountLockoutMap")
private Map<String, AttemptStatistics> loginAttempts;
......@@ -67,7 +68,7 @@ public class AccountLockoutManager {
* @param lockAfterXFailures
*/
public void setLockAfterXFailures(int lockAfterXFailures) {
_log.info("Will lock user accounts after " + lockAfterXFailures + " successive failed attempts.");
LOG.info("Will lock user accounts after " + lockAfterXFailures + " successive failed attempts.");
this.lockAfterXFailures = lockAfterXFailures;
}
......@@ -81,7 +82,7 @@ public class AccountLockoutManager {
if (loginAttempts.containsKey(userName)) {
final AttemptStatistics stats = loginAttempts.get(userName);
loginAttempts.remove(userName);
_log.info("Successful login. Removed failed login statistics for " + userName + " " + stats);
LOG.info("Successful login. Removed failed login statistics for " + userName + " " + stats);
}
}
......@@ -103,8 +104,8 @@ public class AccountLockoutManager {
stats.id = user.getId();
loginAttempts.put(userName, stats);
} else {
if (_log.isDebugEnabled()) {
_log.debug("No such user username=" + userName);
if (LOG.isDebugEnabled()) {
LOG.debug("No such user username=" + userName);
}
}
}
......@@ -114,11 +115,15 @@ public class AccountLockoutManager {
stats.lastAttempt = new Date();
loginAttempts.put(userName, stats);
_log.info("Updated failed login statistics for username=" + userName + " " + stats);
LOG.info("Updated failed login statistics for username=" + userName + " " + stats);
if (stats.count >= lockAfterXFailures) {
_log.warn("Too many failed login attempts. Locking account for username=" + userName);
userService.setAccountLockLocal(stats.id, true);
LOG.warn("Too many failed login attempts. Locking account for username=" + userName);
try {
userService.setAccountLockLocal(stats.id, true);
} catch (NoUserFoundException e) {
LOG.warn(e.getMessage());
}
}
}
......@@ -132,8 +137,8 @@ public class AccountLockoutManager {
return;
}
if (_log.isDebugEnabled()) {
_log.debug("Purging expired entries");
if (LOG.isDebugEnabled()) {
LOG.debug("Purging expired entries");
}
final List<String> userNames = new ArrayList<String>(loginAttempts.keySet());
......@@ -148,12 +153,12 @@ public class AccountLockoutManager {
if (now - stats.lastAttempt.getTime() >= lockoutTime) {
loginAttempts.remove(userName);
_log.info("Removed expired failed login statistics for " + userName + " " + stats);
LOG.info("Removed expired failed login statistics for " + userName + " " + stats);
}
}
if (_log.isDebugEnabled()) {
_log.debug("Number of failed login attempts in memory: " + loginAttempts.size());
if (LOG.isDebugEnabled()) {
LOG.debug("Number of failed login attempts in memory: " + loginAttempts.size());
}
}
......
......@@ -15,8 +15,8 @@
*/
package org.genesys.blocks.security.lockout;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationListener;
import org.springframework.security.authentication.event.AuthenticationFailureBadCredentialsEvent;
......@@ -30,7 +30,7 @@ import org.springframework.stereotype.Component;
*/
@Component
public class AuthenticationFailureBadCredentialsListener implements ApplicationListener<AuthenticationFailureBadCredentialsEvent> {
private final Log _log = LogFactory.getLog(getClass());
private final Logger _log = LoggerFactory.getLogger(getClass());
@Autowired
private AccountLockoutManager lockoutManager;
......@@ -43,7 +43,7 @@ public class AuthenticationFailureBadCredentialsListener implements ApplicationL
if (details != null && details instanceof WebAuthenticationDetails) {
final WebAuthenticationDetails wad = (WebAuthenticationDetails) details;
// This can be picked up by fail2ban http://www.fail2ban.org/
_log.warn("Failed login attempt for username=" + userName + " from IP=" + wad.getRemoteAddress());
_log.warn("Failed login attempt for username={} from IP={}", userName, wad.getRemoteAddress());
}
lockoutManager.handleFailedLogin(userName);
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment