/**
  * Create a signature given the set of request credentials and a secret key.
  *
  * @param credentials the credentials specified on the request
  * @param secretKey the secret key that will be used to generate the signature
  * @return the signature
  */
 private String createSignature(Credentials credentials, String secretKey) {
   return new SignatureGenerator()
       .generate(
           secretKey,
           credentials.getMethod(),
           credentials.getTimestamp(),
           credentials.getPath(),
           credentials.getContent());
 }
  @Override
  public Principal authenticate(Credentials credentials) {
    // Make sure the timestamp has not expired - this is to protect against replay attacks
    if (!validateTimestamp(credentials.getTimestamp())) {
      LOG.info("Invalid timestamp");
      return null;
    }

    // Get the principal identified by the credentials
    Principal principal = getPrincipal(credentials);
    if (principal == null) {
      LOG.info("Could not get principal");
      return null;
    }

    // Get the secret key and use it to validate the request signature
    String secretKey = getSecretKeyFromPrincipal(principal);
    if (!validateSignature(credentials, secretKey)) {
      LOG.info("Invalid signature");
      return null;
    }

    return principal;
  }
 /**
  * Validate the signature on the request by generating a new signature here and making sure they
  * match. The only way for them to match is if both signature are generated using the same secret
  * key. If they match, this means that the requester has a valid secret key and can be a trusted
  * source.
  *
  * @param credentials the credentials specified on the request
  * @param secretKey the secret key that will be used to generate the signature
  * @return true if the signature is valid
  */
 private boolean validateSignature(Credentials credentials, String secretKey) {
   String clientSignature = credentials.getSignature();
   String serverSignature = createSignature(credentials, secretKey);
   return MessageDigest.isEqual(clientSignature.getBytes(), serverSignature.getBytes());
 }