private ResourceResponse getResourceResponse( Context context, String clientId, Iterable<JsonValue> tokens) throws NotFoundException, InvalidClientException, ServerException, InternalServerErrorException { String realm = getAttributeValue(tokens.iterator().next(), REALM.getOAuthField()); OAuth2ProviderSettings oAuth2ProviderSettings = oAuth2ProviderSettingsFactory.get(context); ClientRegistration clientRegistration = clientRegistrationStore.get(clientId, realm, context); Map<String, String> scopeDescriptions = clientRegistration.getScopeDescriptions(getLocale(context)); Map<String, String> scopes = new HashMap<>(); for (JsonValue token : tokens) { for (String scope : token.get(SCOPE.getOAuthField()).asSet(String.class)) { if (scopeDescriptions.containsKey(scope)) { scopes.put(scope, scopeDescriptions.get(scope)); } else { scopes.put(scope, scope); } } } String displayName = clientRegistration.getDisplayName(getLocale(context)); String expiryDateTime = calculateExpiryDateTime(tokens, oAuth2ProviderSettings); JsonValue content = json( object( field("_id", clientId), field("name", displayName), field("scopes", scopes), field("expiryDateTime", expiryDateTime))); return Responses.newResourceResponse( clientId, String.valueOf(content.getObject().hashCode()), content); }
private boolean isEntitled( UmaProviderSettings umaProviderSettings, PermissionTicket permissionTicket, AccessToken authorisationApiToken) throws EntitlementException, ServerException { String realm = permissionTicket.getRealm(); String resourceSetId = permissionTicket.getResourceSetId(); String resourceName = UmaConstants.UMA_POLICY_SCHEME; Subject resourceOwnerSubject; try { ResourceSetStore store = oauth2ProviderSettingsFactory .get(requestFactory.create(getRequest())) .getResourceSetStore(); Set<ResourceSetDescription> results = store.query( org.forgerock.util.query.QueryFilter.equalTo( ResourceSetTokenField.RESOURCE_SET_ID, resourceSetId)); if (results.size() != 1) { throw new NotFoundException("Could not find Resource Set, " + resourceSetId); } resourceName += results.iterator().next().getId(); resourceOwnerSubject = UmaUtils.createSubject( createIdentity(results.iterator().next().getResourceOwnerId(), realm)); } catch (NotFoundException e) { debug.message("Couldn't find resource that permission ticket is registered for", e); throw new ServerException("Couldn't find resource that permission ticket is registered for"); } Subject requestingPartySubject = UmaUtils.createSubject(createIdentity(authorisationApiToken.getResourceOwnerId(), realm)); // Implicitly grant access to the resource owner if (isRequestingPartyResourceOwner(requestingPartySubject, resourceOwnerSubject)) { return true; } List<Entitlement> entitlements = umaProviderSettings .getPolicyEvaluator( requestingPartySubject, permissionTicket.getClientId().toLowerCase()) .evaluate(realm, requestingPartySubject, resourceName, null, false); Set<String> requestedScopes = permissionTicket.getScopes(); Set<String> requiredScopes = new HashSet<String>(requestedScopes); for (Entitlement entitlement : entitlements) { for (String requestedScope : requestedScopes) { final Boolean actionValue = entitlement.getActionValue(requestedScope); if (actionValue != null && actionValue) { requiredScopes.remove(requestedScope); } } } return requiredScopes.isEmpty(); }
/** * Allows users to revoke an OAuth2 application. This will remove their consent and revoke any * access and refresh tokens with a matching client id. * * @param context The request context. * @param resourceId The id of the OAuth2 client. * @return A promise of the removed application. */ @Delete public Promise<ResourceResponse, ResourceException> deleteInstance( Context context, String resourceId) { String userId = contextHelper.getUserId(context); String realm = contextHelper.getRealm(context); debug.message("Revoking access to OAuth2 client {} for user {}", resourceId, userId); try { oAuth2ProviderSettingsFactory.get(context).revokeConsent(userId, resourceId); QueryFilter<CoreTokenField> queryFilter = and(getQueryFilter(userId, realm), equalTo(CLIENT_ID.getField(), resourceId)); JsonValue tokens = tokenStore.query(queryFilter); if (tokens.asCollection().isEmpty()) { return new org.forgerock.json.resource.NotFoundException().asPromise(); } for (JsonValue token : tokens) { String tokenId = getAttributeValue(token, ID.getOAuthField()); debug.message( "Removing OAuth2 token {} with client {} for user {}", tokenId, resourceId, userId); tokenStore.delete(tokenId); } return getResourceResponse(context, resourceId, tokens).asPromise(); } catch (CoreTokenException | InvalidClientException | NotFoundException | ServerException e) { debug.message( "Failed to revoke access to OAuth2 client {} for user {}", resourceId, userId, e); return new InternalServerErrorException(e).asPromise(); } catch (InternalServerErrorException e) { debug.message( "Failed to revoke access to OAuth2 client {} for user {}", resourceId, userId, e); return e.asPromise(); } }
/** {@inheritDoc} */ public DeviceCode createDeviceCode( Set<String> scope, String clientId, String nonce, String responseType, String state, String acrValues, String prompt, String uiLocales, String loginHint, Integer maxAge, String claims, OAuth2Request request, String codeChallenge, String codeChallengeMethod) throws ServerException, NotFoundException { logger.message("DefaultOAuthTokenStoreImpl::Creating Authorization code"); final OAuth2ProviderSettings providerSettings = providerSettingsFactory.get(request); final String deviceCode = UUID.randomUUID().toString(); String userCode = null; int i; for (i = 0; userCode == null && i < 10; i++) { // A 6-byte array will result in an 8-char Base64 user code. byte[] randomBytes = new byte[6]; secureRandom.nextBytes(randomBytes); userCode = Base64.encode(randomBytes); try { readDeviceCode(userCode, request); // code can be found - try again } catch (InvalidGrantException e) { // Good, it doesn't exist yet. break; } catch (ServerException e) { logger.message("Could not query CTS, assume duplicate to be safe", e); } userCode = null; } if (i == 10) { throw new ServerException("Could not generate a unique user code"); } long expiryTime = System.currentTimeMillis() + (1000 * providerSettings.getDeviceCodeLifetime()); final DeviceCode code = new DeviceCode( deviceCode, userCode, clientId, nonce, responseType, state, acrValues, prompt, uiLocales, loginHint, maxAge, claims, expiryTime, scope, realmNormaliser.normalise(request.<String>getParameter(REALM)), codeChallenge, codeChallengeMethod); // Store in CTS try { tokenStore.create(code); if (auditLogger.isAuditLogEnabled()) { String[] obs = {"CREATED_DEVICE_CODE", code.toString()}; auditLogger.logAccessMessage("CREATED_DEVICE_CODE", obs, null); } } catch (CoreTokenException e) { if (auditLogger.isAuditLogEnabled()) { String[] obs = {"FAILED_CREATE_DEVICE_CODE", code.toString()}; auditLogger.logErrorMessage("FAILED_CREATE_DEVICE_CODE", obs, null); } logger.error("Unable to create device code " + code, e); throw new ServerException("Could not create token in CTS"); } request.setToken(DeviceCode.class, code); return code; }
/** {@inheritDoc} */ public RefreshToken createRefreshToken( String grantType, String clientId, String resourceOwnerId, String redirectUri, Set<String> scope, OAuth2Request request) throws ServerException, NotFoundException { final String realm = realmNormaliser.normalise(request.<String>getParameter(REALM)); logger.message("Create refresh token"); OpenIdConnectClientRegistration clientRegistration = getClientRegistration(clientId, request); final OAuth2ProviderSettings providerSettings = providerSettingsFactory.get(request); final String id = UUID.randomUUID().toString(); final String auditId = UUID.randomUUID().toString(); final long lifeTime; if (clientRegistration == null) { lifeTime = providerSettings.getRefreshTokenLifetime(); } else { lifeTime = clientRegistration.getRefreshTokenLifeTime(providerSettings); } long expiryTime = lifeTime < 0 ? -1 : lifeTime + System.currentTimeMillis(); AuthorizationCode token = request.getToken(AuthorizationCode.class); String authModules = null; String acr = null; if (token != null) { authModules = token.getAuthModules(); acr = token.getAuthenticationContextClassReference(); } RefreshToken currentRefreshToken = request.getToken(RefreshToken.class); if (currentRefreshToken != null) { authModules = currentRefreshToken.getAuthModules(); acr = currentRefreshToken.getAuthenticationContextClassReference(); } RefreshToken refreshToken = new OpenAMRefreshToken( id, resourceOwnerId, clientId, redirectUri, scope, expiryTime, OAuth2Constants.Bearer.BEARER, OAuth2Constants.Token.OAUTH_REFRESH_TOKEN, grantType, realm, authModules, acr, auditId); try { tokenStore.create(refreshToken); if (auditLogger.isAuditLogEnabled()) { String[] obs = {"CREATED_REFRESH_TOKEN", refreshToken.toString()}; auditLogger.logAccessMessage("CREATED_REFRESH_TOKEN", obs, null); } } catch (CoreTokenException e) { if (auditLogger.isAuditLogEnabled()) { String[] obs = {"FAILED_CREATE_REFRESH_TOKEN", refreshToken.toString()}; auditLogger.logErrorMessage("FAILED_CREATE_REFRESH_TOKEN", obs, null); } logger.error("Unable to create refresh token: " + refreshToken.getTokenInfo(), e); throw new ServerException("Could not create token in CTS: " + e.getMessage()); } request.setToken(RefreshToken.class, refreshToken); return refreshToken; }
/** {@inheritDoc} */ public AccessToken createAccessToken( String grantType, String accessTokenType, String authorizationCode, String resourceOwnerId, String clientId, String redirectUri, Set<String> scope, RefreshToken refreshToken, String nonce, String claims, OAuth2Request request) throws ServerException, NotFoundException { OpenIdConnectClientRegistration clientRegistration = getClientRegistration(clientId, request); final OAuth2ProviderSettings providerSettings = providerSettingsFactory.get(request); final String id = UUID.randomUUID().toString(); final String auditId = UUID.randomUUID().toString(); String realm = realmNormaliser.normalise(request.<String>getParameter(REALM)); long expiryTime = 0; if (clientRegistration == null) { expiryTime = providerSettings.getAccessTokenLifetime() + System.currentTimeMillis(); } else { expiryTime = clientRegistration.getAccessTokenLifeTime(providerSettings) + System.currentTimeMillis(); } final AccessToken accessToken; if (refreshToken == null) { accessToken = new OpenAMAccessToken( id, authorizationCode, resourceOwnerId, clientId, redirectUri, scope, expiryTime, null, OAuth2Constants.Token.OAUTH_ACCESS_TOKEN, grantType, nonce, realm, claims, auditId); } else { accessToken = new OpenAMAccessToken( id, authorizationCode, resourceOwnerId, clientId, redirectUri, scope, expiryTime, refreshToken.getTokenId(), OAuth2Constants.Token.OAUTH_ACCESS_TOKEN, grantType, nonce, realm, claims, auditId); } try { tokenStore.create(accessToken); if (auditLogger.isAuditLogEnabled()) { String[] obs = {"CREATED_TOKEN", accessToken.toString()}; auditLogger.logAccessMessage("CREATED_TOKEN", obs, null); } } catch (CoreTokenException e) { logger.error("Could not create token in CTS: " + e.getMessage()); if (auditLogger.isAuditLogEnabled()) { String[] obs = {"FAILED_CREATE_TOKEN", accessToken.toString()}; auditLogger.logErrorMessage("FAILED_CREATE_TOKEN", obs, null); } throw new ServerException("Could not create token in CTS: " + e.getMessage()); } request.setToken(AccessToken.class, accessToken); return accessToken; }
/** {@inheritDoc} */ public OpenIdConnectToken createOpenIDToken( ResourceOwner resourceOwner, String clientId, String authorizationParty, String nonce, String ops, OAuth2Request request) throws ServerException, InvalidClientException, NotFoundException { final OAuth2ProviderSettings providerSettings = providerSettingsFactory.get(request); final OpenIdConnectClientRegistration clientRegistration = clientRegistrationStore.get(clientId, request); final String algorithm = clientRegistration.getIDTokenSignedResponseAlgorithm(); final long currentTimeInSeconds = System.currentTimeMillis() / 1000; final long exp = clientRegistration.getJwtTokenLifeTime(providerSettings) / 1000 + currentTimeInSeconds; final String realm = realmNormaliser.normalise(request.<String>getParameter(REALM)); final String iss = providerSettings.getIssuer(); final List<String> amr = getAMRFromAuthModules(request, providerSettings); final byte[] clientSecret = clientRegistration.getClientSecret().getBytes(Utils.CHARSET); final KeyPair keyPair = providerSettings.getServerKeyPair(); final String atHash = generateAtHash(algorithm, request, providerSettings); final String cHash = generateCHash(algorithm, request, providerSettings); final String acr = getAuthenticationContextClassReference(request); final String kid = generateKid(providerSettings.getJWKSet(), algorithm); final String opsId = UUID.randomUUID().toString(); final long authTime = resourceOwner.getAuthTime(); final String subId = clientRegistration.getSubValue(resourceOwner.getId(), providerSettings); try { tokenStore.create( json( object( field(OAuth2Constants.CoreTokenParams.ID, set(opsId)), field(OAuth2Constants.JWTTokenParams.LEGACY_OPS, set(ops)), field(OAuth2Constants.CoreTokenParams.EXPIRE_TIME, set(Long.toString(exp)))))); } catch (CoreTokenException e) { logger.error("Unable to create id_token user session token", e); throw new ServerException("Could not create token in CTS"); } final OpenAMOpenIdConnectToken oidcToken = new OpenAMOpenIdConnectToken( kid, clientSecret, keyPair, algorithm, iss, subId, clientId, authorizationParty, exp, currentTimeInSeconds, authTime, nonce, opsId, atHash, cHash, acr, amr, realm); request.setSession(ops); // See spec section 5.4. - add claims to id_token based on 'response_type' parameter String responseType = request.getParameter(OAuth2Constants.Params.RESPONSE_TYPE); if (providerSettings.isAlwaysAddClaimsToToken() || (responseType != null && responseType.trim().equals(OAuth2Constants.JWTTokenParams.ID_TOKEN))) { appendIdTokenClaims(request, providerSettings, oidcToken); } else if (providerSettings.getClaimsParameterSupported()) { appendRequestedIdTokenClaims(request, providerSettings, oidcToken); } return oidcToken; }
/** {@inheritDoc} */ public AuthorizationCode createAuthorizationCode( Set<String> scope, ResourceOwner resourceOwner, String clientId, String redirectUri, String nonce, OAuth2Request request, String codeChallenge, String codeChallengeMethod) throws ServerException, NotFoundException { logger.message("DefaultOAuthTokenStoreImpl::Creating Authorization code"); OpenIdConnectClientRegistration clientRegistration = getClientRegistration(clientId, request); final OAuth2ProviderSettings providerSettings = providerSettingsFactory.get(request); final String code = UUID.randomUUID().toString(); long expiryTime = 0; if (clientRegistration == null) { expiryTime = providerSettings.getAuthorizationCodeLifetime() + System.currentTimeMillis(); } else { expiryTime = clientRegistration.getAuthorizationCodeLifeTime(providerSettings) + System.currentTimeMillis(); } final String ssoTokenId = getSsoTokenId(request); final OpenAMAuthorizationCode authorizationCode = new OpenAMAuthorizationCode( code, resourceOwner.getId(), clientId, redirectUri, scope, getClaimsFromRequest(request), expiryTime, nonce, realmNormaliser.normalise(request.<String>getParameter(REALM)), getAuthModulesFromSSOToken(request), getAuthenticationContextClassReferenceFromRequest(request), ssoTokenId, codeChallenge, codeChallengeMethod); // Store in CTS try { tokenStore.create(authorizationCode); if (auditLogger.isAuditLogEnabled()) { String[] obs = {"CREATED_AUTHORIZATION_CODE", authorizationCode.toString()}; auditLogger.logAccessMessage("CREATED_AUTHORIZATION_CODE", obs, null); } } catch (CoreTokenException e) { if (auditLogger.isAuditLogEnabled()) { String[] obs = {"FAILED_CREATE_AUTHORIZATION_CODE", authorizationCode.toString()}; auditLogger.logErrorMessage("FAILED_CREATE_AUTHORIZATION_CODE", obs, null); } logger.error("Unable to create authorization code " + authorizationCode.getTokenInfo(), e); throw new ServerException("Could not create token in CTS"); } request.setToken(AuthorizationCode.class, authorizationCode); return authorizationCode; }
private String getResourceOwnerId(String resourceSetId) throws NotFoundException, UmaException { OAuth2ProviderSettings providerSettings = oauth2ProviderSettingsFactory.get(requestFactory.create(getRequest())); ResourceSetDescription resourceSetDescription = getResourceSet(resourceSetId, providerSettings); return resourceSetDescription.getResourceOwnerId(); }