@Override public void checkCurrentToken() { if (request.getSession(false) == null) return; RefreshableKeycloakSecurityContext session = (RefreshableKeycloakSecurityContext) request.getSession().getAttribute(KeycloakSecurityContext.class.getName()); if (session == null) return; // just in case session got serialized if (session.getDeployment() == null) session.setCurrentRequestInfo(deployment, this); if (session.isActive() && !session.getDeployment().isAlwaysRefreshToken()) return; // FYI: A refresh requires same scope, so same roles will be set. Otherwise, refresh will fail and token will // not be updated boolean success = session.refreshExpiredToken(false); if (success && session.isActive()) return; // Refresh failed, so user is already logged out from keycloak. Cleanup and expire our session request.getSession().removeAttribute(KeycloakSecurityContext.class.getName()); request.getSession().invalidate(); }
@Override public void logout() { HttpSession httpSession = request.getSession(false); if (httpSession != null) { SerializableKeycloakAccount account = (SerializableKeycloakAccount) httpSession.getAttribute(KeycloakAccount.class.getName()); if (account != null) { account.getKeycloakSecurityContext().logout(deployment); } cleanSession(httpSession); } }
@Override public boolean isCached(RequestAuthenticator authenticator) { // Assuming authenticatedPrincipal set by previous call of checkCurrentToken() during this request if (authenticatedPrincipal != null) { log.debug("remote logged in already. Establish state from cookie"); RefreshableKeycloakSecurityContext securityContext = authenticatedPrincipal.getKeycloakSecurityContext(); if (!securityContext.getRealm().equals(deployment.getRealm())) { log.debug("Account from cookie is from a different realm than for the request."); return false; } securityContext.setCurrentRequestInfo(deployment, this); request.setAttribute(KeycloakSecurityContext.class.getName(), securityContext); return true; } else { return false; } }
public boolean checkActive() { // this object may have been serialized, so we need to reset realm config/metadata RefreshableKeycloakSecurityContext session = getKeycloakSecurityContext(); if (session.isActive() && !session.getDeployment().isAlwaysRefreshToken()) { log.debug("session is active"); return true; } log.debug("session is not active or refresh is enforced. Try refresh"); boolean success = session.refreshExpiredToken(false); if (!success || !session.isActive()) { log.debug("session is not active return with failure"); return false; } log.debug("refresh succeeded"); setRoles(session); return true; }
@Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws IOException, ServletException { if (request.getAttribute(FILTER_APPLIED) != null) { filterChain.doFilter(request, response); return; } request.setAttribute(FILTER_APPLIED, Boolean.TRUE); KeycloakSecurityContext keycloakSecurityContext = getKeycloakPrincipal(); if (keycloakSecurityContext instanceof RefreshableKeycloakSecurityContext) { RefreshableKeycloakSecurityContext refreshableSecurityContext = (RefreshableKeycloakSecurityContext) keycloakSecurityContext; KeycloakDeployment deployment = resolveDeployment(request, response); if (!refreshableSecurityContext.isActive() || deployment.isAlwaysRefreshToken()) { if (refreshableSecurityContext.refreshExpiredToken(false)) { request.setAttribute(KeycloakSecurityContext.class.getName(), refreshableSecurityContext); } else { clearAuthenticationContext(); } } request.setAttribute(KeycloakSecurityContext.class.getName(), keycloakSecurityContext); } filterChain.doFilter(request, response); }
@Override public void handle(Context context) { OIDCFilterSessionStore.SerializableKeycloakAccount account = context.removeSession(KeycloakAccount.class.getName()); if (account != null) { // Logout of the Keycloak server KeycloakDeployment deployment = account.getKeycloakSecurityContext().getDeployment(); account.getKeycloakSecurityContext().logout(deployment); } // Cleanup the session of Keycloak metadata context.removeSession(KeycloakSecurityContext.class.getName()); context.removeSession(REDIRECT_URI); context.removeSession(SAVED_METHOD); context.removeSession(SAVED_HEADERS); context.removeSession(SAVED_BODY); super.handle(context); } }
log.trace("checking whether to refresh."); if (isActive() && isTokenTimeToLiveSufficient(this.token)) return true; if (!this.getRealm().equals(this.deployment.getRealm())) { if (!isTokenTimeToLiveSufficient(token)) { log.error("failed to refresh the token with a longer time-to-live than the minimum"); return false;
public static Set<String> getRolesFromSecurityContext(RefreshableKeycloakSecurityContext session) { Set<String> roles = null; AccessToken accessToken = session.getToken(); if (session.getDeployment().isUseResourceRoleMappings()) { if (log.isTraceEnabled()) { log.trace("useResourceRoleMappings"); } AccessToken.Access access = accessToken.getResourceAccess(session.getDeployment().getResourceName()); if (access != null) roles = access.getRoles(); } else { if (log.isTraceEnabled()) { log.trace("use realm role mappings"); } AccessToken.Access access = accessToken.getRealmAccess(); if (access != null) roles = access.getRoles(); } if (roles == null) roles = Collections.emptySet(); if (log.isTraceEnabled()) { log.trace("Setting roles: "); for (String role : roles) { log.trace(" role: " + role); } } return roles; }
if (!deployment.getRealm().equals(account.getKeycloakSecurityContext().getRealm())) { log.debug("Account in session belongs to a different realm than for this request."); return false;
private void ensureTokenIsStillValid() { if (keycloakSecurityContext instanceof RefreshableKeycloakSecurityContext) { RefreshableKeycloakSecurityContext.class.cast(keycloakSecurityContext).refreshExpiredToken(true); } } }
public static KeycloakPrincipal<RefreshableKeycloakSecurityContext> createPrincipal(KeycloakDeployment deployment, RefreshableKeycloakSecurityContext securityContext) { return new KeycloakPrincipal<RefreshableKeycloakSecurityContext>(getPrincipalName(deployment, securityContext.getToken()), securityContext); } }
public void authenticatedRequest(KeycloakUndertowAccount account, HttpServerExchange exchange) throws Exception { if (account != null) { IDToken idToken = account.getKeycloakSecurityContext().getToken(); if (idToken == null) return; if (idToken.getSubject() != null) { exchange.getRequestHeaders().put(httpHeaderNames.get(KEYCLOAK_SUBJECT), idToken.getSubject()); } if (idToken.getPreferredUsername() != null) { exchange.getRequestHeaders().put(httpHeaderNames.get(KEYCLOAK_USERNAME), idToken.getPreferredUsername()); } if (idToken.getEmail() != null) { exchange.getRequestHeaders().put(httpHeaderNames.get(KEYCLOAK_EMAIL), idToken.getEmail()); } if (idToken.getName() != null) { exchange.getRequestHeaders().put(httpHeaderNames.get(KEYCLOAK_NAME), idToken.getName()); } if (sendAccessToken) { exchange.getRequestHeaders().put(httpHeaderNames.get(KEYCLOAK_ACCESS_TOKEN), account.getKeycloakSecurityContext().getTokenString()); } } next.handleRequest(exchange); } }
/** * Called after accessToken was verified (including signature, expiration etc) * */ protected Auth postTokenVerification(String tokenString, AccessToken token) { boolean verifyCaller; if (deployment.isUseResourceRoleMappings()) { verifyCaller = token.isVerifyCaller(deployment.getResourceName()); } else { verifyCaller = token.isVerifyCaller(); } if (verifyCaller) { throw new IllegalStateException("VerifyCaller not supported yet in login module"); } RefreshableKeycloakSecurityContext skSession = new RefreshableKeycloakSecurityContext(deployment, null, tokenString, token, null, null, null); String principalName = AdapterUtils.getPrincipalName(deployment, token); final KeycloakPrincipal<RefreshableKeycloakSecurityContext> principal = new KeycloakPrincipal<RefreshableKeycloakSecurityContext>(principalName, skSession); final Set<String> roles = AdapterUtils.getRolesFromSecurityContext(skSession); return new Auth(principal, roles, tokenString); }
public void setCurrentRequestInfo(KeycloakDeployment deployment, AdapterTokenStore tokenStore) { principal.getKeycloakSecurityContext().setCurrentRequestInfo(deployment, tokenStore); }
public boolean checkActive() { // this object may have been serialized, so we need to reset realm config/metadata RefreshableKeycloakSecurityContext session = getKeycloakSecurityContext(); if (session.isActive() && !session.getDeployment().isAlwaysRefreshToken()) { log.debug("session is active"); return true; } log.debug("session is not active or refresh is enforced. Try refresh"); boolean success = session.refreshExpiredToken(false); if (!success || !session.isActive()) { log.debug("session is not active return with failure"); return false; } log.debug("refresh succeeded"); setRoles(session); return true; }
if (!deployment.getRealm().equals(account.getKeycloakSecurityContext().getRealm())) { log.debug("Account in session belongs to a different realm than for this request."); return false;
@Override public AccessToken getToken() { refreshExpiredToken(true); return super.getToken(); }
@Override public void saveAccountInfo(OidcKeycloakAccount account) { RefreshableKeycloakSecurityContext securityContext = (RefreshableKeycloakSecurityContext) account.getKeycloakSecurityContext(); Set<String> roles = account.getRoles(); GenericPrincipal principal = principalFactory.createPrincipal(request.getContext().getRealm(), account.getPrincipal(), roles); SerializableKeycloakAccount sAccount = new SerializableKeycloakAccount(roles, account.getPrincipal(), securityContext); Session session = request.getSessionInternal(true); session.setPrincipal(principal); session.setAuthType("KEYCLOAK"); session.getSession().setAttribute(SerializableKeycloakAccount.class.getName(), sAccount); session.getSession().setAttribute(KeycloakSecurityContext.class.getName(), account.getKeycloakSecurityContext()); String username = securityContext.getToken().getSubject(); log.fine("userSessionManagement.login: " + username); this.sessionManagement.login(session); }
RefreshableKeycloakSecurityContext secContext = new RefreshableKeycloakSecurityContext(deployment, tokenStore, accessTokenString, accessToken, idTokenString, idToken, refreshTokenString); return new KeycloakPrincipal<RefreshableKeycloakSecurityContext>(AdapterUtils.getPrincipalName(deployment, accessToken), secContext); } catch (VerificationException ve) {
public void setCurrentRequestInfo(KeycloakDeployment deployment, AdapterTokenStore tokenStore) { principal.getKeycloakSecurityContext().setCurrentRequestInfo(deployment, tokenStore); }