use of org.codice.ddf.security.oidc.validator.OidcValidationException in project ddf by codice.
the class OAuthPlugin method refreshTokens.
/**
* Attempts to refresh the user's access token and saves the new tokens in the token storage
*
* @param refreshToken refresh token used to refresh access token
* @param oauthSource source being queried
* @throws OAuthPluginException if the access token could not be renewed
*/
private void refreshTokens(String refreshToken, OAuthFederatedSource oauthSource, String sessionId, OIDCProviderMetadata metadata) throws StopProcessingException {
if (refreshToken == null) {
throw createNoAuthException(oauthSource, sessionId, metadata, "unable to find the user's refresh token.");
}
ClientAccessToken clientAccessToken;
try {
LOGGER.debug("Attempting to refresh the user's access token.");
WebClient webClient = createWebclient(metadata.getTokenEndpointURI().toURL().toString());
Consumer consumer = new Consumer(oauthSource.getOauthClientId(), oauthSource.getOauthClientSecret());
AccessTokenGrant accessTokenGrant = new RefreshTokenGrant(refreshToken);
clientAccessToken = OAuthClientUtils.getAccessToken(webClient, consumer, accessTokenGrant);
} catch (OAuthServiceException e) {
String error = e.getError() != null ? e.getError().getError() : "";
throw createNoAuthException(oauthSource, sessionId, metadata, "failed to refresh access token " + error);
} catch (MalformedURLException e) {
throw createNoAuthException(oauthSource, sessionId, metadata, "malformed token endpoint URL. " + e.getMessage());
}
// Validate new access token
try {
AccessToken accessToken = convertCxfAccessTokenToNimbusdsToken(clientAccessToken);
OidcTokenValidator.validateAccessToken(accessToken, null, resourceRetriever, metadata, null);
} catch (OidcValidationException e) {
throw createNoAuthException(oauthSource, sessionId, metadata, "failed to validate refreshed access token.");
}
// Store new tokens
String newAccessToken = clientAccessToken.getTokenKey();
String newRefreshToken = clientAccessToken.getRefreshToken();
int status = tokenStorage.create(sessionId, oauthSource.getId(), newAccessToken, newRefreshToken, oauthSource.getOauthDiscoveryUrl());
if (status != SC_OK) {
LOGGER.warn("Error updating the token information.");
}
}
use of org.codice.ddf.security.oidc.validator.OidcValidationException in project ddf by codice.
the class OidcCredentialsResolver method trySendingGrantAndPopulatingCredentials.
private void trySendingGrantAndPopulatingCredentials(AuthorizationGrant grant, OidcCredentials credentials, WebContext webContext) throws IOException, ParseException {
final OIDCTokens oidcTokens = getOidcTokens(grant);
try {
JWT idToken = oidcTokens.getIDToken();
if (idToken != null) {
OidcTokenValidator.validateIdTokens(idToken, webContext, configuration, client);
}
AccessToken accessToken = oidcTokens.getAccessToken();
if (accessToken != null) {
OidcTokenValidator.validateAccessToken(accessToken, idToken, resourceRetriever, metadata, configuration);
}
credentials.setAccessToken(accessToken);
credentials.setIdToken(idToken);
credentials.setRefreshToken(oidcTokens.getRefreshToken());
} catch (OidcValidationException e) {
throw new TechnicalException(e);
}
}
use of org.codice.ddf.security.oidc.validator.OidcValidationException in project ddf by codice.
the class OAuthSecurityImpl method getNewAccessToken.
/**
* Gets an access token from the configured OAuth provider, saves it to the token storage and
* returns it
*
* @param id The ID to use when storing tokens
* @param sourceId The ID of the source using OAuth to use when storing tokens
* @param encodedClientIdSecret The base 64 encoded clientId:secret
* @param discoveryUrl The URL where the Oauth provider's metadata is hosted
* @param grantType The OAuth grand type to use
* @param queryParameters Query parameters to send
* @return a client access token or null if one could not be returned
*/
private String getNewAccessToken(String id, String sourceId, String encodedClientIdSecret, String discoveryUrl, String grantType, Map<String, String> queryParameters, OIDCProviderMetadata metadata) {
WebClient webClient = createWebClient(metadata.getTokenEndpointURI());
webClient.header(AUTHORIZATION, BASIC + encodedClientIdSecret);
webClient.accept(APPLICATION_JSON);
Form formParam = new Form(GRANT_TYPE, grantType);
formParam.param(SCOPE, OPENID_SCOPE);
queryParameters.forEach(formParam::param);
javax.ws.rs.core.Response response = webClient.form(formParam);
String body;
try {
body = IOUtils.toString((InputStream) response.getEntity(), UTF_8);
} catch (IOException e) {
LOGGER.debug("Unable to retrieve system access token.", e);
return null;
}
if (response.getStatus() != HttpStatus.SC_OK) {
LOGGER.debug("Unable to retrieve system access token. {}", body);
if (LOGGER.isTraceEnabled()) {
sanitizeFormParameters(formParam);
LOGGER.trace("Unable to retrieve system access token. Headers: {}, Request: {}, Status: {}, Response: {}", webClient.getHeaders(), formParam.asMap(), response.getStatus(), body);
}
return null;
}
Map<String, String> map = GSON.fromJson(body, MAP_STRING_TO_OBJECT_TYPE);
String idToken = map.get(ID_TOKEN);
String accessToken = map.get(ACCESS_TOKEN);
String refreshToken = map.get(REFRESH_TOKEN);
JWT jwt = null;
try {
if (idToken != null) {
jwt = SignedJWT.parse(idToken);
}
} catch (java.text.ParseException e) {
LOGGER.debug("Error parsing ID token.", e);
}
try {
OidcTokenValidator.validateAccessToken(new BearerAccessToken(accessToken), jwt, resourceRetriever, metadata, null);
} catch (OidcValidationException e) {
LOGGER.warn("Error validating system access token.", e);
return null;
}
LOGGER.debug("Successfully retrieved system access token.");
int status = tokenStorage.create(id, sourceId, accessToken, refreshToken, discoveryUrl);
if (status != SC_OK) {
LOGGER.debug("Error storing user token.");
}
return accessToken;
}
use of org.codice.ddf.security.oidc.validator.OidcValidationException in project ddf by codice.
the class OAuthSecurityImpl method refreshToken.
/**
* Attempts to refresh an expired access token
*
* @param id The ID to use when storing tokens
* @param sourceId The ID of the source using OAuth to use when storing tokens
* @param clientId The client ID registered with the OAuth provider
* @param clientSecret The client secret registered with the OAuth provider
* @param discoveryUrl The URL where the OAuth provider's metadata is hosted
* @param refreshToken The unexpired refresh token to use
* @param metadata The OAuh provider's metadata
* @return refreshed access token
*/
private String refreshToken(String id, String sourceId, String clientId, String clientSecret, String discoveryUrl, String refreshToken, OIDCProviderMetadata metadata) {
if (refreshToken == null || isExpired(refreshToken)) {
LOGGER.debug("Error refreshing access token: unable to find an unexpired refresh token.");
return null;
}
ClientAccessToken clientAccessToken;
try {
LOGGER.debug("Attempting to refresh the user's access token.");
WebClient webClient = createWebClient(metadata.getTokenEndpointURI());
Consumer consumer = new Consumer(clientId, clientSecret);
AccessTokenGrant accessTokenGrant = new RefreshTokenGrant(refreshToken);
clientAccessToken = OAuthClientUtils.getAccessToken(webClient, consumer, accessTokenGrant);
} catch (OAuthServiceException e) {
LOGGER.debug("Error refreshing access token.", e);
return null;
}
// Validate new access token
try {
AccessToken accessToken = convertCxfAccessTokenToNimbusdsToken(clientAccessToken);
OidcTokenValidator.validateAccessToken(accessToken, null, resourceRetriever, metadata, null);
} catch (OidcValidationException e) {
LOGGER.debug("Error validating access token.");
return null;
}
// Store new tokens
String newAccessToken = clientAccessToken.getTokenKey();
String newRefreshToken = clientAccessToken.getRefreshToken();
int status = tokenStorage.create(id, sourceId, newAccessToken, newRefreshToken, discoveryUrl);
if (status != SC_OK) {
LOGGER.warn("Error updating the token information.");
}
return newAccessToken;
}
use of org.codice.ddf.security.oidc.validator.OidcValidationException in project ddf by codice.
the class OidcCredentialsResolver method resolveIdToken.
/* This methods job is to try and get an id token from a
1. refresh token
2. authorization code
3. access token
*/
public void resolveIdToken(OidcCredentials credentials, WebContext webContext) {
final AccessToken initialAccessToken = credentials.getAccessToken();
final JWT initialIdToken = credentials.getIdToken();
try {
OidcTokenValidator.validateAccessToken(initialAccessToken, initialIdToken, resourceRetriever, metadata, configuration);
if (initialIdToken != null) {
OidcTokenValidator.validateIdTokens(initialIdToken, webContext, configuration, client);
return;
}
} catch (OidcValidationException e) {
throw new TechnicalException(e);
}
final RefreshToken initialRefreshToken = credentials.getRefreshToken();
final AuthorizationCode initialAuthorizationCode = credentials.getCode();
final List<AuthorizationGrant> grantList = new ArrayList<>();
if (initialRefreshToken != null) {
grantList.add(new RefreshTokenGrant(initialRefreshToken));
}
if (initialAuthorizationCode != null) {
try {
final URI callbackUri = new URI(client.computeFinalCallbackUrl(webContext));
grantList.add(new AuthorizationCodeGrant(initialAuthorizationCode, callbackUri));
} catch (URISyntaxException e) {
LOGGER.debug("Problem computing callback url. Cannot add authorization code grant.");
}
}
// try to get id token using refresh token and authorization code
for (AuthorizationGrant grant : grantList) {
try {
trySendingGrantAndPopulatingCredentials(grant, credentials, webContext);
if (credentials.getIdToken() != null) {
break;
}
} catch (IOException | ParseException e) {
LOGGER.debug("Problem sending grant ({}).", grant, e);
}
}
// try to get id token using access token
if (credentials.getIdToken() == null && initialAccessToken != null) {
final UserInfoRequest userInfoRequest = new UserInfoRequest(metadata.getUserInfoEndpointURI(), Method.GET, new BearerAccessToken(initialAccessToken.toString()));
final HTTPRequest userInfoHttpRequest = userInfoRequest.toHTTPRequest();
try {
final HTTPResponse httpResponse = userInfoHttpRequest.send();
final UserInfoResponse userInfoResponse = UserInfoResponse.parse(httpResponse);
if (userInfoResponse instanceof UserInfoSuccessResponse) {
final UserInfoSuccessResponse userInfoSuccessResponse = (UserInfoSuccessResponse) userInfoResponse;
JWT idToken = userInfoSuccessResponse.getUserInfoJWT();
if (idToken == null && userInfoSuccessResponse.getUserInfo().toJWTClaimsSet() != null) {
idToken = new PlainJWT(userInfoSuccessResponse.getUserInfo().toJWTClaimsSet());
}
OidcTokenValidator.validateUserInfoIdToken(idToken, resourceRetriever, metadata);
credentials.setIdToken(idToken);
} else {
throw new TechnicalException("Received a non-successful UserInfoResponse.");
}
} catch (IOException | ParseException | OidcValidationException e) {
LOGGER.debug("Problem retrieving id token using access token.", e);
throw new TechnicalException(e);
}
}
}
Aggregations