33import org .springframework .context .event .EventListener ;
44import org .springframework .security .authentication .event .AbstractAuthenticationFailureEvent ;
55import org .springframework .security .authentication .event .AuthenticationSuccessEvent ;
6+ import org .springframework .security .oauth2 .core .user .OAuth2User ;
67import org .springframework .stereotype .Component ;
8+ import com .digitalsanctuary .spring .user .service .DSUserDetails ;
79import com .digitalsanctuary .spring .user .service .LoginAttemptService ;
810import lombok .RequiredArgsConstructor ;
911import lombok .extern .slf4j .Slf4j ;
@@ -22,28 +24,74 @@ public class AuthenticationEventListener {
2224
2325 /**
2426 * This method listens for successful authentications and handles account lockout functionality.
27+ * It properly handles different authentication types including form login, OAuth2, and OIDC.
2528 *
2629 * @param success the success event
2730 */
2831 @ EventListener
2932 public void onSuccess (AuthenticationSuccessEvent success ) {
30- // Handle successful authentication, e.g. logging or auditing
31- log .debug ("Authentication success: " + success .getAuthentication ().getName ());
32- String username = success .getAuthentication ().getName ();
33- loginAttemptService .loginSucceeded (username );
33+ // Extract username/email based on the principal type
34+ String username = null ;
35+ Object principal = success .getAuthentication ().getPrincipal ();
36+
37+ if (principal instanceof DSUserDetails ) {
38+ // Form login or custom authentication
39+ username = ((DSUserDetails ) principal ).getUsername ();
40+ log .debug ("Authentication success for DSUserDetails: {}" , username );
41+ } else if (principal instanceof OAuth2User ) {
42+ // OAuth2/OIDC authentication - try to get email
43+ OAuth2User oauth2User = (OAuth2User ) principal ;
44+ username = oauth2User .getAttribute ("email" );
45+ if (username == null ) {
46+ // Fallback to name if email is not available
47+ username = oauth2User .getName ();
48+ }
49+ log .debug ("Authentication success for OAuth2User: {}" , username );
50+ } else if (principal instanceof String ) {
51+ // Basic authentication or remember-me
52+ username = (String ) principal ;
53+ log .debug ("Authentication success for String principal: {}" , username );
54+ } else {
55+ // Fallback to getName() method for unknown principal types
56+ username = success .getAuthentication ().getName ();
57+ log .debug ("Authentication success for unknown principal type {}: {}" ,
58+ principal != null ? principal .getClass ().getName () : "null" , username );
59+ }
60+
61+ // Only process login success if we have a valid username
62+ if (username != null && !username .trim ().isEmpty ()) {
63+ loginAttemptService .loginSucceeded (username );
64+ } else {
65+ log .warn ("Could not extract valid username from authentication event - not tracking" );
66+ }
3467 }
3568
3669 /**
3770 * This method listens for authentication failures and handles account lockout functionality.
71+ * It properly handles different authentication types including form login, OAuth2, and OIDC.
3872 *
3973 * @param failure the failure event
4074 */
4175 @ EventListener
4276 public void onFailure (AbstractAuthenticationFailureEvent failure ) {
43- // Handle unsuccessful authentication, e.g. logging or auditing
44- log .debug ("Authentication failure: " + failure .getException ().getMessage ());
77+ // For failures, try to get username from getName() first (the attempted username)
4578 String username = failure .getAuthentication ().getName ();
46- loginAttemptService .loginFailed (username );
79+
80+ // If getName() is null/empty, try to extract from principal
81+ if (username == null || username .trim ().isEmpty ()) {
82+ Object principal = failure .getAuthentication ().getPrincipal ();
83+ if (principal instanceof String ) {
84+ username = (String ) principal ;
85+ }
86+ }
87+
88+ // Only process login failure if we have a valid username
89+ if (username != null && !username .trim ().isEmpty ()) {
90+ log .debug ("Authentication failure for user '{}': {}" , username , failure .getException ().getMessage ());
91+ loginAttemptService .loginFailed (username );
92+ } else {
93+ log .warn ("Could not extract valid username from authentication failure event - not tracking" );
94+ }
4795 }
4896
4997}
0 commit comments