code: public static String computeSignature(UserDetails userDetails, long expires) {
          MessageDigest digest;
          try {
              digest = MessageDigest.getInstance(MESSAGE_DIGEST_ALGORITHM);
          } catch (NoSuchAlgorithmException e) {
              throw new IllegalStateException("No " + MESSAGE_DIGEST_ALGORITHM + " algorithm available!", e);
          }
  
          String signature = userDetails.getUsername() + TOKEN_SEPARATOR + expires + TOKEN_SEPARATOR + userDetails.getPassword() + TOKEN_SEPARATOR + TokenUtils.MAGIC_KEY;
  
          return new String(Hex.encode(digest.digest(signature.getBytes(Charsets.UTF_8))));
      }
docs: Computes a signature for {@code UserDetails} and expiration time.
  
  @param userDetails user details.
  @param expires     expiration time.
  @return signature.