public bool TryValidate(JwtHeaderDocument header, JwtPayloadDocument payload, [NotNullWhen(false)] out TokenValidationError?error) { if (!payload.TryGetClaim(JwtClaimNames.Exp.EncodedUtf8Bytes, out var expires)) { error = TokenValidationError.MissingClaim(JwtClaimNames.Exp.ToString()); return(false); } if (!payload.TryGetClaim(JwtClaimNames.Jti.EncodedUtf8Bytes, out var jti)) { error = TokenValidationError.MissingClaim(JwtClaimNames.Jti.ToString()); return(false); } if (!_tokenReplayCache.TryAdd(jti.GetString(), expires.GetInt64())) { error = TokenValidationError.TokenReplayed(); return(false); } #if NET5_0_OR_GREATER Unsafe.SkipInit(out error); #else error = default; #endif return(true); }
private Jwt(JwtHeaderDocument header, Jwt nested, byte[] rented) { _header = header; _payload = nested.Payload; _nested = nested; _rented = rented; }
public bool TryValidate(JwtHeaderDocument header, JwtPayloadDocument payload, [NotNullWhen(false)] out TokenValidationError?error) { if (payload is null) { error = TokenValidationError.MalformedToken(); return(false); } if (!payload.TryGetClaim(_claim, out var claim)) { error = TokenValidationError.MissingClaim(_claim); return(false); } if (!claim.TryGetDouble(out var value) || _value != value) { error = TokenValidationError.InvalidClaim(_claim); return(false); } #if NET5_0_OR_GREATER Unsafe.SkipInit(out error); #else error = default; #endif return(true); }
/// <summary>Try to validate the token header, according to the <paramref name="header"/>.</summary> /// <returns><c>true</c> if the <paramref name="header"/> is valid. <c>false</c> otherwise.</returns> public bool TryValidateHeader(JwtHeaderDocument header, [NotNullWhen(false)] out TokenValidationError?error) { if (!IgnoreCriticalHeader) { if (!header.Crit.IsEmpty) { var handlers = CriticalHandlers; foreach (var critHeader in header.Crit.EnumerateArray <string>()) { var critHeaderName = critHeader.GetString() !; if (!handlers.TryGetValue(critHeaderName, out var handler)) { error = TokenValidationError.CriticalHeaderUnsupported(critHeaderName); goto Error; } if (!handler.TryHandle(header, critHeaderName)) { error = TokenValidationError.InvalidHeader(critHeaderName); goto Error; } } } } error = null; return(true); Error: return(false); }
public bool TryValidate(JwtHeaderDocument header, JwtPayloadDocument payload, [NotNullWhen(false)] out TokenValidationError?error) { if (header is null) { ThrowHelper.ThrowArgumentNullException(ExceptionArgument.header); } if (header.Alg.IsEmpty) { error = TokenValidationError.MissingHeader(JwtHeaderParameterNames.Alg.ToString()); return(false); } if (!header.Alg.ValueEquals(_algorithm)) { error = TokenValidationError.InvalidHeader(JwtHeaderParameterNames.Alg.ToString()); return(false); } #if NET5_0_OR_GREATER Unsafe.SkipInit(out error); #else error = default; #endif return(true); }
private Jwt(JwtHeaderDocument header, Jwt nested, TokenValidationError error, byte[] rented) { _header = header; _payload = nested.Payload; _nested = nested; _error = error; _rented = rented; }
internal Jwt(Jwt other) { _rawValue = other._rawValue; _rented = other._rented; _header = other._header; _payload = other._payload; _nested = other._nested; _error = other._error; }
public override bool TryValidateSignature(JwtHeaderDocument header, JwtPayloadDocument payload, ReadOnlySpan <byte> contentBytes, ReadOnlySpan <byte> signatureSegment, [NotNullWhen(false)] out SignatureValidationError?error) { #if NET5_0_OR_GREATER Unsafe.SkipInit(out error); #else error = default; #endif return(true); }
public override bool TryValidateSignature(JwtHeaderDocument header, JwtPayloadDocument payload, ReadOnlySpan <byte> contentBytes, ReadOnlySpan <byte> signatureSegment, [NotNullWhen(false)] out SignatureValidationError?error) { if (!payload.Iss.IsEmpty && payload.Iss.ValueEquals(_issuer)) { return(_policy.TryValidateSignature(header, payload, contentBytes, signatureSegment, out error)); } error = SignatureValidationError.InvalidSignature(); return(false); }
/// <inheritsdoc /> public Jwk[] GetKeys(JwtHeaderDocument header) { if (_disposed) { ThrowHelper.ThrowObjectDisposedException(typeof(CachedKeyProvider)); } var kid = header.Kid; long now = EpochTime.UtcNow; bool forceSync = false; if (_syncAfter > now) { var keys = _currentJwks.GetKeys(kid); if (keys.Length != 0) { return(keys); } // force the refresh only when the latest forced refresh is not too old if (_forcedSyncAfter <= now) { _forcedSyncAfter = now + MinimumRefreshInterval; forceSync = true; } } if (forceSync || _syncAfter <= now) { Jwks previous = _currentJwks; Jwks refreshedJwks; _refreshLock.Wait(); try { if (forceSync || _syncAfter <= now) { refreshedJwks = GetKeysFromSource(); _currentJwks = refreshedJwks; _syncAfter = now + AutomaticRefreshInterval; Jwks.PublishJwksRefreshed(previous, refreshedJwks); } } catch { _syncAfter = now + Math.Min(AutomaticRefreshInterval, MinimumRefreshInterval); throw; } finally { _refreshLock.Release(); } } return(_currentJwks.GetKeys(kid)); }
public override bool TryValidateSignature(JwtHeaderDocument header, JwtPayloadDocument payload, ReadOnlySpan <byte> contentBytes, ReadOnlySpan <byte> signatureSegment, [NotNullWhen(false)] out SignatureValidationError?error) { if ((contentBytes.Length == 0 && signatureSegment.Length == 0) || (signatureSegment.IsEmpty && !header.Alg.IsEmpty && header.Alg.ValueEquals(SignatureAlgorithm.None.Utf8Name))) { error = null; return(true); } error = SignatureValidationError.InvalidSignature(); return(false); }
public override bool TryValidateSignature(JwtHeaderDocument header, JwtPayloadDocument payload, ReadOnlySpan <byte> contentBytes, ReadOnlySpan <byte> signatureSegment, [NotNullWhen(false)] out SignatureValidationError?error) { if (!payload.Iss.IsEmpty) { if (TryGetPolicy(payload.Iss, out var policy)) { return(policy.TryValidateSignature(header, payload, contentBytes, signatureSegment, out error)); } } return(_defaultPolicy.TryValidateSignature(header, payload, contentBytes, signatureSegment, out error)); }
public override bool TryValidateSignature(JwtHeaderDocument header, JwtPayloadDocument payload, ReadOnlySpan <byte> contentBytes, ReadOnlySpan <byte> signatureSegment, [NotNullWhen(false)] out SignatureValidationError?error) { if ((contentBytes.Length == 0 && signatureSegment.Length == 0) || (signatureSegment.IsEmpty && !header.Alg.IsEmpty && header.Alg.ValueEquals(SignatureAlgorithm.None.Utf8Name))) { #if NET5_0_OR_GREATER Unsafe.SkipInit(out error); #else error = default; #endif return(true); } error = SignatureValidationError.InvalidSignature(); return(false); }
public bool TryValidate(JwtHeaderDocument header, JwtPayloadDocument payload, [NotNullWhen(false)] out TokenValidationError?error) { if (payload is null) { error = TokenValidationError.MalformedToken(); return(false); } if (payload.ContainsClaim(OAuth2Claims.AuthTime.EncodedUtf8Bytes)) { error = null; return(true); } error = TokenValidationError.MissingClaim(OAuth2Claims.AuthTime.ToString()); return(false); }
public bool TryValidate(JwtHeaderDocument header, JwtPayloadDocument payload, [NotNullWhen(false)] out TokenValidationError?error) { if (payload is null) { error = TokenValidationError.MalformedToken(); return(false); } if (payload.ContainsClaim(_claim)) { error = null; return(true); } error = TokenValidationError.MissingClaim(_claim); return(false); }
/// <inheritsdoc /> private Jwk[] GetKeys(JwtHeaderDocument header, string metadataAddress) { if (_disposed) { ThrowHelper.ThrowObjectDisposedException(typeof(JwksHttpKeyProvider)); } var kid = header.Kid; long now = EpochTime.UtcNow; if (_currentJwks != null && _syncAfter > now) { return(_currentJwks.GetKeys(kid)); } if (_syncAfter <= now) { _refreshLock.Wait(); try { var value = _documentRetriever.GetDocument(metadataAddress, CancellationToken.None); var refreshedJwks = Jwks.FromJson(Issuer, value); Jwks.PublishJwksRefreshed(refreshedJwks); _currentJwks = refreshedJwks; _syncAfter = now + AutomaticRefreshInterval; } catch { _syncAfter = now + (AutomaticRefreshInterval < RefreshInterval ? AutomaticRefreshInterval : RefreshInterval); throw; } finally { _refreshLock.Release(); } } if (_currentJwks != null) { return(_currentJwks.GetKeys(kid)); } ThrowHelper.ThrowInvalidOperationException_UnableToObtainKeysException(metadataAddress); return(Array.Empty <Jwk>()); }
public bool TryValidate(JwtHeaderDocument header, JwtPayloadDocument payload, [NotNullWhen(false)] out TokenValidationError?error) { if (payload is null) { error = TokenValidationError.MalformedToken(); return(false); } if (payload.ContainsClaim(_claim)) { #if NET5_0_OR_GREATER Unsafe.SkipInit(out error); #else error = default; #endif return(true); } error = TokenValidationError.MissingClaim(_claim); return(false); }
public bool TryValidate(JwtHeaderDocument header, JwtPayloadDocument payload, [NotNullWhen(false)] out TokenValidationError?error) { if (header is null) { ThrowHelper.ThrowArgumentNullException(ExceptionArgument.header); } if (header.Alg.IsEmpty) { error = TokenValidationError.MissingHeader(JwtHeaderParameterNames.Alg.ToString()); return(false); } if (!header.Alg.ValueEquals(_algorithm)) { error = TokenValidationError.InvalidHeader(JwtHeaderParameterNames.Alg.ToString()); return(false); } error = null; return(true); }
public bool TryValidate(JwtHeaderDocument header, JwtPayloadDocument payload, [NotNullWhen(false)] out TokenValidationError?error) { if (!payload.TryGetClaim(JwtClaimNames.Exp.EncodedUtf8Bytes, out var expires)) { error = TokenValidationError.MissingClaim(JwtClaimNames.Exp.ToString()); return(false); } if (!payload.TryGetClaim(JwtClaimNames.Jti.EncodedUtf8Bytes, out var jti)) { error = TokenValidationError.MissingClaim(JwtClaimNames.Jti.ToString()); return(false); } if (!_tokenReplayCache.TryAdd(jti.GetString(), expires.GetInt64())) { error = TokenValidationError.TokenReplayed(); return(false); } error = null; return(true); }
public bool TryValidate(JwtHeaderDocument header, JwtPayloadDocument payload, [NotNullWhen(false)] out TokenValidationError?error) { if (payload is null) { error = TokenValidationError.MalformedToken(); return(false); } if (!payload.TryGetClaim(_claim, out var claim)) { error = TokenValidationError.MissingClaim(_claim); return(false); } if (!claim.TryGetDouble(out var value) || _value != value) { error = TokenValidationError.InvalidClaim(_claim); return(false); } error = null; return(true); }
public bool TryValidate(JwtHeaderDocument header, JwtPayloadDocument payload, [NotNullWhen(false)] out TokenValidationError?error) { if (payload is null) { error = TokenValidationError.MalformedToken(); return(false); } if (!payload.TryGetClaim(OAuth2Claims.Acr.EncodedUtf8Bytes, out var property)) { error = TokenValidationError.MissingClaim(OAuth2Claims.Acr.ToString()); return(false); } if (!property.ValueEquals(_requiredAcr)) { error = TokenValidationError.InvalidClaim(OAuth2Claims.Acr.ToString()); return(false); } error = null; return(true); }
/// <inheritdoc/> public void AddHeader(ReadOnlySpan <byte> rawHeader, JwtHeaderDocument header) { bool lockTaken = false; try { _spinLock.Enter(ref lockTaken); var node = new Node(rawHeader.ToArray(), header.Clone(), _head); if (_count >= MaxSize) { RemoveLeastRecentlyUsed(); } else { _count++; } if (_head != null) { _head.Previous = node; } _head = node; if (_tail is null) { _tail = node; } } finally { if (lockTaken) { _spinLock.Exit(); } } }
public Node(byte[] key, JwtHeaderDocument header, Node?next) { Key = key; Header = header; Next = next; }
public void AddHeader(ReadOnlySpan <byte> rawHeader, JwtHeaderDocument header) { }
public bool TryValidateSignature(JwtHeaderDocument header, JwtPayloadDocument payload, ReadOnlySpan <byte> contentBytes, ReadOnlySpan <byte> signatureSegment, [NotNullWhen(false)] out SignatureValidationError?error) { return(SignatureValidationPolicy.TryValidateSignature(header, payload, contentBytes, signatureSegment, out error)); }
/// <summary>Try to validate the token, according to the <paramref name="header"/> and the <paramref name="payload"/>.</summary> public bool TryValidateJwt(JwtHeaderDocument header, JwtPayloadDocument payload, [NotNullWhen(false)] out TokenValidationError?error) { if (payload.Control != 0) { if (RequireAudience) { if (payload.MissingAudience) { error = TokenValidationError.MissingClaim(JwtClaimNames.Aud.ToString()); goto Error; } if (payload.InvalidAudience) { error = TokenValidationError.InvalidClaim(JwtClaimNames.Aud.ToString()); goto Error; } } if (RequireIssuer) { if (payload.MissingIssuer) { error = TokenValidationError.MissingClaim(JwtClaimNames.Iss.ToString()); goto Error; } if (payload.InvalidIssuer) { error = TokenValidationError.InvalidClaim(JwtClaimNames.Iss.ToString()); goto Error; } } if (RequireExpirationTime) { if (payload.MissingExpirationTime) { error = TokenValidationError.MissingClaim(JwtClaimNames.Exp.ToString()); goto Error; } if (payload.Expired) { error = TokenValidationError.Expired(); goto Error; } } if (payload.NotYetValid) { error = TokenValidationError.NotYetValid(); goto Error; } } var validators = _validators; for (int i = 0; i < validators.Length; i++) { if (!validators[i].TryValidate(header, payload, out error)) { goto Error; } } #if NET5_0_OR_GREATER Unsafe.SkipInit(out error); #else error = default; #endif return(true); Error: return(false); }
internal Jwt(JwtHeaderDocument header, JwtPayloadDocument payload) { _header = header; _payload = payload; }
private Jwt(JwtHeaderDocument header, JwtPayloadDocument payload, TokenValidationError error) { _header = header; _payload = payload; _error = error; }
internal static bool TryParseHeader(ReadOnlyMemory <byte> utf8Payload, byte[]?buffer, TokenValidationPolicy policy, [NotNullWhen(true)] out JwtHeaderDocument?header, [NotNullWhen(false)] out TokenValidationError?error) { ReadOnlySpan <byte> utf8JsonSpan = utf8Payload.Span; var database = new JsonMetadata(utf8Payload.Length); int algIdx = -1; int encIdx = -1; int kidIdx = -1; int critIdx = -1; var reader = new Utf8JsonReader(utf8JsonSpan); if (reader.Read()) { JsonTokenType tokenType = reader.TokenType; if (tokenType == JsonTokenType.StartObject) { while (reader.Read()) { tokenType = reader.TokenType; int tokenStart = (int)reader.TokenStartIndex; if (tokenType == JsonTokenType.EndObject) { break; } else if (tokenType != JsonTokenType.PropertyName) { error = TokenValidationError.MalformedToken(); goto Error; } // Adding 1 to skip the start quote will never overflow Debug.Assert(tokenStart < int.MaxValue); database.Append(JsonTokenType.PropertyName, tokenStart + 1, reader.ValueSpan.Length); if (reader.ValueSpan.IndexOf((byte)'\\') != -1) { database.SetNeedUnescaping(database.Length - JsonRow.Size); } ReadOnlySpan <byte> memberName = reader.ValueSpan; reader.Read(); tokenType = reader.TokenType; tokenStart = (int)reader.TokenStartIndex; // Since the input payload is contained within a Span, // token start index can never be larger than int.MaxValue (i.e. utf8JsonSpan.Length). Debug.Assert(reader.TokenStartIndex <= int.MaxValue); if (tokenType == JsonTokenType.String) { if (memberName.Length == 3) { switch ((JwtHeaderParameters)IntegerMarshal.ReadUInt24(memberName)) { case JwtHeaderParameters.Alg: algIdx = database.Length; break; case JwtHeaderParameters.Enc: encIdx = database.Length; break; case JwtHeaderParameters.Kid: kidIdx = database.Length; break; } } // Adding 1 to skip the start quote will never overflow Debug.Assert(tokenStart < int.MaxValue); database.Append(JsonTokenType.String, tokenStart + 1, reader.ValueSpan.Length); } else if (tokenType == JsonTokenType.StartObject) { int count = Utf8JsonReaderHelper.SkipObject(ref reader); int index = database.Length; int tokenEnd = (int)reader.TokenStartIndex; database.Append(JsonTokenType.StartObject, tokenStart, tokenEnd - tokenStart + 1); database.SetNumberOfRows(index, count); } else if (tokenType == JsonTokenType.StartArray) { int count; if (memberName.Length == 4 && (JwtHeaderParameters)IntegerMarshal.ReadUInt32(memberName) == JwtHeaderParameters.Crit && !policy.IgnoreCriticalHeader) { critIdx = database.Length; if (!TryCheckCrit(ref reader, out count)) { error = TokenValidationError.MalformedToken("The 'crit' header parameter must be an array of string."); goto Error; } } else { count = Utf8JsonReaderHelper.SkipArray(ref reader); } int index = database.Length; int tokenEnd = (int)reader.TokenStartIndex; database.Append(JsonTokenType.StartArray, tokenStart, tokenEnd - tokenStart + 1); database.SetNumberOfRows(index, count); } else { Debug.Assert(tokenType >= JsonTokenType.Number && tokenType <= JsonTokenType.Null); database.Append(tokenType, tokenStart, reader.ValueSpan.Length); } } } } Debug.Assert(reader.BytesConsumed == utf8JsonSpan.Length); database.CompleteAllocations(); header = new JwtHeaderDocument(new JwtDocument(utf8Payload, database, buffer), algIdx, encIdx, kidIdx, critIdx); #if NET5_0_OR_GREATER Unsafe.SkipInit(out error); #else error = default; #endif return(true); Error: #if NET5_0_OR_GREATER Unsafe.SkipInit(out header); #else header = default; #endif return(false); }
/// <inheritsdoc /> public Jwk[] GetKeys(JwtHeaderDocument header) { return(GetKeys(header, _jwksAddress)); }