]> git.aero2k.de Git - tmp/jakarta-migration.git/commitdiff
Fix last login time updated too frequently, and delete expired oauth tokens on login...
authorRay Lee <ray.lee@lyrasis.org>
Thu, 7 Mar 2024 04:56:33 +0000 (23:56 -0500)
committerRay Lee <ray.lee@lyrasis.org>
Thu, 7 Mar 2024 04:56:33 +0000 (23:56 -0500)
The last login time was being updated when an authorization success event was triggered from a JWT token, which is now basically every request. A JWT token indicates a continuing session, not what a user would consider a log in event.

services/authentication/service/src/main/java/org/collectionspace/authentication/CSpaceAuthenticationSuccessEvent.java

index 363365e2a0371e2a64a94974b131b3328175cc5f..363719df3c0356e4a45414c53788b7877484651c 100644 (file)
@@ -13,30 +13,49 @@ import org.postgresql.util.PSQLState;
 import org.springframework.context.ApplicationListener;
 import org.springframework.security.authentication.event.AuthenticationSuccessEvent;
 import org.springframework.security.core.Authentication;
+import org.springframework.security.oauth2.server.authorization.authentication.OAuth2AuthorizationCodeRequestAuthenticationToken;
+import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationToken;
 
 public class CSpaceAuthenticationSuccessEvent implements ApplicationListener<AuthenticationSuccessEvent> {
 
-       private static final String UPDATE_USER_SQL =
-                       "UPDATE users SET lastlogin = now() WHERE username = ?";
+    private static final String UPDATE_USER_SQL =
+            "UPDATE users SET lastlogin = now() WHERE username = ?";
 
-       @Override
-       public void onApplicationEvent(AuthenticationSuccessEvent event) {
-               if (event.getSource() instanceof Authentication) {
-                       Authentication eventSource = (Authentication) event.getSource();
+    private static final String DELETE_EXPIRED_AUTHORIZATIONS_SQL =
+            "DELETE FROM oauth2_authorization WHERE access_token_expires_at < now()";
 
-                       if (eventSource.getPrincipal() instanceof CSpaceUser) {
-                               CSpaceDbRealm cspaceDbRealm = new CSpaceDbRealm();
-                               CSpaceUser cspaceUser = (CSpaceUser) eventSource.getPrincipal();
-                               String username = cspaceUser.getUsername();
+    @Override
+    public void onApplicationEvent(AuthenticationSuccessEvent event) {
+        Object eventSource = event.getSource();
 
-                               try {
-                                       setLastLogin(cspaceDbRealm, username);
-                               } catch (Exception e) {
-                                       e.printStackTrace();
-                               }
-                       }
-               }
-       }
+        if (
+            eventSource instanceof Authentication
+            // Ignore authentication via JWT token, since this indicates a continuing session -- not what a user would consider a "log in"
+            && !(eventSource instanceof JwtAuthenticationToken)
+            // Ignore authorization code requests
+            && !(eventSource instanceof OAuth2AuthorizationCodeRequestAuthenticationToken)
+        ) {
+            Authentication authentication = (Authentication) eventSource;
+
+            if (authentication.getPrincipal() instanceof CSpaceUser) {
+                CSpaceDbRealm cspaceDbRealm = new CSpaceDbRealm();
+                CSpaceUser cspaceUser = (CSpaceUser) authentication.getPrincipal();
+                String username = cspaceUser.getUsername();
+
+                try {
+                    setLastLogin(cspaceDbRealm, username);
+                } catch (Exception e) {
+                    e.printStackTrace();
+                }
+
+                try {
+                    deleteExpiredAuthorizations(cspaceDbRealm);
+                } catch (Exception e) {
+                    e.printStackTrace();
+                }
+            }
+        }
+    }
 
        private void setLastLogin(CSpaceDbRealm cspaceDbRealm, String username) throws AccountException {
         Connection conn = null;
@@ -88,4 +107,39 @@ public class CSpaceAuthenticationSuccessEvent implements ApplicationListener<Aut
             }
         }
     }
+
+    private void deleteExpiredAuthorizations(CSpaceDbRealm cspaceDbRealm) throws AccountException {
+        Connection conn = null;
+        PreparedStatement ps = null;
+        ResultSet rs = null;
+
+        try {
+            conn = cspaceDbRealm.getConnection();
+            ps = conn.prepareStatement(DELETE_EXPIRED_AUTHORIZATIONS_SQL);
+            ps.executeUpdate();
+        } catch (Exception ex) {
+            AccountException ae = new AccountException("Unknown Exception");
+            ae.initCause(ex);
+            throw ae;
+        } finally {
+            if (rs != null) {
+                try {
+                    rs.close();
+                } catch (SQLException e) {
+                }
+            }
+            if (ps != null) {
+                try {
+                    ps.close();
+                } catch (SQLException e) {
+                }
+            }
+            if (conn != null) {
+                try {
+                    conn.close();
+                } catch (SQLException ex) {
+                }
+            }
+        }
+    }
 }