88
99import lombok .RequiredArgsConstructor ;
1010
11+ import stirling .software .common .model .ApplicationProperties ;
1112import stirling .software .proprietary .security .database .repository .UserRepository ;
1213import stirling .software .proprietary .security .model .AuthenticationType ;
1314import stirling .software .proprietary .security .model .User ;
@@ -20,6 +21,8 @@ public class CustomUserDetailsService implements UserDetailsService {
2021
2122 private final LoginAttemptService loginAttemptService ;
2223
24+ private final ApplicationProperties .Security securityProperties ;
25+
2326 @ Override
2427 public UserDetails loadUserByUsername (String username ) throws UsernameNotFoundException {
2528 User user =
@@ -35,12 +38,53 @@ public UserDetails loadUserByUsername(String username) throws UsernameNotFoundEx
3538 "Your account has been locked due to too many failed login attempts." );
3639 }
3740
41+ // Handle legacy users without authenticationType (from versions < 1.3.0)
42+ String authTypeStr = user .getAuthenticationType ();
43+ if (authTypeStr == null || authTypeStr .isEmpty ()) {
44+ // Migrate legacy users by detecting authentication type based on password presence
45+ AuthenticationType detectedType ;
46+ if (user .hasPassword ()) {
47+ // Users with passwords are likely traditional web authentication users
48+ detectedType = AuthenticationType .WEB ;
49+ } else {
50+ // Users without passwords are SSO users (OAuth2/SAML2/etc)
51+ // Choose the appropriate SSO type based on what's enabled
52+ detectedType = determinePreferredSSOType ();
53+ }
54+
55+ authTypeStr = detectedType .name ();
56+ // Update the user record to set the detected authentication type
57+ user .setAuthenticationType (detectedType );
58+ userRepository .save (user );
59+ }
60+
3861 AuthenticationType userAuthenticationType =
39- AuthenticationType .valueOf (user . getAuthenticationType () .toUpperCase ());
62+ AuthenticationType .valueOf (authTypeStr .toUpperCase ());
4063 if (!user .hasPassword () && userAuthenticationType == AuthenticationType .WEB ) {
4164 throw new IllegalArgumentException ("Password must not be null" );
4265 }
4366
4467 return user ;
4568 }
69+
70+ /**
71+ * Determines the preferred SSO authentication type based on what's enabled in the application
72+ * configuration.
73+ *
74+ * @return The preferred AuthenticationType for SSO users
75+ */
76+ private AuthenticationType determinePreferredSSOType () {
77+ // Check what SSO types are enabled and prefer in order: OAUTH2 > SAML2 > fallback to OAUTH2
78+ boolean oauth2Enabled = securityProperties .getOauth2 () != null && securityProperties .getOauth2 ().getEnabled ();
79+ boolean saml2Enabled = securityProperties .getSaml2 () != null && securityProperties .getSaml2 ().getEnabled ();
80+
81+ if (oauth2Enabled ) {
82+ return AuthenticationType .OAUTH2 ;
83+ } else if (saml2Enabled ) {
84+ return AuthenticationType .SAML2 ;
85+ } else {
86+ // Fallback to OAUTH2 (better than deprecated SSO)
87+ return AuthenticationType .OAUTH2 ;
88+ }
89+ }
4690}
0 commit comments