use of org.keycloak.representations.AccessTokenResponse in project keycloak by keycloak.
the class AuthUtil method ensureToken.
public static String ensureToken(ConfigData config) {
if (config.getExternalToken() != null) {
return config.getExternalToken();
}
checkAuthInfo(config);
RealmConfigData realmConfig = config.sessionRealmConfigData();
long now = currentTimeMillis();
// if it's less than 5s to expiry, renew it
if (realmConfig.getExpiresAt() - now < 5000) {
// if it's less than 5s to expiry, fail with credentials expired
if (realmConfig.getRefreshExpiresAt() != null && realmConfig.getRefreshExpiresAt() - now < 5000) {
throw new RuntimeException("Session has expired. Login again with '" + OsUtil.CMD + " config credentials'");
}
if (realmConfig.getSigExpiresAt() != null && realmConfig.getSigExpiresAt() - now < 5000) {
throw new RuntimeException("Session has expired. Login again with '" + OsUtil.CMD + " config credentials'");
}
try {
String authorization = null;
StringBuilder body = new StringBuilder();
if (realmConfig.getRefreshToken() != null) {
body.append("grant_type=refresh_token").append("&refresh_token=").append(realmConfig.getRefreshToken());
} else {
body.append("grant_type=").append(realmConfig.getGrantTypeForAuthentication());
}
body.append("&client_id=").append(urlencode(realmConfig.getClientId()));
if (realmConfig.getSigningToken() != null) {
body.append("&client_assertion_type=urn:ietf:params:oauth:client-assertion-type:jwt-bearer").append("&client_assertion=").append(realmConfig.getSigningToken());
} else if (realmConfig.getSecret() != null) {
authorization = BasicAuthHelper.createHeader(realmConfig.getClientId(), realmConfig.getSecret());
}
InputStream result = doPost(realmConfig.serverUrl() + "/realms/" + realmConfig.realm() + "/protocol/openid-connect/token", APPLICATION_FORM_URL_ENCODED, APPLICATION_JSON, body.toString(), authorization);
AccessTokenResponse token = JsonSerialization.readValue(result, AccessTokenResponse.class);
saveMergeConfig(cfg -> {
RealmConfigData realmData = cfg.sessionRealmConfigData();
realmData.setToken(token.getToken());
realmData.setRefreshToken(token.getRefreshToken());
realmData.setExpiresAt(currentTimeMillis() + token.getExpiresIn() * 1000);
if (token.getRefreshToken() != null) {
realmData.setRefreshExpiresAt(currentTimeMillis() + token.getRefreshExpiresIn() * 1000);
}
});
return token.getToken();
} catch (Exception e) {
throw new RuntimeException("Failed to refresh access token - " + e.getMessage(), e);
}
}
return realmConfig.getToken();
}
use of org.keycloak.representations.AccessTokenResponse in project keycloak by keycloak.
the class OIDCIdentityProvider method getFederatedIdentity.
@Override
public BrokeredIdentityContext getFederatedIdentity(String response) {
AccessTokenResponse tokenResponse = null;
try {
tokenResponse = JsonSerialization.readValue(response, AccessTokenResponse.class);
} catch (IOException e) {
throw new IdentityBrokerException("Could not decode access token response.", e);
}
String accessToken = verifyAccessToken(tokenResponse);
String encodedIdToken = tokenResponse.getIdToken();
JsonWebToken idToken = validateToken(encodedIdToken);
try {
BrokeredIdentityContext identity = extractIdentity(tokenResponse, accessToken, idToken);
if (!identity.getId().equals(idToken.getSubject())) {
throw new IdentityBrokerException("Mismatch between the subject in the id_token and the subject from the user_info endpoint");
}
identity.getContextData().put(BROKER_NONCE_PARAM, idToken.getOtherClaims().get(OIDCLoginProtocol.NONCE_PARAM));
if (getConfig().isStoreToken()) {
if (tokenResponse.getExpiresIn() > 0) {
long accessTokenExpiration = Time.currentTime() + tokenResponse.getExpiresIn();
tokenResponse.getOtherClaims().put(ACCESS_TOKEN_EXPIRATION, accessTokenExpiration);
response = JsonSerialization.writeValueAsString(tokenResponse);
}
identity.setToken(response);
}
return identity;
} catch (Exception e) {
throw new IdentityBrokerException("Could not fetch attributes from userinfo endpoint.", e);
}
}
use of org.keycloak.representations.AccessTokenResponse in project keycloak by keycloak.
the class OIDCIdentityProvider method getIDTokenForLogout.
private String getIDTokenForLogout(KeycloakSession session, UserSessionModel userSession) {
String tokenExpirationString = userSession.getNote(FEDERATED_TOKEN_EXPIRATION);
long exp = tokenExpirationString == null ? 0 : Long.parseLong(tokenExpirationString);
int currentTime = Time.currentTime();
if (exp > 0 && currentTime > exp) {
String response = refreshTokenForLogout(session, userSession);
AccessTokenResponse tokenResponse = null;
try {
tokenResponse = JsonSerialization.readValue(response, AccessTokenResponse.class);
} catch (IOException e) {
throw new RuntimeException(e);
}
return tokenResponse.getIdToken();
} else {
return userSession.getNote(FEDERATED_ID_TOKEN);
}
}
use of org.keycloak.representations.AccessTokenResponse in project keycloak by keycloak.
the class OIDCIdentityProvider method exchangeStoredToken.
@Override
protected Response exchangeStoredToken(UriInfo uriInfo, EventBuilder event, ClientModel authorizedClient, UserSessionModel tokenUserSession, UserModel tokenSubject) {
FederatedIdentityModel model = session.users().getFederatedIdentity(authorizedClient.getRealm(), tokenSubject, getConfig().getAlias());
if (model == null || model.getToken() == null) {
event.detail(Details.REASON, "requested_issuer is not linked");
event.error(Errors.INVALID_TOKEN);
return exchangeNotLinked(uriInfo, authorizedClient, tokenUserSession, tokenSubject);
}
try (VaultStringSecret vaultStringSecret = session.vault().getStringSecret(getConfig().getClientSecret())) {
String modelTokenString = model.getToken();
AccessTokenResponse tokenResponse = JsonSerialization.readValue(modelTokenString, AccessTokenResponse.class);
Integer exp = (Integer) tokenResponse.getOtherClaims().get(ACCESS_TOKEN_EXPIRATION);
if (exp != null && exp < Time.currentTime()) {
if (tokenResponse.getRefreshToken() == null) {
return exchangeTokenExpired(uriInfo, authorizedClient, tokenUserSession, tokenSubject);
}
String response = getRefreshTokenRequest(session, tokenResponse.getRefreshToken(), getConfig().getClientId(), vaultStringSecret.get().orElse(getConfig().getClientSecret())).asString();
if (response.contains("error")) {
logger.debugv("Error refreshing token, refresh token expiration?: {0}", response);
model.setToken(null);
session.users().updateFederatedIdentity(authorizedClient.getRealm(), tokenSubject, model);
event.detail(Details.REASON, "requested_issuer token expired");
event.error(Errors.INVALID_TOKEN);
return exchangeTokenExpired(uriInfo, authorizedClient, tokenUserSession, tokenSubject);
}
AccessTokenResponse newResponse = JsonSerialization.readValue(response, AccessTokenResponse.class);
if (newResponse.getExpiresIn() > 0) {
int accessTokenExpiration = Time.currentTime() + (int) newResponse.getExpiresIn();
newResponse.getOtherClaims().put(ACCESS_TOKEN_EXPIRATION, accessTokenExpiration);
}
if (newResponse.getRefreshToken() == null && tokenResponse.getRefreshToken() != null) {
newResponse.setRefreshToken(tokenResponse.getRefreshToken());
newResponse.setRefreshExpiresIn(tokenResponse.getRefreshExpiresIn());
}
response = JsonSerialization.writeValueAsString(newResponse);
String oldToken = tokenUserSession.getNote(FEDERATED_ACCESS_TOKEN);
if (oldToken != null && oldToken.equals(tokenResponse.getToken())) {
int accessTokenExpiration = newResponse.getExpiresIn() > 0 ? Time.currentTime() + (int) newResponse.getExpiresIn() : 0;
tokenUserSession.setNote(FEDERATED_TOKEN_EXPIRATION, Long.toString(accessTokenExpiration));
tokenUserSession.setNote(FEDERATED_REFRESH_TOKEN, newResponse.getRefreshToken());
tokenUserSession.setNote(FEDERATED_ACCESS_TOKEN, newResponse.getToken());
tokenUserSession.setNote(FEDERATED_ID_TOKEN, newResponse.getIdToken());
}
model.setToken(response);
tokenResponse = newResponse;
} else if (exp != null) {
tokenResponse.setExpiresIn(exp - Time.currentTime());
}
tokenResponse.setIdToken(null);
tokenResponse.setRefreshToken(null);
tokenResponse.setRefreshExpiresIn(0);
tokenResponse.getOtherClaims().clear();
tokenResponse.getOtherClaims().put(OAuth2Constants.ISSUED_TOKEN_TYPE, OAuth2Constants.ACCESS_TOKEN_TYPE);
tokenResponse.getOtherClaims().put(ACCOUNT_LINK_URL, getLinkingUrl(uriInfo, authorizedClient, tokenUserSession));
event.success();
return Response.ok(tokenResponse).type(MediaType.APPLICATION_JSON_TYPE).build();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
use of org.keycloak.representations.AccessTokenResponse in project keycloak by keycloak.
the class AbstractOAuth2IdentityProvider method exchangeSessionToken.
protected Response exchangeSessionToken(UriInfo uriInfo, EventBuilder event, ClientModel authorizedClient, UserSessionModel tokenUserSession, UserModel tokenSubject) {
String accessToken = tokenUserSession.getNote(FEDERATED_ACCESS_TOKEN);
if (accessToken == null) {
event.detail(Details.REASON, "requested_issuer is not linked");
event.error(Errors.INVALID_TOKEN);
return exchangeTokenExpired(uriInfo, authorizedClient, tokenUserSession, tokenSubject);
}
AccessTokenResponse tokenResponse = new AccessTokenResponse();
tokenResponse.setToken(accessToken);
tokenResponse.setIdToken(null);
tokenResponse.setRefreshToken(null);
tokenResponse.setRefreshExpiresIn(0);
tokenResponse.getOtherClaims().clear();
tokenResponse.getOtherClaims().put(OAuth2Constants.ISSUED_TOKEN_TYPE, OAuth2Constants.ACCESS_TOKEN_TYPE);
tokenResponse.getOtherClaims().put(ACCOUNT_LINK_URL, getLinkingUrl(uriInfo, authorizedClient, tokenUserSession));
event.success();
return Response.ok(tokenResponse).type(MediaType.APPLICATION_JSON_TYPE).build();
}
Aggregations