-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
c2de39d
commit 739380a
Showing
9 changed files
with
217 additions
and
66 deletions.
There are no files selected for viewing
66 changes: 66 additions & 0 deletions
66
src/Digdir.Library.Dialogporten.WebApiClient/Common/ClaimsPrincipalExtensions.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
using System.Diagnostics.CodeAnalysis; | ||
using System.Security.Claims; | ||
|
||
namespace Altinn.ApiClients.Dialogporten.Common; | ||
|
||
internal static class ClaimsPrincipalExtensions | ||
{ | ||
public static bool VerifyDialogId(this ClaimsPrincipal claimsPrincipal, Guid dialogId) | ||
{ | ||
const string dialogIdClaimName = "i"; | ||
return claimsPrincipal.TryGetClaimValue(dialogIdClaimName, out var dialogIdString) | ||
&& Guid.TryParse(dialogIdString, out var dialogIdClaim) | ||
&& dialogId == dialogIdClaim; | ||
} | ||
|
||
public static bool VerifyActions(this ClaimsPrincipal claimsPrincipal, params string[] requiredActions) | ||
{ | ||
const string actionsClaimName = "a"; | ||
const string actionSeparator = ";"; | ||
if (requiredActions.Length == 0) | ||
{ | ||
return true; | ||
} | ||
|
||
if (!claimsPrincipal.TryGetClaimValue(actionsClaimName, out var actions)) | ||
{ | ||
return false; | ||
} | ||
|
||
var requiredActionsLength = requiredActions | ||
.Distinct(StringComparer.OrdinalIgnoreCase) | ||
.Count(); | ||
var intersectionLength = actions | ||
.Split(actionSeparator) | ||
.Intersect(requiredActions, StringComparer.OrdinalIgnoreCase) | ||
.Count(); | ||
return intersectionLength == requiredActionsLength; | ||
} | ||
|
||
public static bool VerifyExpirationTime(this ClaimsPrincipal claimsPrincipal, IClock clock, TimeSpan clockSkew) | ||
{ | ||
const string expirationTimeClaimName = "exp"; | ||
var exp = claimsPrincipal.TryGetClaimValue(expirationTimeClaimName, out var exps) | ||
&& long.TryParse(exps, out var expl) | ||
? DateTimeOffset.FromUnixTimeSeconds(expl).Add(clockSkew) | ||
: DateTimeOffset.MinValue; | ||
return clock.UtcNow <= exp; | ||
} | ||
|
||
public static bool VerifyNotValidBefore(this ClaimsPrincipal claimsPrincipal, IClock clock, TimeSpan clockSkew) | ||
{ | ||
const string notValidBeforeClaimName = "nbf"; | ||
var nbf = claimsPrincipal.TryGetClaimValue(notValidBeforeClaimName, out var nbfs) | ||
&& long.TryParse(nbfs, out var nbfl) | ||
? DateTimeOffset.FromUnixTimeSeconds(nbfl).Add(-clockSkew) | ||
: DateTimeOffset.MaxValue; | ||
return nbf <= clock.UtcNow; | ||
} | ||
|
||
public static bool TryGetClaimValue(this ClaimsPrincipal claimsPrincipal, string claimType, | ||
[NotNullWhen(true)] out string? value) | ||
{ | ||
value = claimsPrincipal.FindFirst(claimType)?.Value; | ||
return value is not null; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,3 @@ | ||
using BenchmarkDotNet.Running; | ||
using Digdir.Tool.Dialogporten.Benchmarks; | ||
BenchmarkRunner.Run<TokenGenerationBenchmark>(); | ||
BenchmarkRunner.Run<TokenValidatorBenchmarks>(); |
41 changes: 41 additions & 0 deletions
41
src/Digdir.Tool.Dialogporten.Benchmarks/TokenValidatorBenchmarks.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
using System.Buffers.Text; | ||
using System.Diagnostics.CodeAnalysis; | ||
using System.Globalization; | ||
using Altinn.ApiClients.Dialogporten; | ||
using Altinn.ApiClients.Dialogporten.Common; | ||
using Altinn.ApiClients.Dialogporten.Services; | ||
using BenchmarkDotNet.Attributes; | ||
using NSec.Cryptography; | ||
|
||
namespace Digdir.Tool.Dialogporten.Benchmarks; | ||
|
||
[MemoryDiagnoser] | ||
[SuppressMessage("Performance", "CA1822:Mark members as static")] | ||
public class TokenValidatorBenchmarks | ||
{ | ||
private const string ValidTimeStampString = "2025-02-14T09:00:00Z"; | ||
private const string DialogToken = | ||
"eyJhbGciOiJFZERTQSIsInR5cCI6IkpXVCIsImtpZCI6ImRwLXN0YWdpbmctMjQwMzIyLW81eW1uIn0.eyJqdGkiOiIzOGNmZGNiOS0zODhiLTQ3YjgtYTFiZi05ZjE1YjI4MTk4OTQiLCJjIjoidXJuOmFsdGlubjpwZXJzb246aWRlbnRpZmllci1ubzoxNDg4NjQ5ODIyNiIsImwiOjMsInAiOiJ1cm46YWx0aW5uOnBlcnNvbjppZGVudGlmaWVyLW5vOjE0ODg2NDk4MjI2IiwicyI6InVybjphbHRpbm46cmVzb3VyY2U6ZGFnbC1jb3JyZXNwb25kZW5jZSIsImkiOiIwMTk0ZmU4Mi05MjgwLTc3YTUtYTdjZC01ZmYwZTZhNmZhMDciLCJhIjoicmVhZCIsImlzcyI6Imh0dHBzOi8vcGxhdGZvcm0udHQwMi5hbHRpbm4ubm8vZGlhbG9ncG9ydGVuL2FwaS92MSIsImlhdCI6MTczOTUyMzM2NywibmJmIjoxNzM5NTIzMzY3LCJleHAiOjE3Mzk1MjM5Njd9.O_f-RJhRPT7B76S7aOGw6jfxKDki3uJQLLC8nVlcNVJWFIOQUsy6gU4bG1ZdqoMBZPvb2K2X4I5fGpHW9dQMAA"; | ||
private static readonly PublicKeyPair[] ValidPublicKeyPairs = | ||
[ | ||
new("dp-staging-240322-o5ymn", ToPublicKey("zs9hR9oqgf53th2lTdrBq3C1TZ9UlR-HVJOiUpWV63o")), | ||
new("dp-staging-240322-rju3g", ToPublicKey("23Sijekv5ATW4sSEiRPzL_rXH-zRV8MK8jcs5ExCmSU")) | ||
]; | ||
private static readonly DialogTokenValidator _sut = new( | ||
new DefaultEdDsaSecurityKeysCache(ValidPublicKeyPairs), | ||
new BenchmarkClock(ValidTimeStampString)); | ||
|
||
|
||
[Benchmark] | ||
public IValidationResult ValidateDialogToken() => _sut.Validate(DialogToken); | ||
|
||
private static PublicKey ToPublicKey(string key) | ||
=> PublicKey.Import(SignatureAlgorithm.Ed25519, Base64Url.DecodeFromChars(key), KeyBlobFormat.RawPublicKey); | ||
|
||
private sealed class BenchmarkClock(DateTimeOffset utcNow) : IClock | ||
{ | ||
public DateTimeOffset UtcNow { get; } = utcNow; | ||
public BenchmarkClock(string input) : this(DateTimeOffset.Parse(input, CultureInfo.InvariantCulture)) { } | ||
} | ||
} | ||
|
Oops, something went wrong.