private void cleanupNonces() { long now = System.currentTimeMillis() / 1000; // don't clean out the NONCES for each request, this would cause the service to be constantly locked on this // loop under load. One second is small enough that cleaning up does not become too expensive. // Also see SECOAUTH-180 for reasons this class was refactored. if (now - lastCleaned > 1) { Iterator<NonceEntry> iterator = NONCES.iterator(); while (iterator.hasNext()) { // the nonces are already sorted, so simply iterate and remove until the first nonce within the validity // window. NonceEntry nextNonce = iterator.next(); long difference = now - nextNonce.timestamp; if (difference > getValidityWindowSeconds()) { iterator.remove(); } else { break; } } // keep track of when cleanupNonces last ran lastCleaned = now; } }
/** * Validates the nonce. * * @param consumerKey consumer key * @param timestamp timestamp as the number of seconds since January 1, 1970 00:00:00 GMT (according to OAuth 1.0 spec) * @param nonce nonce * @throws OAuthProblemException if the nonce has been used. */ public void validateNonce(String consumerKey, long timestamp, String nonce) throws OAuthProblemException { Preconditions.checkNotNull(consumerKey); Preconditions.checkNotNull(nonce); NonceEntry entry = new NonceEntry(consumerKey, timestamp, nonce); synchronized (NONCES) { if (NONCES.contains(entry)) { throw new OAuthProblemException(OAuth.Problems.NONCE_USED); } else { NONCES.add(entry); } cleanupNonces(); } }
@Override protected void validateTimestampAndNonce(OAuthMessage message) throws IOException, OAuthProblemException { super.validateTimestampAndNonce(message); // Both timestamp and nonce params cannot be null since they have been checked in {@link SimpleOAuthValidator#validateTimestampAndNonce}. final long timestamp = Long.parseLong(message.getParameter(OAuth.OAUTH_TIMESTAMP)); final String nonce = message.getParameter(OAuth.OAUTH_NONCE); nonceServiceService.validateNonce(message.getConsumerKey(), timestamp, nonce); } };