mirror of
https://github.com/DuendeSoftware/products
synced 2026-05-24 09:28:24 +00:00
Rename expiration mode for clarity
This is based on feedback from Brock and Dom
This commit is contained in:
parent
68806859c8
commit
46a9dab6c3
6 changed files with 28 additions and 28 deletions
|
|
@ -40,9 +40,9 @@ public sealed class DPoPOptions
|
|||
|
||||
/// <summary>
|
||||
/// Controls how the issued at time of proof tokens is validated. Defaults to <see
|
||||
/// cref="ExpirationMode.IssuedAt"/>.
|
||||
/// cref="DPoPProofExpirationMode.IssuedAt"/>.
|
||||
/// </summary>
|
||||
public ExpirationMode ProofTokenExpirationMode { get; set; } = ExpirationMode.IssuedAt;
|
||||
public DPoPProofExpirationMode ProofTokenExpirationMode { get; set; } = DPoPProofExpirationMode.IssuedAt;
|
||||
|
||||
/// <summary>
|
||||
/// The maximum allowed length of a proof token, which is enforced to
|
||||
|
|
|
|||
|
|
@ -6,14 +6,14 @@ namespace Duende.AspNetCore.Authentication.JwtBearer.DPoP;
|
|||
/// <summary>
|
||||
/// Controls how the issued at time of proof tokens is validated.
|
||||
/// </summary>
|
||||
public enum ExpirationMode
|
||||
public enum DPoPProofExpirationMode
|
||||
{
|
||||
/// <summary>
|
||||
/// Validate the time from the server-issued nonce.
|
||||
/// Validate the expiration time from the server-issued nonce.
|
||||
/// </summary>
|
||||
Nonce,
|
||||
/// <summary>
|
||||
/// Validate the time from the iat claim in the proof token.
|
||||
/// Validate the expiration time from the iat claim in the proof token.
|
||||
/// </summary>
|
||||
IssuedAt,
|
||||
/// <summary>
|
||||
|
|
@ -384,8 +384,8 @@ internal class DPoPProofValidator : IDPoPProofValidator
|
|||
}
|
||||
|
||||
// get the largest skew based on how the client's freshness is validated
|
||||
var validateIat = dPoPOptions.ProofTokenExpirationMode != ExpirationMode.Nonce;
|
||||
var validateNonce = dPoPOptions.ProofTokenExpirationMode != ExpirationMode.IssuedAt;
|
||||
var validateIat = dPoPOptions.ProofTokenExpirationMode != DPoPProofExpirationMode.Nonce;
|
||||
var validateNonce = dPoPOptions.ProofTokenExpirationMode != DPoPProofExpirationMode.IssuedAt;
|
||||
var skew = TimeSpan.Zero;
|
||||
if (validateIat && dPoPOptions.ProofTokenIssuedAtClockSkew > skew)
|
||||
{
|
||||
|
|
@ -412,7 +412,7 @@ internal class DPoPProofValidator : IDPoPProofValidator
|
|||
{
|
||||
var dPoPOptions = OptionsMonitor.Get(context.Scheme);
|
||||
|
||||
var validateIat = dPoPOptions.ProofTokenExpirationMode != ExpirationMode.Nonce;
|
||||
var validateIat = dPoPOptions.ProofTokenExpirationMode != DPoPProofExpirationMode.Nonce;
|
||||
if (validateIat)
|
||||
{
|
||||
ValidateIat(context, result);
|
||||
|
|
@ -422,7 +422,7 @@ internal class DPoPProofValidator : IDPoPProofValidator
|
|||
}
|
||||
}
|
||||
|
||||
var validateNonce = dPoPOptions.ProofTokenExpirationMode != ExpirationMode.IssuedAt;
|
||||
var validateNonce = dPoPOptions.ProofTokenExpirationMode != DPoPProofExpirationMode.IssuedAt;
|
||||
if (validateNonce)
|
||||
{
|
||||
ValidateNonce(context, result);
|
||||
|
|
@ -441,7 +441,7 @@ internal class DPoPProofValidator : IDPoPProofValidator
|
|||
DPoPProofValidationResult result)
|
||||
{
|
||||
// iat is required by an earlier validation, so result.IssuedAt will not be null
|
||||
if (IsExpired(context, result.IssuedAt!.Value, ExpirationMode.IssuedAt))
|
||||
if (IsExpired(context, result.IssuedAt!.Value, DPoPProofExpirationMode.IssuedAt))
|
||||
{
|
||||
result.SetError("Invalid 'iat' value.");
|
||||
}
|
||||
|
|
@ -473,19 +473,19 @@ internal class DPoPProofValidator : IDPoPProofValidator
|
|||
/// Validates the expiration of the DPoP proof.
|
||||
/// Returns true if the time is beyond the allowed limits, false otherwise.
|
||||
/// </summary>
|
||||
internal bool IsExpired(DPoPProofValidationContext context, long time, ExpirationMode mode)
|
||||
internal bool IsExpired(DPoPProofValidationContext context, long time, DPoPProofExpirationMode mode)
|
||||
{
|
||||
// It is the responsibility of the caller to call this method with either ExpirationMode.IssuedAt or ExpirationMode.Nonce.
|
||||
// Even if the configured ExpirationMode is Both, we are validating one or the other at this point, and the
|
||||
// caller should make two calls, passing the more specific modes.
|
||||
if (mode == ExpirationMode.Both)
|
||||
if (mode == DPoPProofExpirationMode.Both)
|
||||
{
|
||||
throw new ArgumentException("IsExpired should be called with a specific mode (IssuedAt or Nonce), not Both.", nameof(mode));
|
||||
}
|
||||
|
||||
var dpopOptions = OptionsMonitor.Get(context.Scheme);
|
||||
var validityDuration = dpopOptions.ProofTokenLifetime;
|
||||
var skew = mode == ExpirationMode.Nonce ? dpopOptions.ProofTokenNonceClockSkew
|
||||
var skew = mode == DPoPProofExpirationMode.Nonce ? dpopOptions.ProofTokenNonceClockSkew
|
||||
: dpopOptions.ProofTokenIssuedAtClockSkew;
|
||||
|
||||
return ExpirationValidator.IsExpired(validityDuration, skew, time);
|
||||
|
|
|
|||
|
|
@ -162,7 +162,7 @@ public class DPoPIntegrationTests
|
|||
[Fact]
|
||||
public async Task missing_nonce_generates_server_issued_nonce()
|
||||
{
|
||||
ApiOptions = opt => opt.ProofTokenExpirationMode = ExpirationMode.Nonce;
|
||||
ApiOptions = opt => opt.ProofTokenExpirationMode = DPoPProofExpirationMode.Nonce;
|
||||
await Initialize();
|
||||
var token = await LoginAndGetToken();
|
||||
Api.HttpClient.SetToken("DPoP", token.AccessToken);
|
||||
|
|
@ -203,7 +203,7 @@ public class DPoPIntegrationTests
|
|||
|
||||
ApiOptions = opt =>
|
||||
{
|
||||
opt.ProofTokenExpirationMode = ExpirationMode.Nonce;
|
||||
opt.ProofTokenExpirationMode = DPoPProofExpirationMode.Nonce;
|
||||
};
|
||||
Api.OnConfigureServices += services =>
|
||||
{
|
||||
|
|
|
|||
|
|
@ -133,10 +133,10 @@ public class FreshnessTests : DPoPProofValidatorTestBase
|
|||
}
|
||||
}
|
||||
[Theory]
|
||||
[InlineData(ClockSkew, 0, ExpirationMode.IssuedAt)]
|
||||
[InlineData(0, ClockSkew, ExpirationMode.Nonce)]
|
||||
[InlineData(ClockSkew, 0, DPoPProofExpirationMode.IssuedAt)]
|
||||
[InlineData(0, ClockSkew, DPoPProofExpirationMode.Nonce)]
|
||||
public void use_client_or_server_clock_skew_depending_on_validation_mode(int clientClockSkew, int serverClockSkew,
|
||||
ExpirationMode mode)
|
||||
DPoPProofExpirationMode mode)
|
||||
{
|
||||
Options.ProofTokenIssuedAtClockSkew = TimeSpan.FromSeconds(clientClockSkew);
|
||||
Options.ProofTokenNonceClockSkew = TimeSpan.FromSeconds(serverClockSkew);
|
||||
|
|
@ -182,15 +182,15 @@ public class FreshnessTests : DPoPProofValidatorTestBase
|
|||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(ExpirationMode.IssuedAt)]
|
||||
[InlineData(ExpirationMode.Both)]
|
||||
public void validate_iat_when_option_is_set(ExpirationMode mode)
|
||||
[InlineData(DPoPProofExpirationMode.IssuedAt)]
|
||||
[InlineData(DPoPProofExpirationMode.Both)]
|
||||
public void validate_iat_when_option_is_set(DPoPProofExpirationMode mode)
|
||||
{
|
||||
Options.ProofTokenExpirationMode = mode;
|
||||
Options.ProofTokenLifetime = TimeSpan.FromSeconds(ValidFor);
|
||||
Options.ProofTokenIssuedAtClockSkew = TimeSpan.FromSeconds(ClockSkew);
|
||||
Result.IssuedAt = IssuedAt;
|
||||
if (mode == ExpirationMode.Both)
|
||||
if (mode == DPoPProofExpirationMode.Both)
|
||||
{
|
||||
Options.ProofTokenNonceClockSkew = TimeSpan.FromSeconds(ClockSkew);
|
||||
Result.Nonce = DataProtector.Protect(IssuedAt.ToString());
|
||||
|
|
@ -209,15 +209,15 @@ public class FreshnessTests : DPoPProofValidatorTestBase
|
|||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(ExpirationMode.Nonce)]
|
||||
[InlineData(ExpirationMode.Both)]
|
||||
public void validate_nonce_when_option_is_set(ExpirationMode mode)
|
||||
[InlineData(DPoPProofExpirationMode.Nonce)]
|
||||
[InlineData(DPoPProofExpirationMode.Both)]
|
||||
public void validate_nonce_when_option_is_set(DPoPProofExpirationMode mode)
|
||||
{
|
||||
Options.ProofTokenExpirationMode = mode;
|
||||
Options.ProofTokenLifetime = TimeSpan.FromSeconds(ValidFor);
|
||||
Options.ProofTokenNonceClockSkew = TimeSpan.FromSeconds(ClockSkew);
|
||||
Result.Nonce = DataProtector.Protect(IssuedAt.ToString());
|
||||
if (mode == ExpirationMode.Both)
|
||||
if (mode == DPoPProofExpirationMode.Both)
|
||||
{
|
||||
Result.IssuedAt = IssuedAt;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,8 +29,8 @@ public class ReplayTests : DPoPProofValidatorTestBase
|
|||
{
|
||||
ReplayCache.ExistsFunc = _ => false;
|
||||
|
||||
Options.ProofTokenExpirationMode = (validateIat && validateNonce) ? ExpirationMode.Both
|
||||
: validateIat ? ExpirationMode.IssuedAt : ExpirationMode.Nonce;
|
||||
Options.ProofTokenExpirationMode = (validateIat && validateNonce) ? DPoPProofExpirationMode.Both
|
||||
: validateIat ? DPoPProofExpirationMode.IssuedAt : DPoPProofExpirationMode.Nonce;
|
||||
Options.ProofTokenIssuedAtClockSkew = TimeSpan.FromSeconds(clientClockSkew);
|
||||
Options.ProofTokenNonceClockSkew = TimeSpan.FromSeconds(serverClockSkew);
|
||||
Options.ProofTokenLifetime = TimeSpan.FromSeconds(ValidFor);
|
||||
|
|
|
|||
Loading…
Reference in a new issue