I have Keycloak <-> Tomcat <-> Backend Service. I am using Keycloak Tomcat valve. I need to send the user details to backend service if Keycloak has timeout occurred. I am extending the KeycloakAuthenticatorValve to capture if session is invalid in the Keycloak, authentication will fail. But as per the below code RefreshableKeycloakSecurityContext is becoming null and due to that I am not able to retrieve the user information to call the backend service to register the timeout event. I tried to extend the OAuthRequestAuthenticator::authenticate() method but at that point user information can't be retrieved as session already timeout. Can anyone suggest how I can get the user detail in Tomcat when session is timedout in the Keycloak and send the user information to backend? Thanks in advance.
public class FMSKeycloakAuthenticatorValve extends KeycloakAuthenticatorValve {
@Override
public void invoke(Request request, Response response) throws IOException, ServletException {
super.invoke(request, response);
final RefreshableKeycloakSecurityContext secReqContext =
(RefreshableKeycloakSecurityContext) request.getAttribute(KeycloakSecurityContext.class.getName());
if (secReqContext != null) {
// Check if the token is active or expired
if (!secReqContext.isActive()) {
// Custom handling for expired token
handleExpiredToken(request, response, secReqContext);
return;
}
}
getNext().invoke(request, response);
}
private void handleExpiredToken(Request request, Response response,
KeycloakSecurityContext secReqContext) throws IOException {
StringBuilder stbUser = new StringBuilder(100);
stbUser.append(secReqContext.getToken().getPreferredUsername()).append("@")
.append(secReqContext.getRealm());
AuthenticationServiceRemote authService = ServiceLocatorBackend.getInstance()
.getService(stbUser.toString(), AuthenticationServiceRemote.class);
try {
authService.logout(true, stbUser.toString(), request.getRemoteAddr());
} catch (Exception e) {
log.error("Error occurred while calling the logout service", e);
}
}
}
I am getting the secReqContext as null but I wanted to capture the user who has timedout in Keycloak and capture that in the tomcat valve and call the backend service from there.