1. import jwt # For decoding JWTs
  2. import datetime # For handling timestamps
  3. import logging # For logging anomalies
  4. # Configure logging
  5. logging.basicConfig(level=logging.WARNING, format='%(asctime)s - %(levelname)s - %(message)s')
  6. def validate_token(token, expected_iss, expected_aud, expiry_window_hours=24):
  7. """
  8. Validates an authentication token and flags anomalies.
  9. Args:
  10. token (str): The authentication token to validate.
  11. expected_iss (str): The expected issuer of the token.
  12. expected_aud (str): The expected audience of the token.
  13. expiry_window_hours (int): How many hours after expiry to flag.
  14. Returns:
  15. bool: True if the token is valid, False otherwise.
  16. """
  17. try:
  18. # Decode the token
  19. decoded_token = jwt.decode(token, options={"verify_signature": True})
  20. # Check if token is expired
  21. if decoded_token['exp'] < datetime.datetime.utcnow():
  22. logging.warning(f"Token expired: {token}")
  23. return False
  24. # Check issuer
  25. if decoded_token['iss'] != expected_iss:
  26. logging.warning(f"Incorrect issuer: {decoded_token['iss']} != {expected_iss} in token: {token}")
  27. return False
  28. # Check audience
  29. if decoded_token['aud'] != expected_aud:
  30. logging.warning(f"Incorrect audience: {decoded_token['aud']} != {expected_aud} in token: {token}")
  31. return False
  32. # Check for unusual expiry time (e.g., very far in the future)
  33. if decoded_token['exp'] > datetime.datetime.utcnow() + datetime.timedelta(hours=expiry_window_hours):
  34. logging.warning(f"Unusually long expiry time: {decoded_token['exp']} in token: {token}")
  35. return False
  36. return True # Token is valid
  37. except jwt.ExpiredSignatureError:
  38. logging.warning(f"Token expired: {token}")
  39. return False
  40. except jwt.InvalidTokenError:
  41. logging.warning(f"Invalid token: {token}")
  42. return False
  43. except Exception as e:
  44. logging.error(f"Error validating token: {e} in token: {token}")
  45. return False
  46. if __name__ == '__main__':
  47. # Example usage
  48. valid_token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6ImFkbWluIiwiaWF0IjoxNjI3ODg2MDQ4fQ.EXAMPLE_SIGNATURE"
  49. expired_token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6ImFkbWluIiwiaWF0IjoxNjI3ODg2MDQ4fQ.ANOTHER_SIGNATURE"
  50. invalid_issuer_token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6ImFkbWluIiwiaWF0IjoxNjI3ODg2MDQ4fQ.A_DIFFERENT_SIGNATURE"
  51. print(f"Valid token: {validate_token(valid_token, 'my_iss', 'my_aud')}")
  52. print(f"Expired token: {validate_token(expired_token, 'my_iss', 'my_aud')}")
  53. print(f"Invalid issuer token: {validate_token(invalid_issuer_token, 'my_iss', 'my_aud')}")

Add your comment