Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/time provider #2612

Open
wants to merge 4 commits into
base: dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion build/common.props
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@
<EnforceCodeStyleInBuild>true</EnforceCodeStyleInBuild>
</PropertyGroup>

<PropertyGroup Condition=" $([MSBuild]::IsTargetFrameworkCompatible('$(TargetFramework)', 'net8.0')) ">
<DefineConstants>$(DefineConstants);SUPPORTS_TIME_PROVIDER</DefineConstants>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why a new define and not just NET8+

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is not a big reason but a matter of personal preference. It allows easy integration of Microsoft.Bcl.TimeProvider if requested.

If you prefer NET8_0_OR_GREATER, I will change it.

</PropertyGroup>

<PropertyGroup>
<EnablePackageValidation>false</EnablePackageValidation>
Expand Down Expand Up @@ -72,5 +75,5 @@
<PropertyGroup Condition="'$(TargetFramework)' == 'net8.0'">
<IsAotCompatible>true</IsAotCompatible>
</PropertyGroup>

</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -835,7 +835,11 @@ internal static void WriteJwsPayload(
// By default we set these three properties only if they haven't been detected before.
if (setDefaultTimesOnTokenCreation && !(expSet && iatSet && nbfSet))
{
DateTime now = DateTime.UtcNow;
DateTime now =
#if SUPPORTS_TIME_PROVIDER
tokenDescriptor.TimeProvider?.GetUtcNow().UtcDateTime ??
#endif
DateTime.UtcNow;

if (!expSet)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,12 +88,30 @@ public virtual string GenerateNonce()
string nonce = Convert.ToBase64String(Encoding.UTF8.GetBytes(Guid.NewGuid().ToString() + Guid.NewGuid().ToString()));
if (RequireTimeStampInNonce)
{
return DateTime.UtcNow.Ticks.ToString(CultureInfo.InvariantCulture) + "." + nonce;
DateTime utcNow =
#if SUPPORTS_TIME_PROVIDER
TimeProvider?.GetUtcNow().UtcDateTime ??
#endif
DateTime.UtcNow;

return utcNow.Ticks.ToString(CultureInfo.InvariantCulture) + "." + nonce;
}

return nonce;
}

#if SUPPORTS_TIME_PROVIDER
#nullable enable
/// <summary>
/// Gets or sets the time provider.
/// </summary>
/// <remarks>
/// If not set, fall back to using the <see cref="DateTime"/> class to obtain the current time.
/// </remarks>
public TimeProvider? TimeProvider { get; set; }
#nullable restore
#endif

/// <summary>
/// Gets the algorithm mapping between OpenIdConnect and .Net for Hash algorithms.
/// a <see cref="IDictionary{TKey, TValue}"/> that contains mappings from the JWT namespace <see href="https://datatracker.ietf.org/doc/html/rfc7518"/> to .NET.
Expand Down Expand Up @@ -658,7 +676,12 @@ protected virtual void ValidateNonce(OpenIdConnectProtocolValidationContext vali
throw LogHelper.LogExceptionMessage(new OpenIdConnectProtocolInvalidNonceException(LogHelper.FormatInvariant(LogMessages.IDX21327, LogHelper.MarkAsNonPII(timestamp), LogHelper.MarkAsNonPII(DateTime.MinValue.Ticks.ToString(CultureInfo.InvariantCulture)), LogHelper.MarkAsNonPII(DateTime.MaxValue.Ticks.ToString(CultureInfo.InvariantCulture))), ex));
}

DateTime utcNow = DateTime.UtcNow;
DateTime utcNow =
#if SUPPORTS_TIME_PROVIDER
TimeProvider?.GetUtcNow().UtcDateTime ??
#endif
DateTime.UtcNow;

if (nonceTime + NonceLifetime < utcNow)
throw LogHelper.LogExceptionMessage(new OpenIdConnectProtocolInvalidNonceException(LogHelper.FormatInvariant(LogMessages.IDX21324, nonceFoundInJwt, LogHelper.MarkAsNonPII(nonceTime.ToString(CultureInfo.InvariantCulture)), LogHelper.MarkAsNonPII(utcNow.ToString(CultureInfo.InvariantCulture)), LogHelper.MarkAsNonPII(NonceLifetime.ToString("c", CultureInfo.InvariantCulture)))));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ public class SignedHttpRequestCreationParameters
/// Gets or sets a value indicating whether the <see cref="ConfirmationClaimTypes.Cnf"/> claim should be created and added or not.
/// </summary>
/// <remarks>
/// <see cref="SignedHttpRequestDescriptor.CnfClaimValue"/> will be used as a "cnf" claim value, if set.
/// <see cref="SignedHttpRequestDescriptor.CnfClaimValue"/> will be used as a "cnf" claim value, if set.
/// Otherwise, a "cnf" claim value will be derived from <see cref="SignedHttpRequestDescriptor.SigningCredentials"/>.
/// </remarks>
public bool CreateCnf { get; set; } = true;
Expand All @@ -27,19 +27,19 @@ public class SignedHttpRequestCreationParameters
/// <summary>
/// Gets or sets a value indicating whether the <see cref="SignedHttpRequestClaimTypes.Ts"/> claim should be created and added or not.
/// </summary>
/// <remarks>https://datatracker.ietf.org/doc/html/draft-ietf-oauth-signed-http-request-03#section-3</remarks>
/// <remarks>https://datatracker.ietf.org/doc/html/draft-ietf-oauth-signed-http-request-03#section-3</remarks>
public bool CreateTs { get; set; } = true;

/// <summary>
/// Gets or sets a value indicating whether the <see cref="SignedHttpRequestClaimTypes.M"/> claim should be created and added or not.
/// </summary>
/// <remarks>https://datatracker.ietf.org/doc/html/draft-ietf-oauth-signed-http-request-03#section-3</remarks>
/// <remarks>https://datatracker.ietf.org/doc/html/draft-ietf-oauth-signed-http-request-03#section-3</remarks>
public bool CreateM { get; set; } = true;

/// <summary>
/// Gets or sets a value indicating whether the <see cref="SignedHttpRequestClaimTypes.U"/> claim should be created and added or not.
/// </summary>
/// <remarks>https://datatracker.ietf.org/doc/html/draft-ietf-oauth-signed-http-request-03#section-3</remarks>
/// <remarks>https://datatracker.ietf.org/doc/html/draft-ietf-oauth-signed-http-request-03#section-3</remarks>
public bool CreateU { get; set; } = true;

/// <summary>
Expand All @@ -51,19 +51,19 @@ public class SignedHttpRequestCreationParameters
/// <summary>
/// Gets or sets a value indicating whether the <see cref="SignedHttpRequestClaimTypes.Q"/> claim should be created and added or not.
/// </summary>
/// <remarks>https://datatracker.ietf.org/doc/html/draft-ietf-oauth-signed-http-request-03#section-3</remarks>
/// <remarks>https://datatracker.ietf.org/doc/html/draft-ietf-oauth-signed-http-request-03#section-3</remarks>
public bool CreateQ { get; set; }

/// <summary>
/// Gets or sets a value indicating whether the <see cref="SignedHttpRequestClaimTypes.H"/> claim should be created and added or not.
/// </summary>
/// <remarks>https://datatracker.ietf.org/doc/html/draft-ietf-oauth-signed-http-request-03#section-3</remarks>
/// <remarks>https://datatracker.ietf.org/doc/html/draft-ietf-oauth-signed-http-request-03#section-3</remarks>
public bool CreateH { get; set; }

/// <summary>
/// Gets or sets a value indicating whether the <see cref="SignedHttpRequestClaimTypes.B"/> claim should be created and added or not.
/// </summary>
/// <remarks>https://datatracker.ietf.org/doc/html/draft-ietf-oauth-signed-http-request-03#section-3</remarks>
/// <remarks>https://datatracker.ietf.org/doc/html/draft-ietf-oauth-signed-http-request-03#section-3</remarks>
public bool CreateB { get; set; }

/// <summary>
Expand All @@ -76,5 +76,17 @@ public class SignedHttpRequestCreationParameters
/// </summary>
/// <remarks>Allows for adjusting the local time so it matches a server time.</remarks>
public TimeSpan TimeAdjustment { get; set; } = DefaultTimeAdjustment;

#if SUPPORTS_TIME_PROVIDER
#nullable enable
/// <summary>
/// Gets or sets the time provider.
/// </summary>
/// <remarks>
/// If not set, fall back to using the <see cref="DateTime"/> class to obtain the current time.
/// </remarks>
public TimeProvider? TimeProvider { get; set; }
#nullable restore
#endif
}
}
Loading