/// <summary> /// Parses a JWT string encoded. /// </summary> /// <param name="jwt">The string encoded.</param> /// <param name="algorithm">The signature algorithm.</param> /// <param name="verify">true if verify the signature; otherwise, false.</param> /// <returns>A JSON web token object.</returns> /// <exception cref="ArgumentNullException">jwt was null or empty. -or- algorithm was null and verify is true.</exception> /// <exception cref="ArgumentException">jwt did not contain any information.</exception> /// <exception cref="FormatException">jwt was in incorrect format.</exception> /// <exception cref="InvalidOperationException">Verify failure.</exception> public static JsonWebToken <T> Parse(string jwt, ISignatureProvider algorithm, bool verify = true) { if (string.IsNullOrWhiteSpace(jwt)) { throw new ArgumentNullException(nameof(jwt), "jwt should not be null or empty."); } var prefix = $"{TokenInfo.BearerTokenType} "; if (jwt.IndexOf(prefix) == 0) { if (jwt.Length == prefix.Length) { throw new ArgumentException("jwt should not contain a scheme only.", nameof(jwt)); } jwt = jwt.Substring(prefix.Length); } var arr = jwt.Split('.'); if (arr.Length < 3) { throw new FormatException("jwt is not in the correct format."); } if (verify) { var bytes = Encoding.ASCII.GetBytes($"{arr[0]}.{arr[1]}"); var sign = WebFormat.Base64UrlDecode(arr[2]); if (algorithm != null) { if (!algorithm.Verify(bytes, sign)) { throw new InvalidOperationException("jwt signature is incorrect."); } } else { if (sign.Length > 0) { throw new ArgumentNullException(nameof(algorithm), "algorithm should not be null."); } } } var header = WebFormat.Base64UrlDecodeTo <JsonWebTokenHeader>(arr[0]); if (header == null) { throw new ArgumentException("jwt should contain header in Base64Url.", nameof(jwt)); } var payload = WebFormat.Base64UrlDecodeTo <T>(arr[1]); if (payload == null) { throw new ArgumentException("jwt should contain payload in Base64Url.", nameof(jwt)); } var obj = new JsonWebToken <T>(payload, algorithm) { headerBase64Url = arr[0], signatureCache = arr[2] }; obj.header.Type = header.Type; obj.header.AlgorithmName = header.AlgorithmName; return(obj); }
/// <summary> /// Refreshs the cache. /// </summary> private void Refresh() { headerCache = WebFormat.Base64UrlDecodeTo <JsonWebTokenHeader>(HeaderBase64Url) ?? JsonWebTokenHeader.NoAlgorithm; payloadCache = WebFormat.Base64UrlDecodeTo <T>(PayloadBase64Url); }