Expand my Community achievements bar.

Guidelines for the Responsible Use of Generative AI in the Experience Cloud Community.
SOLVED

AEM CUG - Enable authentication but using external login API and token

Avatar

Level 1

Hi All,

I an novice in AEM and recently have gotten a use case to do gated AEM assets (images, pdf & etc) for external users that do not sits in AEM's user/group, I've studied the CUG authentication features from a few Internet sources, I notice the authentication is mainly performed against the OOTB AEM login module, and seldom elaborate on how it works if I were to provide a custom login page link. Hence, I have a few related queries here, hopefully any folks with similar experiences or experts can shed some light.

  1. From the gated asset folder, possible to put a custom login page link that calling an external login API?
    Then10_1-1676790407662.png
  2. If #1 is possible, assume the external login API authenticated successfully and return an login token, how can I make use of this login token and communicate with AEM that this user has login successfully? and hence can allow the user to view/read the gated asset.
  3. From my knowledge, the permission on CUG seems to work with AEM's user/group only, it might not work with non-AEM's user/group. Wild idea: what if I create a "read-only AEM user/group" so that whenever the external login API come back with a login token, I can treat it as a condition/validation to trigger the AEM login using the "read-only AEM user/group", programmatically thru client-side code (eg: invoke this API "/libs/granite/core/content/login.html"), or AEM already have similar login API exposed?

I appreciate any responses with comments/corrections, advises, better solutions or references on this matter. 

Sorry for the long read, I just wanted to ensure that my words fully express my ideas and thoughts.

Thanks for your time.

1 Accepted Solution

Avatar

Correct answer by
Level 5

You can create a custom logic page and have custom authentication handler written to validate the behavior, below are the steps to do so.

  1. Create a custom login page that will be used to authenticate the user. This page should have a form that the user will fill in with their credentials.
  2. When the user submits the login form, the form data should be sent to your external login API for authentication (You can achieve this using servlet call).
  3. Write a service class which calls from servlet If the user's credentials are valid, the API should return a login token to the custom login page(from servlet).
  4. The custom login page should then send the login token to AEM, along with a request to log the user in.
  5. you can create a custom authentication handler that will validate the login token and create a session for the user. You can use this session to control access to gated assets.

Custom Authentication Handler Example:

@component(service = Authenticator.class)
public class MyCustomAuthHandler implements AuthenticationHandler {

    @reference
    private ResourceResolverFactory resourceResolverFactory;

    @Override
    public AuthenticationInfo extractCredentials(SlingHttpServletRequest request, 
                                                  AuthenticateCallback callback) 
                                                  throws NoAuthenticationHandlerException {
        // Extract the login token from the request
        String loginToken = request.getParameter("loginToken");
        
        // Call your external login API to authenticate the user and retrieve their details
        
        
        // If authentication succeeds, create a session for the user
        ResourceResolver resourceResolver = null;
        try {
            resourceResolver = resourceResolverFactory.getServiceResourceResolver(null);
            UserManager userManager = resourceResolver.adaptTo(UserManager.class);
            
           
            // Create a session for the user and return the authentication info
            return new AuthenticationInfo("myCustomAuthType", "userId", 
                                           "UserPassword".toCharArray());
        } catch (Exception e) {
            // Handle any exceptions that may occur
            // ...
        } finally {
            if (resourceResolver != null && resourceResolver.isLive()) {
                resourceResolver.close();
            }
        }
        
        
        return null;
    }
    
    
}

Hope this is helpful.

View solution in original post

2 Replies

Avatar

Correct answer by
Level 5

You can create a custom logic page and have custom authentication handler written to validate the behavior, below are the steps to do so.

  1. Create a custom login page that will be used to authenticate the user. This page should have a form that the user will fill in with their credentials.
  2. When the user submits the login form, the form data should be sent to your external login API for authentication (You can achieve this using servlet call).
  3. Write a service class which calls from servlet If the user's credentials are valid, the API should return a login token to the custom login page(from servlet).
  4. The custom login page should then send the login token to AEM, along with a request to log the user in.
  5. you can create a custom authentication handler that will validate the login token and create a session for the user. You can use this session to control access to gated assets.

Custom Authentication Handler Example:

@component(service = Authenticator.class)
public class MyCustomAuthHandler implements AuthenticationHandler {

    @reference
    private ResourceResolverFactory resourceResolverFactory;

    @Override
    public AuthenticationInfo extractCredentials(SlingHttpServletRequest request, 
                                                  AuthenticateCallback callback) 
                                                  throws NoAuthenticationHandlerException {
        // Extract the login token from the request
        String loginToken = request.getParameter("loginToken");
        
        // Call your external login API to authenticate the user and retrieve their details
        
        
        // If authentication succeeds, create a session for the user
        ResourceResolver resourceResolver = null;
        try {
            resourceResolver = resourceResolverFactory.getServiceResourceResolver(null);
            UserManager userManager = resourceResolver.adaptTo(UserManager.class);
            
           
            // Create a session for the user and return the authentication info
            return new AuthenticationInfo("myCustomAuthType", "userId", 
                                           "UserPassword".toCharArray());
        } catch (Exception e) {
            // Handle any exceptions that may occur
            // ...
        } finally {
            if (resourceResolver != null && resourceResolver.isLive()) {
                resourceResolver.close();
            }
        }
        
        
        return null;
    }
    
    
}

Hope this is helpful.

Avatar

Administrator

@VeenaK great reply. Good to see great AEM SMEs in this community. Looking forward to your continuous contribution here.



Kautuk Sahni