From 9246b4205765a01e8a64fe869b389675f3f73bea Mon Sep 17 00:00:00 2001 From: Anthony Stirling <77850077+Frooodle@users.noreply.github.com> Date: Fri, 8 Mar 2024 18:06:40 +0000 Subject: [PATCH] Login fixes (#881) * init * user and pass to just pass lang update * session management fixes and avoid demo user locking * Hardening suggestions for Stirling-PDF / loginFixes (#882) Switch order of literals to prevent NullPointerException Co-authored-by: pixeebot[bot] <104101892+pixeebot[bot]@users.noreply.github.com> --------- Co-authored-by: pixeebot[bot] <104101892+pixeebot[bot]@users.noreply.github.com> --- .../CustomAuthenticationFailureHandler.java | 33 ++++++++++++++----- .../security/SecurityConfiguration.java | 17 ++++++++-- 2 files changed, 39 insertions(+), 11 deletions(-) diff --git a/src/main/java/stirling/software/SPDF/config/security/CustomAuthenticationFailureHandler.java b/src/main/java/stirling/software/SPDF/config/security/CustomAuthenticationFailureHandler.java index cbdf7d26..038e087f 100644 --- a/src/main/java/stirling/software/SPDF/config/security/CustomAuthenticationFailureHandler.java +++ b/src/main/java/stirling/software/SPDF/config/security/CustomAuthenticationFailureHandler.java @@ -1,6 +1,7 @@ package stirling.software.SPDF.config.security; import java.io.IOException; +import java.util.Optional; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.authentication.BadCredentialsException; @@ -12,15 +13,19 @@ import org.springframework.stereotype.Component; import jakarta.servlet.ServletException; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; +import stirling.software.SPDF.model.User; @Component public class CustomAuthenticationFailureHandler extends SimpleUrlAuthenticationFailureHandler { @Autowired private final LoginAttemptService loginAttemptService; - @Autowired - public CustomAuthenticationFailureHandler(LoginAttemptService loginAttemptService) { + @Autowired private final UserService userService; // Inject the UserService + + public CustomAuthenticationFailureHandler( + LoginAttemptService loginAttemptService, UserService userService) { this.loginAttemptService = loginAttemptService; + this.userService = userService; } @Override @@ -33,17 +38,27 @@ public class CustomAuthenticationFailureHandler extends SimpleUrlAuthenticationF logger.error("Failed login attempt from IP: " + ip); String username = request.getParameter("username"); - if (loginAttemptService.loginAttemptCheck(username)) { - setDefaultFailureUrl("/login?error=locked"); - - } else { - if (exception.getClass().isAssignableFrom(BadCredentialsException.class)) { - setDefaultFailureUrl("/login?error=badcredentials"); - } else if (exception.getClass().isAssignableFrom(LockedException.class)) { + if (!isDemoUser(username)) { + if (loginAttemptService.loginAttemptCheck(username)) { setDefaultFailureUrl("/login?error=locked"); + + } else { + if (exception.getClass().isAssignableFrom(LockedException.class)) { + setDefaultFailureUrl("/login?error=locked"); + } } } + if (exception.getClass().isAssignableFrom(BadCredentialsException.class)) { + setDefaultFailureUrl("/login?error=badcredentials"); + } super.onAuthenticationFailure(request, response, exception); } + + private boolean isDemoUser(String username) { + Optional user = userService.findByUsername(username); + return user.isPresent() + && user.get().getAuthorities().stream() + .anyMatch(authority -> "ROLE_DEMO_USER".equals(authority.getAuthority())); + } } diff --git a/src/main/java/stirling/software/SPDF/config/security/SecurityConfiguration.java b/src/main/java/stirling/software/SPDF/config/security/SecurityConfiguration.java index 76d78aaf..1f171136 100644 --- a/src/main/java/stirling/software/SPDF/config/security/SecurityConfiguration.java +++ b/src/main/java/stirling/software/SPDF/config/security/SecurityConfiguration.java @@ -21,6 +21,7 @@ import org.springframework.security.web.authentication.rememberme.PersistentToke import org.springframework.security.web.savedrequest.NullRequestCache; import org.springframework.security.web.util.matcher.AntPathRequestMatcher; +import jakarta.servlet.http.HttpSession; import stirling.software.SPDF.repository.JPATokenRepositoryImpl; @Configuration @@ -78,7 +79,7 @@ public class SecurityConfiguration { .defaultSuccessUrl("/") .failureHandler( new CustomAuthenticationFailureHandler( - loginAttemptService)) + loginAttemptService, userService)) .permitAll()) .requestCache(requestCache -> requestCache.requestCache(new NullRequestCache())) .logout( @@ -87,7 +88,19 @@ public class SecurityConfiguration { new AntPathRequestMatcher("/logout")) .logoutSuccessUrl("/login?logout=true") .invalidateHttpSession(true) // Invalidate session - .deleteCookies("JSESSIONID", "remember-me")) + .deleteCookies("JSESSIONID", "remember-me") + .addLogoutHandler( + (request, response, authentication) -> { + HttpSession session = + request.getSession( + false); + if (session != null) { + String sessionId = session.getId(); + sessionRegistry() + .removeSessionInformation( + sessionId); + } + })) .rememberMe( rememberMeConfigurer -> rememberMeConfigurer // Use the configurator directly