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.

0

There are 0 best solutions below