@Post public Representation token(final Representation entity) throws OAuth2RestletException { final OAuth2Request request = requestFactory.create(getRequest()); try { final AccessToken accessToken = accessTokenService.requestAccessToken(request); return new JacksonRepresentation<Map<String, Object>>(accessToken.toMap()); } catch (InvalidGrantException e) { throw new OAuth2RestletException( e.getStatusCode(), e.getError(), "Assertion is invalid.", request.<String>getParameter("redirect_uri"), request.<String>getParameter("state")); } catch (ClientAuthenticationFailedException e) { getResponse() .setChallengeRequests( singletonList( new ChallengeRequest( ChallengeScheme.valueOf( SUPPORTED_RESTLET_CHALLENGE_SCHEMES.get(e.getChallengeScheme())), e.getChallengeRealm()))); throw new OAuth2RestletException( e.getStatusCode(), e.getError(), e.getMessage(), request.<String>getParameter("state")); } catch (OAuth2Exception e) { throw new OAuth2RestletException( e.getStatusCode(), e.getError(), e.getMessage(), request.<String>getParameter("redirect_uri"), request.<String>getParameter("state")); } }
/** For at_hash values, used when token and id_token exist in scope. */ private String generateAtHash( String algorithm, OAuth2Request request, OAuth2ProviderSettings providerSettings) throws ServerException { final AccessToken accessToken = request.getToken(AccessToken.class); if (accessToken == null) { logger.message("at_hash generation requires an existing access_token."); return null; } final String accessTokenValue = ((String) accessToken.getTokenInfo().get(OAuth2Constants.Params.ACCESS_TOKEN)); return generateHash(algorithm, accessTokenValue, providerSettings); }
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(); }
/** {@inheritDoc} */ public void additionalDataToReturnFromTokenEndpoint( AccessToken accessToken, OAuth2Request request) throws ServerException, InvalidClientException, NotFoundException { final Map<String, String> data = new HashMap<String, String>(); data.put("nonce", accessToken.getNonce()); data.put( OAuth2Constants.Custom.SSO_TOKEN_ID, getSsoToken(ServletUtils.getRequest(request.<Request>getRequest()))); final Map<String, Object> tokenEntries = scopeValidator.extraDataToReturnForTokenEndpoint( data, new LegacyAccessTokenAdapter(accessToken)); if (tokenEntries != null) { for (final Map.Entry<String, Object> tokenEntry : tokenEntries.entrySet()) { accessToken.addExtraData(tokenEntry.getKey(), (String) tokenEntry.getValue()); } } }
// See spec section 5.5. - add claims to id_token based on 'claims' parameter in the access token private void appendRequestedIdTokenClaims( OAuth2Request request, OAuth2ProviderSettings providerSettings, OpenAMOpenIdConnectToken oidcToken) throws ServerException, NotFoundException, InvalidClientException { AccessToken accessToken = request.getToken(AccessToken.class); String claims; if (accessToken != null) { claims = (String) accessToken.toMap().get(OAuth2Constants.Custom.CLAIMS); } else { claims = request.getParameter(OAuth2Constants.Custom.CLAIMS); } if (claims != null) { try { JSONObject claimsObject = new JSONObject(claims); JSONObject idTokenClaimsRequest = claimsObject.getJSONObject(OAuth2Constants.JWTTokenParams.ID_TOKEN); Map<String, Object> userInfo = providerSettings.getUserInfo(accessToken, request).getValues(); Iterator<String> it = idTokenClaimsRequest.keys(); while (it.hasNext()) { String keyName = it.next(); if (userInfo.containsKey(keyName)) { oidcToken.put(keyName, userInfo.get(keyName)); } } } catch (UnauthorizedClientException e) { throw new InvalidClientException(e.getMessage()); } catch (JSONException e) { // if claims object not found, fall through } } }
public void updateAccessToken(AccessToken accessToken) { try { deleteAccessToken(accessToken.getTokenId()); tokenStore.create(accessToken); } catch (ServerException e) { logger.error( "DefaultOAuthTokenStoreImpl::Unable to delete access token " + accessToken.getTokenId(), e); throw new OAuthProblemException( Status.SERVER_ERROR_INTERNAL.getCode(), "Internal error", "Could not delete token in CTS", null); } catch (CoreTokenException e) { logger.error( "DefaultOAuthTokenStoreImpl::Unable to create access token " + accessToken.getTokenId(), e); throw new OAuthProblemException( Status.SERVER_ERROR_INTERNAL.getCode(), "Internal error", "Could not create token in CTS", null); } }
/** {@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; }
@Post public Representation requestAuthorization(JsonRepresentation entity) throws BadRequestException, UmaException, EntitlementException, ServerException, NotFoundException { UmaProviderSettings umaProviderSettings = umaProviderSettingsFactory.get(this.getRequest()); JsonValue requestBody = json(toMap(entity)); PermissionTicket permissionTicket = getPermissionTicket(umaProviderSettings.getUmaTokenStore(), requestBody); final AccessToken authorisationApiToken = getAuthorisationApiToken(); if (hasExpired(permissionTicket)) { throw new UmaException( 400, UmaConstants.EXPIRED_TICKET_ERROR_CODE, "The permission ticket has expired"); } // Remove permission ticket so it cannot be re-used umaProviderSettings.getUmaTokenStore().deletePermissionTicket(permissionTicket.getId()); final String requestingUserId = authorisationApiToken.getResourceOwnerId(); final String resourceSetId = permissionTicket.getResourceSetId(); final Request request = getRequest(); final String resourceOwnerId = getResourceOwnerId(resourceSetId); auditLogger.log( resourceSetId, resourceOwnerId, UmaAuditType.REQUEST, request, requestingUserId); if (isEntitled(umaProviderSettings, permissionTicket, authorisationApiToken)) { getResponse().setStatus(new Status(200)); auditLogger.log( resourceSetId, resourceOwnerId, UmaAuditType.GRANTED, request, requestingUserId); return createJsonRpt( umaProviderSettings.getUmaTokenStore(), permissionTicket, authorisationApiToken); } else { try { if (verifyPendingRequestDoesNotAlreadyExist( resourceSetId, resourceOwnerId, permissionTicket.getRealm(), requestingUserId, permissionTicket.getScopes())) { auditLogger.log( resourceSetId, resourceOwnerId, UmaAuditType.DENIED, request, requestingUserId); throw new UmaException( 403, UmaConstants.NOT_AUTHORISED_ERROR_CODE, "The client is not authorised to access the requested resource set"); } else { pendingRequestsService.createPendingRequest( ServletUtils.getRequest(getRequest()), resourceSetId, auditLogger.getResourceName(resourceSetId, request), resourceOwnerId, requestingUserId, permissionTicket.getRealm(), permissionTicket.getScopes()); auditLogger.log( resourceSetId, resourceOwnerId, UmaAuditType.REQUEST_SUBMITTED, request, requestingUserId); } } catch (org.forgerock.openam.sm.datalayer.store.ServerException e) { logger.error("Failed to create pending request", e); throw new UmaException( 403, UmaConstants.NOT_AUTHORISED_ERROR_CODE, "Failed to create pending request"); } throw newRequestSubmittedException(); } // TODO not sure where "need_info" error fits in.... }