Simplify making dpop optional

This commit is contained in:
Joe DeCock 2025-12-08 13:25:33 -06:00
parent 0a726cace8
commit 742aa615d9
4 changed files with 12 additions and 29 deletions

View file

@ -24,7 +24,7 @@ internal class DPoPJwtBearerEvents
private readonly ILogger<DPoPJwtBearerEvents> _logger;
/// <summary>
/// Constructs a new instance of <see cref="DPoPJwtBearerEvents"/>.
/// Constructs a new instance of <see cref="DPoPJwtBearerEvents"/>.
/// </summary>
public DPoPJwtBearerEvents(IOptionsMonitor<DPoPOptions> optionsMonitor, IDPoPProofValidator validator, ILogger<DPoPJwtBearerEvents> logger)
{
@ -47,10 +47,10 @@ internal class DPoPJwtBearerEvents
{
context.Token = token;
}
else if (dpopOptions.TokenMode == DPoPMode.DPoPOnly)
else if (!dpopOptions.AllowBearerTokens)
{
// this rejects the attempt for this handler,
// since we don't want to attempt Bearer given the Mode
// this rejects the attempt for this handler.
// we don't want to attempt Bearer when it is disabled by configuration.
context.NoResult();
}
@ -114,10 +114,10 @@ internal class DPoPJwtBearerEvents
}
}
}
else if (dPoPOptions.TokenMode == DPoPMode.DPoPAndBearer)
else if (dPoPOptions.AllowBearerTokens)
{
// if the scheme used was not DPoP, then it was Bearer
// and if an access token was presented with a cnf, then the
// and if an access token was presented with a cnf, then the
// client should have sent it as DPoP, so we fail the request
if (context.Principal?.HasClaim(x => x.Type == JwtClaimTypes.Confirmation) ?? false)
{
@ -172,7 +172,7 @@ internal class DPoPJwtBearerEvents
_logger.LogDebug("Challenge invoked in a JWT bearer authentication scheme using DPoP");
var dPoPOptions = _optionsMonitor.Get(context.Scheme.Name);
if (dPoPOptions.TokenMode == DPoPMode.DPoPOnly)
if (!dPoPOptions.AllowBearerTokens)
{
// if we are using DPoP only, then we don't need/want the default
// JwtBearerHandler to add its WWW-Authenticate response header,

View file

@ -1,19 +0,0 @@
// Copyright (c) Duende Software. All rights reserved.
// See LICENSE in the project root for license information.
namespace Duende.AspNetCore.Authentication.JwtBearer.DPoP;
/// <summary>
/// Determines if DPoP and Bearer tokens are allowed, or only DPoP tokens.
/// </summary>
public enum DPoPMode
{
/// <summary>
/// Only DPoP tokens will be accepted
/// </summary>
DPoPOnly,
/// <summary>
/// Both DPoP and Bearer tokens will be accepted
/// </summary>
DPoPAndBearer
}

View file

@ -12,9 +12,11 @@ namespace Duende.AspNetCore.Authentication.JwtBearer.DPoP;
public sealed class DPoPOptions
{
/// <summary>
/// Controls if both DPoP and Bearer tokens are allowed, or only DPoP. Defaults to <see cref="DPoPMode.DPoPOnly"/>.
/// Controls if bearer tokens are accepted in addition to DPoP tokens. If
/// set, both Bearer and DPoP tokens can be used for authentication. If not,
/// DPoP tokens must be used. Defaults to false.
/// </summary>
public DPoPMode TokenMode { get; set; } = DPoPMode.DPoPOnly;
public bool AllowBearerTokens { get; set; }
/// <summary>
/// The amount of time that a proof token is valid for. Defaults to 1 second.

View file

@ -232,7 +232,7 @@ public class DPoPIntegrationTests(ITestOutputHelper testOutputHelper)
services.ConfigureDPoPTokensForScheme(ApiHost.AuthenticationScheme,
opt =>
{
opt.TokenMode = DPoPMode.DPoPOnly;
opt.AllowBearerTokens = false;
configureDPoP?.Invoke(opt);
});