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.