diff --git a/scripts/debug-upsert-small-bag.ps1 b/scripts/debug-upsert-small-bag.ps1 index 6311059..1892575 100644 --- a/scripts/debug-upsert-small-bag.ps1 +++ b/scripts/debug-upsert-small-bag.ps1 @@ -1,8 +1,9 @@ -# 单独调试 POST /OrderV2/UpsertSmallBag(与 SmallBagTrackOrderClient 一致:鉴权走 Header) +# 单独调试 POST /OrderV2/UpsertSmallBag(与 SmallBagTrackOrderClient 一致:鉴权走 Header + Bearer) param( [string]$BaseUrl = "https://api.nanafa.com/track", [string]$AppKey = "W2606001", [string]$AppSecret = "ziK8UzlQ39m3kdL346XEBg8nljY8os52", + [string]$Authorization = "", [string]$OrderNo = "", [string]$Client = "TEST001" ) @@ -45,13 +46,25 @@ $url = ($BaseUrl.TrimEnd('/')) + "/OrderV2/UpsertSmallBag" Write-Host "========== UpsertSmallBag Debug ==========" -ForegroundColor Cyan Write-Host "URL: $url" Write-Host "Headers: appKey=$AppKey, timestamp=$timestamp, sign=$sign" +if (-not [string]::IsNullOrWhiteSpace($Authorization)) { + Write-Host "Headers: Authorization=" +} Write-Host "Body:" Write-Host ($body | ConvertFrom-Json | ConvertTo-Json -Depth 5) Write-Host "========================================" -ForegroundColor Cyan try { + $headers = @{ + appKey = $AppKey + timestamp = "$timestamp" + sign = $sign + } + if (-not [string]::IsNullOrWhiteSpace($Authorization)) { + $headers.Authorization = $Authorization + } + $response = Invoke-WebRequest -Uri $url -Method POST ` - -Headers @{ appKey = $AppKey; timestamp = "$timestamp"; sign = $sign } ` + -Headers $headers ` -ContentType "application/json; charset=utf-8" ` -Body ([System.Text.Encoding]::UTF8.GetBytes($body)) ` -UseBasicParsing @@ -69,6 +82,6 @@ catch { Write-Host $_.Exception.Message -ForegroundColor Red } Write-Host "" - Write-Host "Tip: track SignatureValidationFilter reads appKey/timestamp/sign from HTTP Headers." -ForegroundColor Yellow + Write-Host "Tip: track gateway requires Authorization Bearer from logged-in user, plus appKey/timestamp/sign headers." -ForegroundColor Yellow exit 1 } diff --git a/src/Oms.Application/Integrations/SmallBagTrack/SmallBagTrackOrderClient.cs b/src/Oms.Application/Integrations/SmallBagTrack/SmallBagTrackOrderClient.cs index d2e1186..0522cf0 100644 --- a/src/Oms.Application/Integrations/SmallBagTrack/SmallBagTrackOrderClient.cs +++ b/src/Oms.Application/Integrations/SmallBagTrack/SmallBagTrackOrderClient.cs @@ -1,5 +1,7 @@ +using System.Net.Http.Headers; using System.Net.Http.Json; using System.Text.Json; +using Microsoft.AspNetCore.Http; using Microsoft.Extensions.Logging; namespace Oms.Application.Integrations.SmallBagTrack; @@ -7,6 +9,7 @@ namespace Oms.Application.Integrations.SmallBagTrack; internal sealed class SmallBagTrackOrderClient( IHttpClientFactory httpClientFactory, ISmallBagTrackConfigProvider configProvider, + IHttpContextAccessor httpContextAccessor, ILogger logger) : ISmallBagTrackOrderClient { private static readonly JsonSerializerOptions JsonOptions = new() @@ -68,10 +71,18 @@ internal sealed class SmallBagTrackOrderClient( var sign = SmallBagTrackSignHelper.GenerateSign(appKey, timestamp, settings.AppSecret.Trim()); var body = SmallBagTrackUpsertApiRequest.FromBusinessRequest(request); var url = SmallBagTrackUpsertApiRequest.BuildEndpointUrl(settings.BaseUrl); + var authorization = ResolveAuthorization(request); var requestJson = JsonSerializer.Serialize( new { - auth = new { appKey, timestamp, sign, transport = "header" }, + auth = new + { + appKey, + timestamp, + sign, + transport = "header", + authorizationForwarded = !string.IsNullOrWhiteSpace(authorization) + }, body }, JsonOptions); @@ -80,6 +91,7 @@ internal sealed class SmallBagTrackOrderClient( httpRequest.Headers.TryAddWithoutValidation("appKey", appKey); httpRequest.Headers.TryAddWithoutValidation("timestamp", timestamp.ToString()); httpRequest.Headers.TryAddWithoutValidation("sign", sign); + ApplyAuthorization(httpRequest, authorization); httpRequest.Content = JsonContent.Create(body, options: JsonOptions); var client = httpClientFactory.CreateClient(HttpClientName); @@ -98,6 +110,26 @@ internal sealed class SmallBagTrackOrderClient( }; } + private string? ResolveAuthorization(SmallBagTrackUpsertRequest request) + { + if (!string.IsNullOrWhiteSpace(request.Authorization)) + { + return request.Authorization.Trim(); + } + + return httpContextAccessor.HttpContext?.Request.Headers.Authorization.ToString(); + } + + private static void ApplyAuthorization(HttpRequestMessage httpRequest, string? authorization) + { + if (string.IsNullOrWhiteSpace(authorization)) + { + return; + } + + httpRequest.Headers.Authorization = AuthenticationHeaderValue.Parse(authorization); + } + private static SmallBagTrackUpsertResult Skipped(string reason) => new() { diff --git a/src/Oms.Application/Integrations/SmallBagTrack/SmallBagTrackUpsertRequest.cs b/src/Oms.Application/Integrations/SmallBagTrack/SmallBagTrackUpsertRequest.cs index 71d8e85..79c71fa 100644 --- a/src/Oms.Application/Integrations/SmallBagTrack/SmallBagTrackUpsertRequest.cs +++ b/src/Oms.Application/Integrations/SmallBagTrack/SmallBagTrackUpsertRequest.cs @@ -20,6 +20,11 @@ public class SmallBagTrackUpsertRequest public string ApiCode { get; set; } = string.Empty; public SmallBagTrackConsigneeRequest Consignee { get; set; } = new(); + + /// + /// 转发到轨迹网关的 Authorization(异步入队前从当前 HTTP 请求捕获)。 + /// + public string? Authorization { get; set; } } public class SmallBagTrackConsigneeRequest diff --git a/src/Oms.Application/Services/Orders/OrderService.ParcelBilling.cs b/src/Oms.Application/Services/Orders/OrderService.ParcelBilling.cs index e862146..928b291 100644 --- a/src/Oms.Application/Services/Orders/OrderService.ParcelBilling.cs +++ b/src/Oms.Application/Services/Orders/OrderService.ParcelBilling.cs @@ -1,4 +1,5 @@ using Fake.Application; +using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using Oms.Application.Dtos.Channels; using Oms.Application.Dtos.Orders; @@ -1444,6 +1445,18 @@ public partial class OrderService OrderParcelReceiverInput? receiver) { var request = await BuildSmallBagTrackUpsertRequestAsync(order, receiver); + var authorization = LazyServiceProvider + .GetRequiredService() + .HttpContext? + .Request + .Headers + .Authorization + .ToString(); + if (!string.IsNullOrWhiteSpace(authorization)) + { + request.Authorization = authorization; + } + SmallBagTrackOrderNotifier.Enqueue(request); }