use of com.nimbusds.oauth2.sdk.token.Tokens 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 com.nimbusds.oauth2.sdk.token.Tokens in project ddf by codice.
the class OAuthPlugin method process.
/**
* Verifies that a source configured to use OAuth has a valid access token to process and that the
* user has authorized the use of their data against this source.
*
* @param source source being queried
* @param input query request
* @throws OAuthPluginException if the user's access token is not available or if the source is
* not authorized
* @throws StopProcessingException for errors not related to OAuth
*/
@Override
public QueryRequest process(Source source, QueryRequest input) throws StopProcessingException {
OAuthFederatedSource oauthSource = getSource(source);
if (oauthSource == null) {
return input;
}
Object securityAssertion = input.getProperties().get(SECURITY_SUBJECT);
if (!(securityAssertion instanceof Subject)) {
LOGGER.warn("The user's subject is not available.");
throw new StopProcessingException("The user's subject is not available.");
}
Subject subject = (Subject) securityAssertion;
Session session = subject.getSession(false);
if (session == null) {
LOGGER.warn("The user's session is not available.");
throw new StopProcessingException("The user's session is not available.");
}
String sessionId = (String) session.getId();
if (sessionId == null) {
LOGGER.warn("The user's session ID is not available.");
throw new StopProcessingException("The user's session ID is not available.");
}
OIDCProviderMetadata metadata;
try {
metadata = OIDCProviderMetadata.parse(resourceRetriever.retrieveResource(new URL(oauthSource.getOauthDiscoveryUrl())).getContent());
} catch (OAuthServiceException | IOException | ParseException e) {
LOGGER.error("Unable to retrieve OAuth provider's metadata for the {} source.", oauthSource.getId());
throw new StopProcessingException("Unable to retrieve OAuth provider's metadata.");
}
TokenEntry tokenEntry = tokenStorage.read(sessionId, oauthSource.getId());
if (tokenEntry == null) {
// See if the user already logged in to the OAuth provider for a different source
findExistingTokens(oauthSource, sessionId, metadata);
throw createNoAuthException(oauthSource, sessionId, metadata, "the user's tokens were not found.");
}
// an outdated token)
if (!oauthSource.getOauthDiscoveryUrl().equals(tokenEntry.getDiscoveryUrl())) {
// the discoveryUrl is different from the one stored - the user must login
tokenStorage.delete(sessionId, oauthSource.getId());
findExistingTokens(oauthSource, sessionId, metadata);
throw createNoAuthException(oauthSource, sessionId, metadata, "the oauth provider information has been changed and is different from the one stored.");
}
verifyAccessToken(oauthSource, sessionId, tokenEntry, metadata);
return input;
}
use of com.nimbusds.oauth2.sdk.token.Tokens in project syncope by apache.
the class OIDCC4UILogic method login.
@PreAuthorize("hasRole('" + IdRepoEntitlement.ANONYMOUS + "')")
public OIDCLoginResponse login(final String redirectURI, final String authorizationCode, final String opName) {
// 0. look for OP
OIDCC4UIProvider op = opDAO.findByName(opName);
if (op == null) {
throw new NotFoundException("OIDC Provider '" + opName + '\'');
}
// 1. look for configured client
OidcClient oidcClient = getOidcClient(opName, redirectURI);
oidcClient.setCallbackUrl(redirectURI);
// 2. get OpenID Connect tokens
String idTokenHint;
JWTClaimsSet idToken;
try {
OidcCredentials credentials = new OidcCredentials();
credentials.setCode(new AuthorizationCode(authorizationCode));
OIDC4UIContext ctx = new OIDC4UIContext();
oidcClient.getAuthenticator().validate(credentials, ctx, NoOpSessionStore.INSTANCE);
idToken = credentials.getIdToken().getJWTClaimsSet();
idTokenHint = credentials.getIdToken().serialize();
} catch (Exception e) {
LOG.error("While validating Token Response", e);
SyncopeClientException sce = SyncopeClientException.build(ClientExceptionType.Unknown);
sce.getElements().add(e.getMessage());
throw sce;
}
// 3. prepare the result
OIDCLoginResponse loginResponse = new OIDCLoginResponse();
loginResponse.setLogoutSupported(StringUtils.isNotBlank(op.getEndSessionEndpoint()));
// 3a. find matching user (if any) and return the received attributes
String keyValue = idToken.getSubject();
for (OIDCC4UIProviderItem item : op.getItems()) {
Attr attrTO = new Attr();
attrTO.setSchema(item.getExtAttrName());
String value = idToken.getClaim(item.getExtAttrName()) == null ? null : idToken.getClaim(item.getExtAttrName()).toString();
if (value != null) {
attrTO.getValues().add(value);
loginResponse.getAttrs().add(attrTO);
if (item.isConnObjectKey()) {
keyValue = value;
}
}
}
List<String> matchingUsers = keyValue == null ? List.of() : userManager.findMatchingUser(keyValue, op.getConnObjectKeyItem().get());
LOG.debug("Found {} matching users for {}", matchingUsers.size(), keyValue);
// 3b. not found: create or selfreg if configured
String username;
if (matchingUsers.isEmpty()) {
if (op.isCreateUnmatching()) {
LOG.debug("No user matching {}, about to create", keyValue);
String defaultUsername = keyValue;
username = AuthContextUtils.callAsAdmin(AuthContextUtils.getDomain(), () -> userManager.create(op, loginResponse, defaultUsername));
} else if (op.isSelfRegUnmatching()) {
UserTO userTO = new UserTO();
userManager.fill(op, loginResponse, userTO);
loginResponse.getAttrs().clear();
loginResponse.getAttrs().addAll(userTO.getPlainAttrs());
if (StringUtils.isNotBlank(userTO.getUsername())) {
loginResponse.setUsername(userTO.getUsername());
} else {
loginResponse.setUsername(keyValue);
}
loginResponse.setSelfReg(true);
return loginResponse;
} else {
throw new NotFoundException(Optional.ofNullable(keyValue).map(value -> "User matching the provided value " + value).orElse("User marching the provided claims"));
}
} else if (matchingUsers.size() > 1) {
throw new IllegalArgumentException("Several users match the provided value " + keyValue);
} else {
if (op.isUpdateMatching()) {
LOG.debug("About to update {} for {}", matchingUsers.get(0), keyValue);
username = AuthContextUtils.callAsAdmin(AuthContextUtils.getDomain(), () -> userManager.update(matchingUsers.get(0), op, loginResponse));
} else {
username = matchingUsers.get(0);
}
}
loginResponse.setUsername(username);
// 4. generate JWT for further access
Map<String, Object> claims = new HashMap<>();
claims.put(JWT_CLAIM_OP_NAME, opName);
claims.put(JWT_CLAIM_ID_TOKEN, idTokenHint);
byte[] authorities = null;
try {
authorities = ENCRYPTOR.encode(POJOHelper.serialize(authDataAccessor.getAuthorities(loginResponse.getUsername(), null)), CipherAlgorithm.AES).getBytes();
} catch (Exception e) {
LOG.error("Could not fetch authorities", e);
}
Pair<String, OffsetDateTime> accessTokenInfo = accessTokenDataBinder.create(loginResponse.getUsername(), claims, authorities, true);
loginResponse.setAccessToken(accessTokenInfo.getLeft());
loginResponse.setAccessTokenExpiryTime(accessTokenInfo.getRight());
return loginResponse;
}
use of com.nimbusds.oauth2.sdk.token.Tokens in project kf-key-management by kids-first.
the class FenceService method refreshTokens.
public Mono<OIDCTokens> refreshTokens(String refreshToken, AllFences.Fence fence) {
Mono<Optional<OIDCTokens>> blockingWrapper = Mono.fromCallable(() -> {
val clientId = fence.getClientId();
val clientSecret = fence.getClientSecret();
val fenceEndpoint = fence.getTokenEndpoint();
val request = new TokenRequest(new URI(fenceEndpoint), new ClientSecretBasic(new ClientID(clientId), new com.nimbusds.oauth2.sdk.auth.Secret(clientSecret)), new RefreshTokenGrant(new RefreshToken(refreshToken)));
val fenceResponse = request.toHTTPRequest().send();
if (fenceResponse.indicatesSuccess()) {
val tokens = OIDCTokenResponse.parse(fenceResponse).toSuccessResponse().getOIDCTokens();
return Optional.of(tokens);
}
return Optional.empty();
});
return blockingWrapper.subscribeOn(Schedulers.boundedElastic()).flatMap(o -> o.map(Mono::just).orElseGet(Mono::empty));
}
use of com.nimbusds.oauth2.sdk.token.Tokens in project kf-key-management by kids-first.
the class FenceService method requestTokens.
public Mono<OIDCTokens> requestTokens(String authCode, AllFences.Fence fence) {
Mono<Optional<OIDCTokens>> blockingWrapper = Mono.fromCallable(() -> {
String clientId = fence.getClientId();
String clientSecret = fence.getClientSecret();
String fenceEndpoint = fence.getTokenEndpoint();
String redirectUri = fence.getRedirectUri();
val fenceRequest = new TokenRequest(new URI(fenceEndpoint), new ClientSecretBasic(new ClientID(clientId), new com.nimbusds.oauth2.sdk.auth.Secret(clientSecret)), new AuthorizationCodeGrant(new AuthorizationCode(authCode), new URI(redirectUri)), new Scope(fence.getScope()));
val fenceResponse = fenceRequest.toHTTPRequest().send();
if (fenceResponse.indicatesSuccess()) {
val tokens = OIDCTokenResponse.parse(fenceResponse).toSuccessResponse().getOIDCTokens();
return Optional.of(tokens);
} else {
log.error("Error in {} fence response during request tokens: status={}, content={}", fence.getName(), fenceResponse.getStatusCode(), fenceResponse.getContent());
return Optional.empty();
}
});
return blockingWrapper.subscribeOn(Schedulers.boundedElastic()).flatMap(o -> o.map(Mono::just).orElseGet(Mono::empty));
}
Aggregations