AEMaaCS – User’s list based on Last Login Date | Community
Skip to main content
BrijeshYadav
Level 5
June 26, 2025
Solved

AEMaaCS – User’s list based on Last Login Date

  • June 26, 2025
  • 1 reply
  • 354 views

Hi, As we know, the lastLogin attribute is not natively provided by AEM in any version. For the AEM on-premise environments, we were able to capture this information by implementing an AuthenticationInfoPostProcessor or by tracking the user token expiry.

However, with AEM as a Cloud Service (AEMaaCS), these approaches don’t appear to be technically feasible due to platform restrictions.

Could you please share your expert insights on how we can achieve similar functionality in AEMaaCS? Any recommended best practices or workarounds would be greatly appreciated

Regards
Brijesh Yadav

This post is no longer active and is closed to new replies. Need help? Start a new post to ask your question.
Best answer by ButhpurKiran

Hi Brijesh,


One approach could be creating custom handler, below is skeleton version(used for our app) and you can add respective code in @9944223 methods

PS: Below class denotes Okta specific platform that can get interchanged according your desired platform

package com.example.aem.auth; import org.apache.sling.auth.core.spi.AuthenticationHandler; import org.apache.sling.auth.core.spi.AuthenticationInfo; import org.apache.sling.api.resource.ResourceResolver; import org.apache.sling.api.servlets.SlingSafeMethodsServlet; import org.osgi.framework.Constants; import org.osgi.service.component.annotations.Component; import org.osgi.service.component.annotations.Reference; import javax.servlet.Servlet; import javax.servlet.ServletException; import java.io.IOException; import java.util.Map; @Component(service = Servlet.class, property = { Constants.SERVICE_DESCRIPTION + "=Okta Authentication Handler", "sling.servlet.methods=GET", "sling.servlet.paths=/bin/okta-auth" }) public class OktaAuthenticationHandler extends SlingSafeMethodsServlet implements AuthenticationHandler { @3214626 private OktaService oktaService; @9944223 protected void doGet(SlingHttpServletRequest request, SlingHttpServletResponse response) throws ServletException, IOException { String code = request.getParameter("codexxx"); if (code != null) { String accessToken = oktaService.exchangeCodeForToken(code); Map<String, Object> userProfile = oktaService.getUserProfile(accessToken); String userId = (String) userProfile.get("subServiceUser"); // Create or authenticate the user in AEM authenticateUser(userId); // Log the login event logLoginEvent(userId); // Proceed with the request response.getWriter().write("Authentication successful"); } else { // Redirect to Okta for authentication String authorizationUrl = oktaService.getAuthorizationUrl(); response.sendRedirect(authorizationUrl); } } private void authenticateUser(String userId) { // Implement user authentication logic here } private void logLoginEvent(String userId) { // Implement login event logging logic here } @9944223 public AuthenticationInfo extractCredentials(HttpServletRequest request, HttpServletResponse response) { // Implement credential extraction logic here return null; } @9944223 public boolean requestCredentials(HttpServletRequest request, HttpServletResponse response) throws IOException { // Implement credential request logic here return false; } @9944223 public void dropCredentials(HttpServletRequest request, HttpServletResponse response) throws IOException { // Implement credential drop logic here } @9944223 public boolean authenticationSucceeded(HttpServletRequest request, HttpServletResponse response, AuthenticationInfo authInfo) { // Implement authentication success logic here return true; } @9944223 public void authenticationFailed(HttpServletRequest request, HttpServletResponse response, AuthenticationInfo authInfo) { // Implement authentication failure logic here } }

  

Thanks

 

Kind regards,

Kiran Buthpur

1 reply

ButhpurKiran
ButhpurKiranAccepted solution
Level 4
June 26, 2025

Hi Brijesh,


One approach could be creating custom handler, below is skeleton version(used for our app) and you can add respective code in @9944223 methods

PS: Below class denotes Okta specific platform that can get interchanged according your desired platform

package com.example.aem.auth; import org.apache.sling.auth.core.spi.AuthenticationHandler; import org.apache.sling.auth.core.spi.AuthenticationInfo; import org.apache.sling.api.resource.ResourceResolver; import org.apache.sling.api.servlets.SlingSafeMethodsServlet; import org.osgi.framework.Constants; import org.osgi.service.component.annotations.Component; import org.osgi.service.component.annotations.Reference; import javax.servlet.Servlet; import javax.servlet.ServletException; import java.io.IOException; import java.util.Map; @Component(service = Servlet.class, property = { Constants.SERVICE_DESCRIPTION + "=Okta Authentication Handler", "sling.servlet.methods=GET", "sling.servlet.paths=/bin/okta-auth" }) public class OktaAuthenticationHandler extends SlingSafeMethodsServlet implements AuthenticationHandler { @3214626 private OktaService oktaService; @9944223 protected void doGet(SlingHttpServletRequest request, SlingHttpServletResponse response) throws ServletException, IOException { String code = request.getParameter("codexxx"); if (code != null) { String accessToken = oktaService.exchangeCodeForToken(code); Map<String, Object> userProfile = oktaService.getUserProfile(accessToken); String userId = (String) userProfile.get("subServiceUser"); // Create or authenticate the user in AEM authenticateUser(userId); // Log the login event logLoginEvent(userId); // Proceed with the request response.getWriter().write("Authentication successful"); } else { // Redirect to Okta for authentication String authorizationUrl = oktaService.getAuthorizationUrl(); response.sendRedirect(authorizationUrl); } } private void authenticateUser(String userId) { // Implement user authentication logic here } private void logLoginEvent(String userId) { // Implement login event logging logic here } @9944223 public AuthenticationInfo extractCredentials(HttpServletRequest request, HttpServletResponse response) { // Implement credential extraction logic here return null; } @9944223 public boolean requestCredentials(HttpServletRequest request, HttpServletResponse response) throws IOException { // Implement credential request logic here return false; } @9944223 public void dropCredentials(HttpServletRequest request, HttpServletResponse response) throws IOException { // Implement credential drop logic here } @9944223 public boolean authenticationSucceeded(HttpServletRequest request, HttpServletResponse response, AuthenticationInfo authInfo) { // Implement authentication success logic here return true; } @9944223 public void authenticationFailed(HttpServletRequest request, HttpServletResponse response, AuthenticationInfo authInfo) { // Implement authentication failure logic here } }

  

Thanks

 

Kind regards,

Kiran Buthpur