Udap.Client
0.4.0
dotnet add package Udap.Client --version 0.4.0
NuGet\Install-Package Udap.Client -Version 0.4.0
<PackageReference Include="Udap.Client" Version="0.4.0" />
paket add Udap.Client --version 0.4.0
#r "nuget: Udap.Client, 0.4.0"
// Install Udap.Client as a Cake Addin #addin nuget:?package=Udap.Client&version=0.4.0 // Install Udap.Client as a Cake Tool #tool nuget:?package=Udap.Client&version=0.4.0
Udap.Client
📦 Nuget Package: Udap.Client
Udap.Config simple dependency injection example configuration
If you chose to load a trust anchor yourself or non at all then registration can be a simple as the following.
builder.Services.AddScoped<TrustChainValidator>();
builder.Services.AddHttpClient<IUdapClient, UdapClient>();
The Udap.Client returns a UdapDiscoveryDocumentResponse
. For convenience it contains a IsError property. If you need to understand why there is an error then you can investigate the Error
, Exception
, ErrorType
, and HttpErrorReason
depending on the reason for the error. There are also events you can subscribe to to get details about JWT and Certificate chaining errors. The Problem events come from the TrustChainValidator
and are very useful. See example below.
var udapClient = serviceProvider.GetRequiredService<IUdapClient>();
var loggerFactory = serviceProvider.GetRequiredService<ILoggerFactory>();
var logger = loggerFactory.CreateLogger(typeof(Program));
udapClient.Problem += element => logger.LogWarning(element.ChainElementStatus
.Summarize(TrustChainValidator.DefaultProblemFlags));
udapClient.Untrusted += certificate2 => logger.LogWarning("Untrusted: " + certificate2.Subject);
udapClient.TokenError += message => logger.LogWarning("TokenError: " + message);
var response = await udapClient.ValidateResource(options.BaseUrl, trustAnchorStore, community);
if (response.IsError)
{
logger.LogError(response.HttpErrorReason);
}
else
{
logger.LogInformation(JsonSerializer.Serialize(
response,
new JsonSerializerOptions{WriteIndented = true}));
}
Experiment with this example code in the 1_UdapClientMetadata CLI Project
Example command line run: dotnet run --baseUrl https://fhirlabs.net/fhir/r4 --trustAnchor "C:\SureFhirLabs_CA.cer" --community udap://ECDSA/
NOTE The above example trust anchor (download) is used by most communities in the https://fhirlabs.net/fhir/r4 test server.
Udap.Client configuration with a ITrustAnchorStore implementation
Implement the ITrustAnchorStore to load trust anchors from a store. Below is dependency injection example of a file system store implementation. Note the CertStore folder in this project with anchors and intermediates folders. Also take note of the appsettings.json
configuration. Notice each community has an Anchors and Intermediates collection of file references. In accompanying example project all communities issue certificates through a sub-certificate authority, yet the configuration only configured one Intermediate. Why is this? If the published certificate at the resource ./well-known/udap
endpoint contains a AIA extension then the .NET X509Chain.Build
method will follow the URL in the extension. This is true on Windows and Linux. Some Certificate Authorities may not follow this practice and you will have to configure for the intermediate certificate.
Note: An anchor must be chosen for each community. When you receive signed metadata the client will proceed to build a certificate chain from the first x5c header certificate and the anchor as the root certificate.
There is another way for intermediate certificates to be discovered. That is within the x5c header of the signed metadata. While the first certificate in the x5c header must be the signing certificate, the rest of the certificates may be the rest of the chain. But again you must have an anchor deliberately chosen and loaded into the client. The client will no load and trust an anchor from the x5c header.
<details><summary><a>View Metadata</></summary>
"UdapFileCertStoreManifest": {
"Communities": [
{
"Name": "udap://stage.healthtogo.me/",
"Anchors": [
{
"FilePath": "CertStore/anchors/EMRDirectTestCA.crt"
}
]
},
{
"Name": "udap://fhirlabs.net/",
"Intermediates": [
"CertStore/intermediates/SureFhirLabs_Intermediate.cer"
],
"Anchors": [
{
"FilePath": "CertStore/anchors/SureFhirLabs_CA.cer"
}
]
},
{
"Name": "udap://expired.fhirlabs.net/",
"Anchors": [
{
"FilePath": "CertStore/anchors/SureFhirLabs_CA.cer"
}
]
},
{
"Name": "udap://revoked.fhirlabs.net/",
"Anchors": [
{
"FilePath": "CertStore/anchors/SureFhirLabs_CA.cer"
}
]
},
{
"Name": "udap://untrusted.fhirlabs.net/",
"Anchors": [
{
"FilePath": "CertStore/anchors/SureFhirLabs_CA.cer"
}
]
},
{
"Name": "udap://Iss.Miss.Match.To.SubjAltName/",
"Anchors": [
{
"FilePath": "CertStore/anchors/SureFhirLabs_CA.cer"
}
]
},
{
"Name": "udap://Iss.Miss.Match.To.BaseUrl//",
"Anchors": [
{
"FilePath": "CertStore/anchors/SureFhirLabs_CA.cer"
}
]
},
{
"Name": "udap://ECDSA/",
"Anchors": [
{
"FilePath": "CertStore/anchors/SureFhirLabs_CA.cer"
}
]
}
]
}
</details> <br/>
services.Configure<UdapFileCertStoreManifest>(context.Configuration.GetSection("UdapFileCertStoreManifest"));
services.AddSingleton<ITrustAnchorStore, TrustAnchorFileStore>();
services.AddScoped<TrustChainValidator>();
services.AddHttpClient<IUdapClient, UdapClient>();
Experiment with this example code in the 1_UdapClientMetadata CLI Project
Udap.Client advanced configuration
The TrustChainValidator a couple ways to control it's behavior when validating a chain. One is the control the Problem Flags
identified in the .NET X509ChainStatusFlags
settings. The defaults are recommended. Perhaps you are running some unit tests that do not publish a certificate revocation list. Then your code might look something like the following where we mask out OfflineRevocation
and RevocationStatusUnknown
flags.
services.Configure<UdapFileCertStoreManifest>(context.Configuration.GetSection("UdapFileCertStoreManifest"));
var problemFlags = X509ChainStatusFlags.NotTimeValid |
X509ChainStatusFlags.Revoked |
X509ChainStatusFlags.NotSignatureValid |
X509ChainStatusFlags.InvalidBasicConstraints |
X509ChainStatusFlags.CtlNotTimeValid |
X509ChainStatusFlags.UntrustedRoot |
// X509ChainStatusFlags.OfflineRevocation |
X509ChainStatusFlags.CtlNotSignatureValid;
// X509ChainStatusFlags.RevocationStatusUnknown;
services.AddSingleton<ITrustAnchorStore, TrustAnchorFileStore>();
services.AddScoped<TrustChainValidator>(sp => new TrustChainValidator(new X509ChainPolicy(), problemFlags, sp.GetService<ILogger<TrustChainValidator>>()));
services.AddHttpClient<IUdapClient, UdapClient>();
TODO: Cover X509ChainPolicy
Udap.Client Dynamic Client Registration with a ICertificateStore implementation
Example projects
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET | net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 is compatible. |
-
net8.0
- IdentityModel (>= 7.0.0)
- Udap.Common (>= 0.4.0)
- Udap.Model (>= 0.4.0)
-
net9.0
- IdentityModel (>= 7.0.0)
- Udap.Common (>= 0.4.0)
- Udap.Model (>= 0.4.0)
NuGet packages (1)
Showing the top 1 NuGet packages that depend on Udap.Client:
Package | Downloads |
---|---|
Udap.Server
Package is a part of the UDAP reference implementation for .NET. |
GitHub repositories
This package is not used by any popular GitHub repositories.
Version | Downloads | Last updated |
---|---|---|
0.4.0 | 132 | 12/14/2024 |
0.3.96 | 275 | 11/6/2024 |
0.3.95 | 204 | 11/2/2024 |
0.3.94 | 128 | 10/31/2024 |
0.3.93 | 273 | 10/13/2024 |
0.3.92 | 109 | 10/13/2024 |
0.3.91 | 104 | 10/10/2024 |
0.3.89 | 139 | 10/10/2024 |
0.3.87 | 141 | 10/5/2024 |
0.3.86 | 157 | 10/5/2024 |
0.3.85 | 121 | 10/4/2024 |
0.3.84 | 113 | 10/3/2024 |
0.3.83 | 108 | 10/3/2024 |
0.3.82 | 166 | 9/20/2024 |
0.3.81 | 213 | 9/19/2024 |
0.3.80 | 159 | 9/19/2024 |
0.3.79 | 152 | 9/19/2024 |
0.3.78 | 145 | 9/19/2024 |
0.3.77 | 184 | 9/17/2024 |
0.3.76 | 117 | 9/17/2024 |
0.3.75 | 124 | 9/12/2024 |
0.3.74 | 118 | 9/12/2024 |
0.3.73 | 140 | 9/10/2024 |
0.3.72 | 289 | 9/7/2024 |
0.3.71 | 128 | 9/5/2024 |
0.3.70 | 124 | 9/5/2024 |
0.3.69 | 128 | 9/5/2024 |
0.3.68 | 146 | 9/4/2024 |
0.3.67 | 115 | 9/4/2024 |
0.3.66 | 108 | 9/4/2024 |
0.3.65 | 112 | 9/4/2024 |
0.3.64 | 114 | 9/2/2024 |
0.3.63 | 121 | 8/31/2024 |
0.3.62 | 135 | 8/29/2024 |
0.3.61 | 134 | 8/28/2024 |
0.3.60 | 195 | 8/2/2024 |
0.3.59 | 146 | 8/1/2024 |
0.3.58 | 106 | 8/1/2024 |
0.3.57 | 213 | 7/19/2024 |
0.3.56 | 121 | 7/19/2024 |
0.3.54 | 129 | 7/18/2024 |
0.3.53 | 136 | 7/15/2024 |
0.3.52 | 127 | 7/15/2024 |
0.3.51 | 128 | 7/12/2024 |
0.3.50 | 202 | 7/1/2024 |
0.3.49 | 138 | 7/1/2024 |
0.3.48 | 346 | 5/22/2024 |
0.3.47 | 239 | 5/15/2024 |
0.3.46 | 113 | 5/14/2024 |
0.3.45 | 176 | 5/12/2024 |
0.3.44 | 117 | 5/12/2024 |
0.3.43 | 100 | 5/12/2024 |
0.3.42 | 112 | 5/12/2024 |
0.3.41 | 189 | 5/6/2024 |
0.3.40 | 171 | 5/4/2024 |
0.3.39 | 133 | 5/1/2024 |
0.3.38 | 141 | 4/30/2024 |
0.3.37 | 214 | 4/11/2024 |
0.3.36 | 130 | 4/10/2024 |
0.3.35 | 257 | 4/9/2024 |
0.3.34 | 158 | 4/8/2024 |
0.3.33 | 154 | 4/7/2024 |
0.3.32 | 148 | 4/5/2024 |
0.3.31 | 145 | 4/4/2024 |
0.3.30 | 123 | 4/4/2024 |
0.3.29 | 179 | 4/3/2024 |
0.3.28 | 114 | 4/3/2024 |
0.3.27 | 131 | 4/2/2024 |
0.3.26 | 107 | 4/2/2024 |
0.3.25 | 158 | 4/2/2024 |
0.3.24 | 193 | 3/24/2024 |
0.3.22 | 242 | 3/6/2024 |
0.3.21 | 137 | 3/6/2024 |
0.3.20 | 141 | 3/5/2024 |
0.3.19 | 159 | 3/2/2024 |
0.3.18 | 148 | 3/2/2024 |
0.3.13 | 162 | 3/1/2024 |
0.3.12 | 131 | 2/24/2024 |
0.3.10 | 134 | 2/14/2024 |
0.3.8 | 214 | 2/11/2024 |
0.3.7 | 141 | 2/11/2024 |
0.3.6 | 139 | 2/10/2024 |
0.3.5 | 123 | 2/10/2024 |
0.3.4 | 130 | 2/10/2024 |
0.3.2 | 139 | 2/10/2024 |
0.3.0 | 289 | 1/31/2024 |
0.2.21 | 551 | 10/24/2023 |
0.2.20 | 147 | 10/23/2023 |
0.2.19 | 188 | 10/20/2023 |
0.2.18 | 198 | 10/11/2023 |
0.2.17 | 195 | 10/5/2023 |
0.2.16 | 264 | 9/21/2023 |
0.2.15 | 150 | 9/21/2023 |
0.2.14 | 211 | 9/20/2023 |
0.2.13 | 141 | 9/20/2023 |
0.2.12 | 162 | 9/20/2023 |
0.2.11 | 158 | 9/19/2023 |
0.2.10 | 229 | 9/13/2023 |
0.2.9 | 312 | 8/26/2023 |
0.2.8 | 185 | 8/18/2023 |
0.2.7 | 184 | 8/15/2023 |
0.2.6 | 173 | 8/12/2023 |
0.2.5 | 212 | 8/11/2023 |
0.2.4 | 190 | 8/10/2023 |
0.2.3 | 224 | 8/2/2023 |
0.2.2 | 191 | 8/1/2023 |
0.2.1 | 201 | 7/25/2023 |
0.2.0 | 248 | 7/16/2023 |
0.1.24 | 346 | 5/26/2023 |
0.1.23 | 167 | 5/22/2023 |
0.1.22 | 135 | 5/22/2023 |
0.1.21 | 163 | 5/21/2023 |
0.1.20 | 169 | 5/20/2023 |
0.1.17 | 171 | 5/9/2023 |
0.1.16 | 145 | 5/6/2023 |
0.1.15 | 162 | 5/4/2023 |
0.1.14 | 183 | 5/2/2023 |
0.1.12 | 153 | 5/1/2023 |
0.1.11 | 166 | 4/29/2023 |
0.1.9 | 162 | 4/29/2023 |
0.1.8 | 162 | 4/29/2023 |
0.1.7 | 192 | 4/28/2023 |
0.1.6 | 176 | 4/27/2023 |
0.1.5 | 185 | 4/27/2023 |
0.1.4 | 189 | 4/25/2023 |
0.1.3 | 206 | 4/23/2023 |
0.1.2 | 216 | 4/22/2023 |
0.1.1 | 237 | 4/22/2023 |
0.0.4-preview040 | 152 | 4/21/2023 |
0.0.4-preview039 | 127 | 4/13/2023 |
0.0.4-preview038 | 154 | 4/11/2023 |
0.0.4-preview037 | 140 | 4/7/2023 |
0.0.4-preview036 | 150 | 3/31/2023 |
0.0.4-preview035 | 131 | 3/31/2023 |
0.0.4-preview034 | 145 | 3/31/2023 |
0.0.4-preview033 | 153 | 3/30/2023 |
0.0.4-preview032 | 156 | 3/19/2023 |
0.0.4-preview029 | 149 | 3/18/2023 |
0.0.4-preview028 | 148 | 3/15/2023 |
0.0.4-preview027 | 139 | 3/13/2023 |
0.0.4-preview026 | 143 | 3/12/2023 |
0.0.4-preview025 | 149 | 3/10/2023 |
0.0.4-preview024 | 147 | 3/9/2023 |
0.0.4-preview022 | 171 | 3/9/2023 |
0.0.4-preview021 | 140 | 3/7/2023 |
0.0.4-preview020 | 168 | 3/7/2023 |
0.0.4-preview019 | 128 | 3/4/2023 |
0.0.4-preview018 | 167 | 3/4/2023 |
0.0.4-preview017 | 154 | 3/4/2023 |
0.0.4-preview016 | 133 | 3/1/2023 |
0.0.4-preview015 | 152 | 2/28/2023 |
0.0.4-preview014 | 158 | 2/23/2023 |
0.0.4-preview013 | 170 | 2/23/2023 |
0.0.4-preview012 | 180 | 2/21/2023 |
0.0.4-preview011 | 146 | 2/20/2023 |
0.0.4-preview010 | 142 | 2/20/2023 |
0.0.4-preview009 | 135 | 2/19/2023 |
0.0.4-preview008 | 174 | 2/14/2023 |
0.0.4-preview007 | 143 | 2/10/2023 |
0.0.4-preview006 | 153 | 2/8/2023 |
0.0.4-preview005 | 161 | 2/8/2023 |
0.0.4-preview004 | 128 | 2/7/2023 |
0.0.4-preview003 | 131 | 2/7/2023 |
0.0.4-preview002 | 146 | 2/7/2023 |
0.0.4-preview001 | 146 | 2/3/2023 |
0.0.4-preview000 | 145 | 2/2/2023 |
0.0.3-preview032 | 151 | 2/1/2023 |
0.0.3-preview031 | 144 | 2/1/2023 |
0.0.3-preview030 | 166 | 1/30/2023 |
0.0.3-preview029 | 157 | 1/21/2023 |
0.0.3-preview028 | 150 | 1/19/2023 |
0.0.3-preview027 | 167 | 1/18/2023 |
0.0.3-preview026 | 181 | 1/16/2023 |
0.0.3-preview025 | 134 | 1/15/2023 |
0.0.3-preview024 | 179 | 1/15/2023 |
0.0.3-preview020 | 159 | 1/15/2023 |
0.0.3-preview019 | 145 | 1/11/2023 |
0.0.3-preview018 | 169 | 1/11/2023 |
0.0.3-preview017 | 175 | 1/7/2023 |
0.0.3-preview016 | 156 | 1/7/2023 |
0.0.3-preview015 | 162 | 1/6/2023 |
0.0.3-preview014 | 154 | 1/6/2023 |
0.0.3-preview013 | 162 | 1/6/2023 |
0.0.3-preview012 | 169 | 1/6/2023 |
0.0.3-preview011 | 160 | 1/6/2023 |
0.0.3-preview010 | 182 | 1/3/2023 |
0.0.3-preview009 | 165 | 1/3/2023 |
0.0.3-preview008 | 171 | 1/2/2023 |
0.0.3-preview007 | 168 | 1/2/2023 |
0.0.3-preview006 | 154 | 1/2/2023 |
0.0.3-preview005 | 163 | 1/2/2023 |
0.0.3-preview004 | 170 | 1/1/2023 |
0.0.3-preview003 | 162 | 12/31/2022 |
0.0.3-preview002 | 210 | 12/28/2022 |
0.0.3-preview001 | 214 | 12/21/2022 |
0.0.3-preview000 | 163 | 11/29/2022 |
0.0.2-preview003 | 143 | 11/4/2022 |
0.0.2-preview002 | 157 | 11/4/2022 |
0.0.2-preview000 | 212 | 11/4/2022 |
0.0.1-preview002 | 188 | 11/4/2022 |
0.0.1-preview001 | 174 | 11/4/2022 |