Logging a user in directly from an ActionToken

Thanks for that tip. It looks like the AbstractActionTokenHandler sets a note that the session should be terminated after required actions are executed:

I took your suggestion and did override that method. The thought that I would need to include required actions explicitly sent me to a different approach in my ActionTokenHandler. I settled on this, which works with no custom Authenticator required (it skips the authentication flow entirely):

  @Override
  public AuthenticationSessionModel startFreshAuthenticationSession(PortalLinkActionToken token, ActionTokenContext<PortalLinkActionToken> tokenContext) {
    return tokenContext.createAuthenticationSessionForClient(token.getIssuedFor());
  }
  
  @Override
  public Response handleToken(
      PortalLinkActionToken token,
      ActionTokenContext<PortalLinkActionToken> tokenContext) {
    UserModel user = tokenContext.getAuthenticationSession().getAuthenticatedUser();
    AuthenticationSessionModel authSession = tokenContext.getAuthenticationSession();
    ClientModel client = authSession.getClient();

    String redirectUri =
        token.getRedirectUri() != null
            ? token.getRedirectUri()
            : ResolveRelative.resolveRelativeUri(session, client.getRootUrl(), client.getBaseUrl());
    log.infof("Using redirect_uri %s", redirectUri);
    String redirect = RedirectUtils.verifyRedirectUri(tokenContext.getSession(), redirectUri, authSession.getClient());
    if (redirect != null) {
      authSession.setAuthNote(AuthenticationManager.SET_REDIRECT_URI_AFTER_REQUIRED_ACTIONS, "true");
      authSession.setRedirectUri(redirect);
      authSession.setClientNote(OIDCLoginProtocol.REDIRECT_URI_PARAM, redirectUri);
    }

    String nextAction = AuthenticationManager.nextRequiredAction(tokenContext.getSession(), authSession, tokenContext.getRequest(), tokenContext.getEvent());
    return AuthenticationManager.redirectToRequiredActions(tokenContext.getSession(), tokenContext.getRealm(), authSession, tokenContext.getUriInfo(), nextAction);

    // This doesn't work. Why?
    //return tokenContext.processFlow(true, AUTHENTICATE_PATH, tokenContext.getRealm().getBrowserFlow(), null, new AuthenticationProcessor());
  }

Although, I still don’t really understand why the processFlow doesn’t forward to the normal browser flow. In any case, thanks again for all the help, and I hope we can continue the discussion here if someone finds or can contribute better information.