From 25013d7ccb38b2a6108eaba7ef3a086bec1f2711 Mon Sep 17 00:00:00 2001 From: Anthony Stirling <77850077+Frooodle@users.noreply.github.com.> Date: Fri, 5 Sep 2025 19:09:57 +0100 Subject: [PATCH] login_fix --- .../service/CustomUserDetailsService.java | 46 ++++++++++++++++++- 1 file changed, 45 insertions(+), 1 deletion(-) diff --git a/app/proprietary/src/main/java/stirling/software/proprietary/security/service/CustomUserDetailsService.java b/app/proprietary/src/main/java/stirling/software/proprietary/security/service/CustomUserDetailsService.java index 1704e5972..969d04c4f 100644 --- a/app/proprietary/src/main/java/stirling/software/proprietary/security/service/CustomUserDetailsService.java +++ b/app/proprietary/src/main/java/stirling/software/proprietary/security/service/CustomUserDetailsService.java @@ -8,6 +8,7 @@ import org.springframework.stereotype.Service; import lombok.RequiredArgsConstructor; +import stirling.software.common.model.ApplicationProperties; import stirling.software.proprietary.security.database.repository.UserRepository; import stirling.software.proprietary.security.model.AuthenticationType; import stirling.software.proprietary.security.model.User; @@ -20,6 +21,8 @@ public class CustomUserDetailsService implements UserDetailsService { private final LoginAttemptService loginAttemptService; + private final ApplicationProperties.Security securityProperties; + @Override public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { User user = @@ -35,12 +38,53 @@ public class CustomUserDetailsService implements UserDetailsService { "Your account has been locked due to too many failed login attempts."); } + // Handle legacy users without authenticationType (from versions < 1.3.0) + String authTypeStr = user.getAuthenticationType(); + if (authTypeStr == null || authTypeStr.isEmpty()) { + // Migrate legacy users by detecting authentication type based on password presence + AuthenticationType detectedType; + if (user.hasPassword()) { + // Users with passwords are likely traditional web authentication users + detectedType = AuthenticationType.WEB; + } else { + // Users without passwords are SSO users (OAuth2/SAML2/etc) + // Choose the appropriate SSO type based on what's enabled + detectedType = determinePreferredSSOType(); + } + + authTypeStr = detectedType.name(); + // Update the user record to set the detected authentication type + user.setAuthenticationType(detectedType); + userRepository.save(user); + } + AuthenticationType userAuthenticationType = - AuthenticationType.valueOf(user.getAuthenticationType().toUpperCase()); + AuthenticationType.valueOf(authTypeStr.toUpperCase()); if (!user.hasPassword() && userAuthenticationType == AuthenticationType.WEB) { throw new IllegalArgumentException("Password must not be null"); } return user; } + + /** + * Determines the preferred SSO authentication type based on what's enabled in the application + * configuration. + * + * @return The preferred AuthenticationType for SSO users + */ + private AuthenticationType determinePreferredSSOType() { + // Check what SSO types are enabled and prefer in order: OAUTH2 > SAML2 > fallback to OAUTH2 + boolean oauth2Enabled = securityProperties.getOauth2().getEnabled(); + boolean saml2Enabled = securityProperties.getSaml2().getEnabled(); + + if (oauth2Enabled) { + return AuthenticationType.OAUTH2; + } else if (saml2Enabled) { + return AuthenticationType.SAML2; + } else { + // Fallback to OAUTH2 (better than deprecated SSO) + return AuthenticationType.OAUTH2; + } + } }