Class EntraIdAuthenticator

java.lang.Object
org.codelibs.fess.sso.entraid.EntraIdAuthenticator
All Implemented Interfaces:
SsoAuthenticator

public class EntraIdAuthenticator extends Object implements SsoAuthenticator
Microsoft Entra ID SSO authenticator implementation. Handles OAuth2/OpenID Connect authentication flow with Entra ID.
  • Field Details

    • ENTRAID_STATE_TTL

      protected static final String ENTRAID_STATE_TTL
      Configuration key for Entra ID state time-to-live.
      See Also:
    • ENTRAID_AUTHORITY

      protected static final String ENTRAID_AUTHORITY
      Configuration key for Entra ID authority URL.
      See Also:
    • ENTRAID_TENANT

      protected static final String ENTRAID_TENANT
      Configuration key for Entra ID tenant ID.
      See Also:
    • ENTRAID_CLIENT_SECRET

      protected static final String ENTRAID_CLIENT_SECRET
      Configuration key for Entra ID client secret.
      See Also:
    • ENTRAID_CLIENT_ID

      protected static final String ENTRAID_CLIENT_ID
      Configuration key for Entra ID client ID.
      See Also:
    • ENTRAID_REPLY_URL

      protected static final String ENTRAID_REPLY_URL
      Configuration key for Entra ID reply URL.
      See Also:
    • ENTRAID_DEFAULT_GROUPS

      protected static final String ENTRAID_DEFAULT_GROUPS
      Configuration key for Entra ID default groups.
      See Also:
    • ENTRAID_DEFAULT_ROLES

      protected static final String ENTRAID_DEFAULT_ROLES
      Configuration key for Entra ID default roles.
      See Also:
    • AAD_STATE_TTL

      protected static final String AAD_STATE_TTL
      Legacy configuration key for Azure AD state time-to-live.
      See Also:
    • AAD_AUTHORITY

      protected static final String AAD_AUTHORITY
      Legacy configuration key for Azure AD authority URL.
      See Also:
    • AAD_TENANT

      protected static final String AAD_TENANT
      Legacy configuration key for Azure AD tenant ID.
      See Also:
    • AAD_CLIENT_SECRET

      protected static final String AAD_CLIENT_SECRET
      Legacy configuration key for Azure AD client secret.
      See Also:
    • AAD_CLIENT_ID

      protected static final String AAD_CLIENT_ID
      Legacy configuration key for Azure AD client ID.
      See Also:
    • AAD_REPLY_URL

      protected static final String AAD_REPLY_URL
      Legacy configuration key for Azure AD reply URL.
      See Also:
    • AAD_DEFAULT_GROUPS

      protected static final String AAD_DEFAULT_GROUPS
      Legacy configuration key for Azure AD default groups.
      See Also:
    • AAD_DEFAULT_ROLES

      protected static final String AAD_DEFAULT_ROLES
      Legacy configuration key for Azure AD default roles.
      See Also:
    • STATES

      protected static final String STATES
      Session attribute key for storing Entra ID states.
      See Also:
    • STATE

      protected static final String STATE
      OAuth2 state parameter name.
      See Also:
    • ERROR

      protected static final String ERROR
      OAuth2 error parameter name.
      See Also:
    • ERROR_DESCRIPTION

      protected static final String ERROR_DESCRIPTION
      OAuth2 error description parameter name.
      See Also:
    • ERROR_URI

      protected static final String ERROR_URI
      OAuth2 error URI parameter name.
      See Also:
    • ID_TOKEN

      protected static final String ID_TOKEN
      OpenID Connect ID token parameter name.
      See Also:
    • CODE

      protected static final String CODE
      OAuth2 authorization code parameter name.
      See Also:
    • acquisitionTimeout

      protected long acquisitionTimeout
      Timeout for token acquisition in milliseconds.
    • groupCache

      protected com.google.common.cache.Cache<String,org.codelibs.core.misc.Pair<String[],String[]>> groupCache
      Cache for storing group information to reduce API calls.
    • groupCacheExpiry

      protected long groupCacheExpiry
      Group cache expiry time in seconds.
    • maxGroupDepth

      protected int maxGroupDepth
      Maximum depth for processing nested groups to prevent infinite loops.
    • useV2Endpoint

      protected boolean useV2Endpoint
      Use V2 endpoint.
  • Constructor Details

    • EntraIdAuthenticator

      public EntraIdAuthenticator()
      Default constructor for EntraIdAuthenticator.
  • Method Details

    • init

      @PostConstruct public void init()
      Initializes the Entra ID authenticator. Registers this authenticator with the SSO manager and sets up group cache.
    • getLoginCredential

      public org.lastaflute.web.login.credential.LoginCredential getLoginCredential()
      Description copied from interface: SsoAuthenticator
      Gets the login credential for SSO authentication.
      Specified by:
      getLoginCredential in interface SsoAuthenticator
      Returns:
      The login credential.
    • getAuthUrl

      protected String getAuthUrl(jakarta.servlet.http.HttpServletRequest request)
      Generates the Entra ID authorization URL for the authentication request.
      Parameters:
      request - The HTTP servlet request.
      Returns:
      The authorization URL to redirect the user to.
    • storeStateInSession

      protected void storeStateInSession(jakarta.servlet.http.HttpSession session, String state, String nonce)
      Stores state and nonce information in the HTTP session.
      Parameters:
      session - The HTTP session.
      state - The OAuth2 state parameter.
      nonce - The OpenID Connect nonce parameter.
    • processAuthenticationData

      protected org.lastaflute.web.login.credential.LoginCredential processAuthenticationData(jakarta.servlet.http.HttpServletRequest request)
      Processes authentication data from the OAuth2 callback.
      Parameters:
      request - The HTTP servlet request containing authentication data.
      Returns:
      The login credential or null if processing fails.
    • parseAuthenticationResponse

      protected com.nimbusds.openid.connect.sdk.AuthenticationResponse parseAuthenticationResponse(String url, Map<String,List<String>> params)
      Parses the authentication response from Entra ID.
      Parameters:
      url - The response URL.
      params - The response parameters.
      Returns:
      The parsed authentication response.
    • validateNonce

      protected void validateNonce(EntraIdAuthenticator.StateData stateData, com.microsoft.aad.msal4j.IAuthenticationResult authData)
      Validates the nonce in the authentication result.
      Parameters:
      stateData - The stored state data containing the expected nonce.
      authData - The authentication result containing the actual nonce.
    • getAccessToken

      public com.microsoft.aad.msal4j.IAuthenticationResult getAccessToken(String refreshToken)
      Obtains an access token using a refresh token.
      Parameters:
      refreshToken - The refresh token to use for token acquisition.
      Returns:
      The authentication result containing the access token.
    • getAccessToken

      protected com.microsoft.aad.msal4j.IAuthenticationResult getAccessToken(com.nimbusds.oauth2.sdk.AuthorizationCode authorizationCode, String currentUri)
      Obtains an access token using an authorization code.
      Parameters:
      authorizationCode - The authorization code received from Entra ID.
      currentUri - The current URI for the redirect.
      Returns:
      The authentication result containing the access token.
    • refreshTokenSilently

      public com.microsoft.aad.msal4j.IAuthenticationResult refreshTokenSilently(EntraIdCredential.EntraIdUser user)
      Attempts to refresh tokens silently using the MSAL4J silent authentication flow.
      Parameters:
      user - The Entra ID user whose tokens need to be refreshed.
      Returns:
      The new authentication result, or null if silent refresh failed.
    • validateAuthRespMatchesCodeFlow

      protected void validateAuthRespMatchesCodeFlow(com.nimbusds.openid.connect.sdk.AuthenticationSuccessResponse oidcResponse)
      Validates that the authentication response matches the authorization code flow.
      Parameters:
      oidcResponse - The OpenID Connect authentication success response.
    • validateState

      protected EntraIdAuthenticator.StateData validateState(jakarta.servlet.http.HttpSession session, String state)
      Validates the OAuth2 state parameter.
      Parameters:
      session - The HTTP session containing stored state data.
      state - The state parameter to validate.
      Returns:
      The validated state data.
    • removeStateFromSession

      protected EntraIdAuthenticator.StateData removeStateFromSession(jakarta.servlet.http.HttpSession session, String state)
      Removes and returns state data from the HTTP session.
      Parameters:
      session - The HTTP session.
      state - The state parameter to remove.
      Returns:
      The removed state data or null if not found.
    • containsAuthenticationData

      protected boolean containsAuthenticationData(jakarta.servlet.http.HttpServletRequest request)
      Checks if the request contains authentication data from Entra ID.
      Parameters:
      request - The HTTP servlet request to check.
      Returns:
      True if authentication data is present, false otherwise.
    • updateMemberOf

      public void updateMemberOf(EntraIdCredential.EntraIdUser user)
      Updates the user's group and role membership information with lazy loading for parent groups. Direct groups are retrieved synchronously, while parent groups are fetched asynchronously to avoid login delays when users have many nested group memberships.
      Parameters:
      user - The Entra ID user to update.
    • processMemberOf

      protected void processMemberOf(EntraIdCredential.EntraIdUser user, List<String> groupList, List<String> roleList, String url)
      Processes member-of information from Microsoft Graph API.
      Parameters:
      user - The Entra ID user.
      groupList - The list to add group names to.
      roleList - The list to add role names to.
      url - The Microsoft Graph API URL.
    • addGroupOrRoleName

      protected void addGroupOrRoleName(List<String> list, String value, boolean useDomainServices)
      Adds a group or role name to the specified list.
      Parameters:
      list - The list to add the group or role name to.
      value - The group or role name value.
      useDomainServices - Whether to use domain services for group resolution.
    • processDirectMemberOf

      protected void processDirectMemberOf(EntraIdCredential.EntraIdUser user, List<String> groupList, List<String> roleList, List<String> groupIdsForParentLookup, String url)
      Processes direct member-of information from Microsoft Graph API without parent group lookup. This method retrieves only direct group memberships and collects group IDs for later asynchronous parent group lookup.
      Parameters:
      user - The Entra ID user.
      groupList - The list to add group names to.
      roleList - The list to add role names to.
      groupIdsForParentLookup - The list to collect group IDs for later parent lookup.
      url - The Microsoft Graph API URL.
    • scheduleParentGroupLookup

      protected void scheduleParentGroupLookup(EntraIdCredential.EntraIdUser user, List<String> initialGroups, List<String> initialRoles, List<String> groupIds)
      Schedules asynchronous parent group lookup using TimeoutManager. This method defers the retrieval of nested group information to avoid login delays.
      Parameters:
      user - The Entra ID user.
      initialGroups - The initial group list to be updated.
      initialRoles - The initial role list to be updated.
      groupIds - The list of group IDs to lookup parent groups for.
    • processParentGroup

      protected void processParentGroup(EntraIdCredential.EntraIdUser user, List<String> groupList, List<String> roleList, String id)
      Processes parent group information for nested groups.
      Parameters:
      user - The Entra ID user.
      groupList - The list to add group names to.
      roleList - The list to add role names to.
      id - The group ID to process.
    • processParentGroup

      protected void processParentGroup(EntraIdCredential.EntraIdUser user, List<String> groupList, List<String> roleList, String id, int depth)
      Processes parent group information for nested groups with depth tracking.
      Parameters:
      user - The Entra ID user.
      groupList - The list to add group names to.
      roleList - The list to add role names to.
      id - The group ID to process.
      depth - The current recursion depth.
    • getParentGroup

      protected org.codelibs.core.misc.Pair<String[],String[]> getParentGroup(EntraIdCredential.EntraIdUser user, String id)
      Retrieves parent group information for the specified group ID.
      Parameters:
      user - The Entra ID user.
      id - The group ID to get parent information for.
      Returns:
      A pair containing group names and role names.
    • getParentGroup

      protected org.codelibs.core.misc.Pair<String[],String[]> getParentGroup(EntraIdCredential.EntraIdUser user, String id, int depth)
      Retrieves parent group information for the specified group ID with depth tracking.
      Parameters:
      user - The Entra ID user.
      id - The group ID to get parent information for.
      depth - The current recursion depth.
      Returns:
      A pair containing group names and role names.
    • processGroup

      protected void processGroup(EntraIdCredential.EntraIdUser user, List<String> groupList, List<String> roleList, String id)
      Processes individual group information.
      Parameters:
      user - The Entra ID user.
      groupList - The list to add group names to.
      roleList - The list to add role names to.
      id - The group ID to process.
    • getDefaultGroupList

      protected List<String> getDefaultGroupList()
      Gets the default group list for users. Uses new entraid.default.groups key with fallback to legacy aad.default.groups.
      Returns:
      The default group list.
    • getDefaultRoleList

      protected List<String> getDefaultRoleList()
      Gets the default role list for users. Uses new entraid.default.roles key with fallback to legacy aad.default.roles.
      Returns:
      The default role list.
    • getClientId

      protected String getClientId()
      Gets the Entra ID client ID from configuration. Uses new entraid.client.id key with fallback to legacy aad.client.id.
      Returns:
      The client ID.
    • getClientSecret

      protected String getClientSecret()
      Gets the Entra ID client secret from configuration. Uses new entraid.client.secret key with fallback to legacy aad.client.secret.
      Returns:
      The client secret.
    • getTenant

      protected String getTenant()
      Gets the Entra ID tenant ID from configuration. Uses new entraid.tenant key with fallback to legacy aad.tenant.
      Returns:
      The tenant ID.
    • getAuthority

      protected String getAuthority()
      Gets the Entra ID authority URL from configuration. Uses new entraid.authority key with fallback to legacy aad.authority.
      Returns:
      The authority URL.
    • getStateTtl

      protected long getStateTtl()
      Gets the state time-to-live from configuration. Uses new entraid.state.ttl key with fallback to legacy aad.state.ttl.
      Returns:
      The state TTL in milliseconds.
    • getReplyUrl

      protected String getReplyUrl(jakarta.servlet.http.HttpServletRequest request)
      Gets the reply URL for Entra ID authentication. Uses new entraid.reply.url key with fallback to legacy aad.reply.url.
      Parameters:
      request - The HTTP servlet request.
      Returns:
      The reply URL.
    • resolveCredential

      public void resolveCredential(FessLoginAssist.LoginCredentialResolver resolver)
      Description copied from interface: SsoAuthenticator
      Resolves credential using the provided resolver.
      Specified by:
      resolveCredential in interface SsoAuthenticator
      Parameters:
      resolver - The login credential resolver.
    • setAcquisitionTimeout

      public void setAcquisitionTimeout(long acquisitionTimeout)
      Sets the token acquisition timeout.
      Parameters:
      acquisitionTimeout - The timeout in milliseconds.
    • setGroupCacheExpiry

      public void setGroupCacheExpiry(long groupCacheExpiry)
      Sets the group cache expiry time.
      Parameters:
      groupCacheExpiry - The cache expiry time in seconds.
    • setMaxGroupDepth

      public void setMaxGroupDepth(int maxGroupDepth)
      Sets the maximum group depth for nested group processing.
      Parameters:
      maxGroupDepth - The maximum depth for nested groups.
    • getResponse

      public org.lastaflute.web.response.ActionResponse getResponse(SsoResponseType responseType)
      Description copied from interface: SsoAuthenticator
      Gets the action response for the specified SSO response type.
      Specified by:
      getResponse in interface SsoAuthenticator
      Parameters:
      responseType - The type of SSO response required.
      Returns:
      The action response.
    • logout

      public String logout(org.codelibs.fess.mylasta.action.FessUserBean user)
      Description copied from interface: SsoAuthenticator
      Performs logout for the specified user.
      Specified by:
      logout in interface SsoAuthenticator
      Parameters:
      user - The user to logout.
      Returns:
      The logout URL or null if not applicable.
    • setUseV2Endpoint

      public void setUseV2Endpoint(boolean useV2Endpoint)
      Enable to use V2 endpoint.
      Parameters:
      useV2Endpoint - true if using V2 endpoint.