@Override public void handle(Object event) { AuthenticationFailureBadCredentialsEvent loginFailureEvent = (AuthenticationFailureBadCredentialsEvent) event; Object name = loginFailureEvent.getAuthentication().getPrincipal(); Users user = usersRepository.loadUserByUsername((String) name); eventService.raiseSecurityEvent(new AuthenticationFailedEvent( ((WebAuthenticationDetails) loginFailureEvent .getAuthentication().getDetails()).getRemoteAddress(), (String) name)); if (user != null) { // update the failed login count user.increaseFailedLoginAttempts(); if (user.getFailedLoginAttempts() >= max_failed_attempts) { Calendar cal = Calendar.getInstance(); user.setLockoutTime(cal); } // update user usersRepository.updateUser(user); } }
@Test public void testHandle_when_account_is_not_locked() { AuthenticationFailureBadCredentialsEvent loginFailureEvent=mock(AuthenticationFailureBadCredentialsEvent.class); Authentication authentication=mock(Authentication.class); WebAuthenticationDetails webAuthenticationDetails=mock(WebAuthenticationDetails.class); Object name=new String(username); when(loginFailureEvent.getAuthentication()).thenReturn(authentication); when(authentication.getDetails()).thenReturn(webAuthenticationDetails); when(webAuthenticationDetails.getRemoteAddress()).thenReturn("127.0.0.1"); when(authentication.getPrincipal()).thenReturn(name); Users user=mock(Users.class); when(user.getFailedLoginAttempts()).thenReturn(0); when(usersRepository.loadUserByUsername(username)).thenReturn(user); loginFailureEventListener.handle(loginFailureEvent); verify(usersRepository).updateUser(user); }
@Test public void testHandle_when_account_is_locked() { AuthenticationFailureBadCredentialsEvent loginFailureEvent=mock(AuthenticationFailureBadCredentialsEvent.class); Authentication authentication=mock(Authentication.class); WebAuthenticationDetails webAuthenticationDetails=mock(WebAuthenticationDetails.class); Object name=new String(username); when(loginFailureEvent.getAuthentication()).thenReturn(authentication); when(authentication.getPrincipal()).thenReturn(name); when(authentication.getDetails()).thenReturn(webAuthenticationDetails); when(webAuthenticationDetails.getRemoteAddress()).thenReturn("127.0.0.1"); Users user=mock(Users.class); when(user.getFailedLoginAttempts()).thenReturn(3); when(usersRepository.loadUserByUsername(username)).thenReturn(user); loginFailureEventListener.handle(loginFailureEvent); verify(user).setLockoutTime(any(Calendar.class)); verify(usersRepository).updateUser(user); }
@Override public void onApplicationEvent(AbstractAuthenticationEvent event) { if (event instanceof AuthenticationSuccessEvent) { log.debug("Authentication OK: {}", event.getAuthentication().getName()); // Activity log Object details = event.getAuthentication().getDetails(); String params = null; if (details instanceof WebAuthenticationDetails) { WebAuthenticationDetails wad = (WebAuthenticationDetails) details; params = wad.getRemoteAddress(); } else if (GenericHolder.get() != null) { params = (String) GenericHolder.get(); } UserActivity.log(event.getAuthentication().getName(), "LOGIN", null, null, params); } else if (event instanceof AuthenticationFailureBadCredentialsEvent) { log.info("Authentication ERROR: {}", event.getAuthentication().getName()); } }
@Override public void onApplicationEvent(AbstractAuthenticationEvent appEvent) { String currentUserName = extractUserName(appEvent); if (currentUserName == null || isLockMechanismDisabled()) { return; } if (appEvent instanceof AuthenticationSuccessEvent && accessCounter.containsKey(currentUserName) && accessCounter.get(currentUserName) < maxLoginFailures) { accessCounter.remove(currentUserName); lastFailedLogin.remove(currentUserName); } if (appEvent instanceof AuthenticationFailureBadCredentialsEvent) { if (accessCounter.containsKey(currentUserName)) { accessCounter.put(currentUserName, accessCounter.get(currentUserName) + 1); } else { accessCounter.put(currentUserName, 1); } lastFailedLogin.put(currentUserName, new Date()); } }
@Override public void handle(Object event) { AuthenticationFailureBadCredentialsEvent loginFailureEvent = (AuthenticationFailureBadCredentialsEvent) event; Object name = loginFailureEvent.getAuthentication() .getPrincipal(); Users user=usersRepository.loadUserByUsername((String)name); if (user != null) { // update the failed login count user.increaseFailedLoginAttempts(); if (user.getFailedLoginAttempts()>=max_failed_attempts){ Calendar cal = Calendar.getInstance(); user.setLockoutTime(cal); } // update user usersRepository.updateUser(user); } }
@Override @Transactional public void onApplicationEvent(AuthenticationFailureBadCredentialsEvent event) { Object principal = event.getAuthentication().getPrincipal(); if (principal instanceof String) { User user = this.userRepository.findByUserName((String) principal); if (user != null) { if (user.getFailedLogins() == null) { user.setFailedLogins(1); } else { user.setFailedLogins(user.getFailedLogins() + 1); } if (user.getFailedLogins() > 10) { user.setLockedOut(LocalDateTime.now().plusMinutes(10)); } } else { LoggerFactory.getLogger(UserAuthenticationErrorHandler.class) .error("Unknown user login attempt: {}", principal); } } }
@Override @Transactional public void onApplicationEvent(AuthenticationFailureBadCredentialsEvent ev) { try { String username = ev.getAuthentication().getName(); TypedQuery<User> query = User.findUsersByEmailAddress(username, null, null); User targetUser = (User) query.getSingleResult(); if (targetUser != null) { // only for existing users targetUser.reportLoginFailure(); targetUser.persist(); } } catch(Exception e) { } }
private SubsonicRESTController.ErrorCode authenticate(HttpServletRequest httpRequest, String username, String password, String salt, String token, Authentication previousAuth) { // Previously authenticated and username not overridden? if (username == null && previousAuth != null) { return null; } if (salt != null && token != null) { User user = securityService.getUserByName(username); if (user == null) { return SubsonicRESTController.ErrorCode.NOT_AUTHENTICATED; } String expectedToken = DigestUtils.md5Hex(user.getPassword() + salt); if (!expectedToken.equals(token)) { return SubsonicRESTController.ErrorCode.NOT_AUTHENTICATED; } password = user.getPassword(); } if (password != null) { UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(username, password); authRequest.setDetails(authenticationDetailsSource.buildDetails(httpRequest)); try { Authentication authResult = authenticationManager.authenticate(authRequest); SecurityContextHolder.getContext().setAuthentication(authResult); return null; } catch (AuthenticationException x) { eventPublisher.publishEvent(new AuthenticationFailureBadCredentialsEvent(authRequest, x)); return SubsonicRESTController.ErrorCode.NOT_AUTHENTICATED; } } return SubsonicRESTController.ErrorCode.MISSING_PARAMETER; }
public void onApplicationEvent(ApplicationEvent event) { try { if (event instanceof InteractiveAuthenticationSuccessEvent) { this.logLoginSuccess(event); } if (event instanceof AuthenticationFailureBadCredentialsEvent) { this.logBadCredential(event); } if (event instanceof AuthenticationFailureLockedEvent) { this.logLocked(event); } if (event instanceof AuthenticationFailureDisabledEvent) { this.logDisabled(event); } if (event instanceof AuthenticationFailureExpiredEvent) { this.logAccountExpired(event); } if (event instanceof AuthenticationFailureCredentialsExpiredEvent) { this.logCredentialExpired(event); } } catch (Exception ex) { logger.error(ex.getMessage(), ex); } }
public void logBadCredential(ApplicationEvent event) throws Exception { AuthenticationFailureBadCredentialsEvent authenticationFailureBadCredentialsEvent = (AuthenticationFailureBadCredentialsEvent) event; Authentication authentication = authenticationFailureBadCredentialsEvent .getAuthentication(); logger.info("{}", authentication); String tenantId = this.getTenantId(authentication); Object principal = authentication.getPrincipal(); String userId = null; if (principal instanceof SpringSecurityUserAuth) { userId = ((SpringSecurityUserAuth) principal).getId(); } else { userId = authentication.getName(); } AuditDTO auditDto = new AuditDTO(); auditDto.setUserId(userId); auditDto.setAuditTime(new Date()); auditDto.setAction("login"); auditDto.setResult("failure"); auditDto.setApplication("lemon"); auditDto.setClient(getUserIp(authentication)); auditDto.setServer(InetAddress.getLocalHost().getHostAddress()); auditDto.setDescription(authenticationFailureBadCredentialsEvent .getException().getMessage()); auditDto.setTenantId(tenantId); auditConnector.log(auditDto); ctx.publishEvent(new LoginEvent(authentication, userId, this .getSessionId(authentication), "badCredentials", "default", tenantId)); }
/** * On login failure we record the failing email address and ip address * * @param e bad credentials event */ @Override public void onApplicationEvent(final AuthenticationFailureBadCredentialsEvent e) { final WebAuthenticationDetails auth = (WebAuthenticationDetails) e.getAuthentication().getDetails(); final String email = e.getAuthentication().getPrincipal().toString(); loginAttemptService.loginFailed(email, auth.getRemoteAddress()); }
@Test public void testAuditLogin_failure() { final String error = "exception message"; final AbstractAuthenticationFailureEvent event = new AuthenticationFailureBadCredentialsEvent( authMock, new BadCredentialsException(error)); auditService.auditLoginFailureEvent(event); verify(accountActivityMessageRepository, times(1)) .save(argThat(matches(false, username, error))); verifyNoMoreInteractions(accountActivityMessageRepository); }
@Override public void onApplicationEvent(final AuthenticationFailureBadCredentialsEvent e) { final WebAuthenticationDetails auth = (WebAuthenticationDetails) e.getAuthentication().getDetails(); if (auth != null) { loginAttemptService.loginFailed(auth.getRemoteAddress()); } }
private void pingAuthenticationListener() { AuthenticationListener listener = new AuthenticationListener(); this.context.addApplicationListener(listener); AuthenticationManager manager = this.context.getBean(AuthenticationManager.class); try { manager.authenticate(new UsernamePasswordAuthenticationToken("foo", "wrong")); fail("Expected BadCredentialsException"); } catch (BadCredentialsException e) { // expected } assertThat(listener.event) .isInstanceOf(AuthenticationFailureBadCredentialsEvent.class); }
@Override public void onApplicationEvent(final AuthenticationFailureBadCredentialsEvent e) { // final WebAuthenticationDetails auth = (WebAuthenticationDetails) e.getAuthentication().getDetails(); // if (auth != null) { // loginAttemptService.loginFailed(auth.getRemoteAddress()); // } final String xfHeader = request.getHeader("X-Forwarded-For"); if (xfHeader == null) { loginAttemptService.loginFailed(request.getRemoteAddr()); } else { loginAttemptService.loginFailed(xfHeader.split(",")[0]); } }
private void pingAuthenticationListener() { AuthenticationListener listener = new AuthenticationListener(); this.context.addApplicationListener(listener); AuthenticationManager manager = this.context.getBean(AuthenticationManager.class); try { manager.authenticate(new UsernamePasswordAuthenticationToken("foo", "wrong")); fail("Expected BadCredentialsException"); } catch (BadCredentialsException e) { // expected } assertTrue("Wrong event type: " + listener.event, listener.event instanceof AuthenticationFailureBadCredentialsEvent); }
@Override public void onApplicationEvent(AuthenticationFailureBadCredentialsEvent event) { this.transactionTemplate.execute(ts -> { updateLockedProperties(event); return null; }); }
@Override @Transactional(propagation = Propagation.REQUIRES_NEW) public void onApplicationEvent(final AuthenticationFailureBadCredentialsEvent event) { repository.findByUsername((String) event.getAuthentication().getPrincipal()) .ifPresent(account -> updateAccount(account)); }
@Test public void testHandle_when_account_is_not_locked() { AuthenticationFailureBadCredentialsEvent loginFailureEvent=mock(AuthenticationFailureBadCredentialsEvent.class); Authentication authentication=mock(Authentication.class); Object name=new String(username); when(loginFailureEvent.getAuthentication()).thenReturn(authentication); when(authentication.getPrincipal()).thenReturn(name); Users user=mock(Users.class); when(user.getFailedLoginAttempts()).thenReturn(0); when(usersRepository.loadUserByUsername(username)).thenReturn(user); loginFailureEventListener.handle(loginFailureEvent); verify(usersRepository).updateUser(user); }
@Test public void testHandle_when_account_is_locked() { AuthenticationFailureBadCredentialsEvent loginFailureEvent=mock(AuthenticationFailureBadCredentialsEvent.class); Authentication authentication=mock(Authentication.class); Object name=new String(username); when(loginFailureEvent.getAuthentication()).thenReturn(authentication); when(authentication.getPrincipal()).thenReturn(name); Users user=mock(Users.class); when(user.getFailedLoginAttempts()).thenReturn(3); when(usersRepository.loadUserByUsername(username)).thenReturn(user); loginFailureEventListener.handle(loginFailureEvent); verify(user).setLockoutTime(any(Calendar.class)); verify(usersRepository).updateUser(user); }
@Override public void onAuthenticationFailure( HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) throws IOException, ServletException { if (exception instanceof BadCredentialsException) { String name = request.getParameter("username"); String password = request.getParameter("password"); Authentication auth = new UsernamePasswordAuthenticationToken(name, password); eventPublisher.publishEvent( new AuthenticationFailureBadCredentialsEvent(auth, exception)); } super.onAuthenticationFailure(request, response, exception); }
public void testAuthenticationFailureEvent() throws Exception { String userName = "bar"; String ip = "1.2.3.4"; String sessionId = "it tastes just like our regular coffee"; HttpServletRequest request = createMock(HttpServletRequest.class); HttpSession session = createMock(HttpSession.class); expect(request.getRemoteAddr()).andReturn(ip); expect(request.getSession(false)).andReturn(session); expect(session.getId()).andReturn(sessionId); replay(request, session); WebAuthenticationDetails details = new WebAuthenticationDetails(request); verify(request, session); org.springframework.security.core.Authentication authentication = new TestingDetailsAuthenticationToken(userName, "cheesiness", new GrantedAuthority[0], details); AuthenticationFailureBadCredentialsEvent authEvent = new AuthenticationFailureBadCredentialsEvent(authentication, new BadCredentialsException("you are bad!")); SecurityAuthenticationEventOnmsEventBuilder builder = new SecurityAuthenticationEventOnmsEventBuilder(); builder.setEventProxy(m_eventProxy); builder.afterPropertiesSet(); EventBuilder eventBuilder = new EventBuilder(SecurityAuthenticationEventOnmsEventBuilder.FAILURE_UEI, "OpenNMS.WebUI"); eventBuilder.addParam("user", userName); eventBuilder.addParam("ip", ip); eventBuilder.addParam("exceptionName", authEvent.getException().getClass().getSimpleName()); eventBuilder.addParam("exceptionMessage", authEvent.getException().getMessage()); m_eventProxy.send(EventEquals.eqEvent(eventBuilder.getEvent())); m_mocks.replayAll(); builder.onApplicationEvent(authEvent); m_mocks.verifyAll(); }
@Override public void onApplicationEvent(AuthenticationFailureBadCredentialsEvent event) { Authentication authentication = event.getAuthentication(); saveEvent(loginlogService, authentication); }
@Override public boolean canHandle(Object event) { return event instanceof AuthenticationFailureBadCredentialsEvent; }
@Test public void testCanHandle_when_event_matches() { AuthenticationFailureBadCredentialsEvent event=mock(AuthenticationFailureBadCredentialsEvent.class); assertEquals(loginFailureEventListener.canHandle(event),true); }
@Test public void testCanHandle_when_event_unmatch() { AuthenticationFailureBadCredentialsEvent event=mock(AuthenticationFailureBadCredentialsEvent.class); assertEquals(loginSuccessEventListener.canHandle(event),false); }
@Override public void onApplicationEvent(AuthenticationFailureBadCredentialsEvent event) { onAjaxFailure(request.get()); }
@ExtDirectMethod(ExtDirectMethodType.FORM_POST) @PreAuthorize("hasAuthority('PRE_AUTH')") @Transactional public ExtDirectFormPostResult signin2fa(HttpServletRequest request, @AuthenticationPrincipal JpaUserDetails jpaUserDetails, @RequestParam("code") int code) { User user = jpaUserDetails.getUser(this.jpaQueryFactory); if (user != null) { if (TotpAuthUtil.verifyCode(user.getSecret(), code, 3)) { user.setLastAccess(ZonedDateTime.now(ZoneOffset.UTC)); jpaUserDetails.grantAuthorities(); Authentication newAuth = new UsernamePasswordAuthenticationToken( jpaUserDetails, null, jpaUserDetails.getAuthorities()); SecurityContextHolder.getContext().setAuthentication(newAuth); ExtDirectFormPostResult result = new ExtDirectFormPostResult(); result.addResultProperty(AUTH_USER, new UserDetailDto(jpaUserDetails, user, CsrfController.getCsrfToken(request))); return result; } BadCredentialsException excp = new BadCredentialsException( "Bad verification code"); AuthenticationFailureBadCredentialsEvent event = new AuthenticationFailureBadCredentialsEvent( SecurityContextHolder.getContext().getAuthentication(), excp); this.applicationEventPublisher.publishEvent(event); user = jpaUserDetails.getUser(this.jpaQueryFactory); if (user.getLockedOutUntil() != null) { HttpSession session = request.getSession(false); if (session != null) { Application.logger.debug("Invalidating session: " + session.getId()); session.invalidate(); } SecurityContext context = SecurityContextHolder.getContext(); context.setAuthentication(null); SecurityContextHolder.clearContext(); } } return new ExtDirectFormPostResult(false); }
private void updateLockedProperties(AuthenticationFailureBadCredentialsEvent event) { Object principal = event.getAuthentication().getPrincipal(); if (this.loginLockAttempts != null && (principal instanceof String || principal instanceof JpaUserDetails)) { User user = null; if (principal instanceof String) { user = this.jpaQueryFactory.selectFrom(QUser.user) .where(QUser.user.loginName.eq((String) principal)) .where(QUser.user.deleted.isFalse()).fetchFirst(); } else { user = ((JpaUserDetails) principal).getUser(this.jpaQueryFactory); } if (user != null) { if (user.getFailedLogins() == null) { user.setFailedLogins(1); } else { user.setFailedLogins(user.getFailedLogins() + 1); } if (user.getFailedLogins() >= this.loginLockAttempts) { if (this.loginLockMinutes != null) { user.setLockedOutUntil(ZonedDateTime.now(ZoneOffset.UTC) .plusMinutes(this.loginLockMinutes)); } else { user.setLockedOutUntil( ZonedDateTime.now(ZoneOffset.UTC).plusYears(1000)); } } this.jpaQueryFactory.getEntityManager().merge(user); } else { Application.logger.warn("Unknown user login attempt: {}", principal); } } else { Application.logger.warn("Invalid login attempt: {}", principal); } }
@ExtDirectMethod(ExtDirectMethodType.FORM_POST) @PreAuthorize("hasAuthority('PRE_AUTH')") public ExtDirectFormPostResult signin2fa(HttpServletRequest request, @AuthenticationPrincipal MongoUserDetails userDetails, @RequestParam("code") int code) { User user = userDetails.getUser(this.mongoDb); if (user != null) { if (TotpAuthUtil.verifyCode(user.getSecret(), code, 3)) { this.mongoDb.getCollection(User.class).updateOne( Filters.eq(CUser.id, userDetails.getUserDbId()), Updates.set(CUser.lastAccess, new Date())); userDetails.grantAuthorities(); Authentication newAuth = new UsernamePasswordAuthenticationToken( userDetails, null, userDetails.getAuthorities()); SecurityContextHolder.getContext().setAuthentication(newAuth); ExtDirectFormPostResult result = new ExtDirectFormPostResult(); result.addResultProperty(AUTH_USER, new UserDetailDto(userDetails, user, CsrfController.getCsrfToken(request))); return result; } BadCredentialsException excp = new BadCredentialsException( "Bad verification code"); AuthenticationFailureBadCredentialsEvent event = new AuthenticationFailureBadCredentialsEvent( SecurityContextHolder.getContext().getAuthentication(), excp); this.applicationEventPublisher.publishEvent(event); user = userDetails.getUser(this.mongoDb); if (user.getLockedOutUntil() != null) { HttpSession session = request.getSession(false); if (session != null) { Application.logger.debug("Invalidating session: " + session.getId()); session.invalidate(); } SecurityContext context = SecurityContextHolder.getContext(); context.setAuthentication(null); SecurityContextHolder.clearContext(); } } return new ExtDirectFormPostResult(false); }
@Override public void onApplicationEvent(AuthenticationFailureBadCredentialsEvent event) { updateLockedProperties(event); }
private void updateLockedProperties(AuthenticationFailureBadCredentialsEvent event) { Object principal = event.getAuthentication().getPrincipal(); if (this.loginLockAttempts != null && (principal instanceof String || principal instanceof MongoUserDetails)) { User user = null; if (principal instanceof String) { user = this.mongoDb.getCollection(User.class).findOneAndUpdate( Filters.and(Filters.eq(CUser.loginName, principal), Filters.eq(CUser.deleted, false)), Updates.inc(CUser.failedLogins, 1), new FindOneAndUpdateOptions() .returnDocument(ReturnDocument.AFTER).upsert(false)); } else { user = this.mongoDb.getCollection(User.class).findOneAndUpdate( Filters.eq(CUser.id, ((MongoUserDetails) principal).getUserDbId()), Updates.inc(CUser.failedLogins, 1), new FindOneAndUpdateOptions() .returnDocument(ReturnDocument.AFTER).upsert(false)); } if (user != null) { if (user.getFailedLogins() >= this.loginLockAttempts) { if (this.loginLockMinutes != null) { this.mongoDb.getCollection(User.class).updateOne( Filters.eq(CUser.id, user.getId()), Updates.set(CUser.lockedOutUntil, Date.from(ZonedDateTime.now(ZoneOffset.UTC) .plusMinutes(this.loginLockMinutes) .toInstant()))); } else { this.mongoDb.getCollection(User.class) .updateOne(Filters.eq(CUser.id, user.getId()), Updates.set(CUser.lockedOutUntil, Date.from(ZonedDateTime .now(ZoneOffset.UTC) .plusYears(1000).toInstant()))); } } } else { Application.logger.warn("Unknown user login attempt: {}", principal); } } else { Application.logger.warn("Invalid login attempt: {}", principal); } }
@Bean @ConditionalOnProperty(prefix = "freezo.security.authentication.account", name = "updateOnFailure", havingValue = "true", matchIfMissing = true) public ApplicationListener<AuthenticationFailureBadCredentialsEvent> failedAuthHandler() { return new FailedAuthHandler(); }