From 653f1d484b619cfa70eae17419d3140182b02654 Mon Sep 17 00:00:00 2001 From: vvdb-architecture Date: Mon, 29 Apr 2024 11:46:15 +0200 Subject: [PATCH] Make sure a traceparent is always present even if we are not authenticated. Don't assume there is alwasys a non-null activity. Use the header dictionary for searching header values. --- .../AddContextToPrincipalMiddleware.cs | 29 +++++++++++-------- 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/src/Arc4u.Standard.OAuth2.AspNetCore/Middleware/AddContextToPrincipalMiddleware.cs b/src/Arc4u.Standard.OAuth2.AspNetCore/Middleware/AddContextToPrincipalMiddleware.cs index 5a325f00..990a625a 100644 --- a/src/Arc4u.Standard.OAuth2.AspNetCore/Middleware/AddContextToPrincipalMiddleware.cs +++ b/src/Arc4u.Standard.OAuth2.AspNetCore/Middleware/AddContextToPrincipalMiddleware.cs @@ -8,7 +8,6 @@ using Microsoft.AspNetCore.Http; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; -using Microsoft.Extensions.Primitives; namespace Arc4u.OAuth2.Middleware; public class AddContextToPrincipalMiddleware @@ -29,26 +28,32 @@ public async Task Invoke(HttpContext context) { ArgumentNullException.ThrowIfNull(context); - if (context.User is not null && context.User is AppPrincipal principal && principal.Identity is not null && principal.Identity.IsAuthenticated) - { - using var activity = _activitySource?.StartActivity("Add context to Arc4u Principal", ActivityKind.Producer); + // Note that the action of setting a traceparent and adding context to the principal are conceptually separate, but they are viewed as one "activity" for the purposes of logging. - // Ensure we have a traceparent. + using var activity = _activitySource?.StartActivity("Add context to Arc4u Principal", ActivityKind.Producer); + + // We may have a null current activity if we are not in the context of an activity. + // we may not be in the context of an activity if either (1) there is no _activitySource or (2) the activity has no active listeners + if (Activity.Current is not null) + { + // Ensure we have a traceparent, whether we are authenticated or not, since it's always useful to have a traceparent. if (!context.Request.Headers.ContainsKey("traceparent")) { - // Activity.Current is not null just because we are in the context of an activity. - context.Request.Headers.Add("traceparent", Activity.Current!.Id); + // Activity.Current is not null because we are in the context of an activity. + context.Request.Headers.Add("traceparent", Activity.Current.Id); } - activity?.SetTag(LoggingConstants.ActivityId, Activity.Current!.Id); + activity?.SetTag(LoggingConstants.ActivityId, Activity.Current.Id); + } - // Check for a culture. - var cultureHeader = context.Request?.Headers?.FirstOrDefault(h => h.Key.Equals("culture", StringComparison.InvariantCultureIgnoreCase)); - if (cultureHeader.HasValue && StringValues.Empty != cultureHeader.Value.Value && cultureHeader.Value.Value.Any()) + if (context.User is not null && context.User is AppPrincipal principal && principal.Identity is not null && principal.Identity.IsAuthenticated) + { + // Check for a culture. The header dictionary takes care of the proper matching of the header name. + if ((context.Request?.Headers?.TryGetValue("culture", out var cultureHeader) ?? false) && cultureHeader.Any()) { try { - principal.Profile.CurrentCulture = new CultureInfo(cultureHeader.Value.Value[0]); + principal.Profile.CurrentCulture = new CultureInfo(cultureHeader[0]); } catch (Exception ex) {