Normalize backend API token
This commit is contained in:
@@ -163,9 +163,12 @@ Bei HTTP-Fehlern wie `401 Unauthorized` protokolliert der Agent:
|
||||
- ob ein Authorization-Header gesetzt wurde
|
||||
- Authorization-Scheme, z. B. `Bearer`
|
||||
- Token-Länge, aber niemals den Token selbst
|
||||
- kurzer SHA-256-Fingerprint des Tokens zum Abgleich mit dem Backend
|
||||
- `WWW-Authenticate`-Header des Backends
|
||||
- gekürzten Response-Body des Backends
|
||||
|
||||
Beim Speichern wird der API-Token normalisiert. Falls versehentlich `Bearer ...` oder `Authorization: Bearer ...` eingefügt wurde, speichert der Agent nur den eigentlichen Tokenwert.
|
||||
|
||||
## Nicht mehr im Agent
|
||||
|
||||
- keine Layout-JSON-Verwaltung
|
||||
|
||||
@@ -168,7 +168,9 @@ internal sealed class SettingsForm : Form
|
||||
var settings = _settingsStore.Load();
|
||||
settings.Backend.BaseUrl = _backendBaseUrl.Text.Trim();
|
||||
settings.Backend.AgentId = _agentId.Text.Trim();
|
||||
settings.Backend.EncryptedApiToken = _settingsStore.EncryptPassword(_apiToken.Text);
|
||||
var normalizedToken = SettingsStore.NormalizeBackendApiToken(_apiToken.Text);
|
||||
settings.Backend.EncryptedApiToken = _settingsStore.EncryptPassword(normalizedToken);
|
||||
_apiToken.Text = normalizedToken;
|
||||
settings.Backend.NextJobPath = _nextJobPath.Text.Trim();
|
||||
settings.Backend.ImagePath = _imagePath.Text.Trim();
|
||||
settings.Backend.ReportSuccessPath = _reportSuccessPath.Text.Trim();
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
using System.Drawing;
|
||||
using System.Net.Http.Headers;
|
||||
using System.Net.Http.Json;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
using System.Text.Json;
|
||||
using LabelPrintAgent.Configuration;
|
||||
using Serilog;
|
||||
@@ -117,7 +119,7 @@ public sealed class BackendClient
|
||||
private HttpRequestMessage CreateRequest(HttpMethod method, string url, AppSettings settings)
|
||||
{
|
||||
var request = new HttpRequestMessage(method, url);
|
||||
var token = _settingsStore.DecryptBackendApiToken(settings);
|
||||
var token = SettingsStore.NormalizeBackendApiToken(_settingsStore.DecryptBackendApiToken(settings));
|
||||
if (!string.IsNullOrWhiteSpace(token))
|
||||
{
|
||||
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", token);
|
||||
@@ -154,7 +156,7 @@ public sealed class BackendClient
|
||||
Log.Warning(
|
||||
"Backend request failed: {Method} {Url} -> {StatusCode} {ReasonPhrase}. " +
|
||||
"AuthorizationHeaderPresent={AuthorizationHeaderPresent}, AuthorizationScheme={AuthorizationScheme}, " +
|
||||
"TokenLength={TokenLength}, WwwAuthenticate={WwwAuthenticate}, ResponseBody={ResponseBody}",
|
||||
"TokenLength={TokenLength}, TokenSha256Prefix={TokenSha256Prefix}, WwwAuthenticate={WwwAuthenticate}, ResponseBody={ResponseBody}",
|
||||
request.Method.Method,
|
||||
request.RequestUri,
|
||||
(int)response.StatusCode,
|
||||
@@ -162,6 +164,7 @@ public sealed class BackendClient
|
||||
authorization is not null,
|
||||
authorization?.Scheme ?? string.Empty,
|
||||
authorization?.Parameter?.Length ?? 0,
|
||||
GetTokenSha256Prefix(authorization?.Parameter),
|
||||
wwwAuthenticate,
|
||||
Truncate(responseBody, 2000));
|
||||
|
||||
@@ -197,6 +200,17 @@ public sealed class BackendClient
|
||||
return value[..maxLength] + "...";
|
||||
}
|
||||
|
||||
private static string GetTokenSha256Prefix(string? token)
|
||||
{
|
||||
if (string.IsNullOrEmpty(token))
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
var hash = SHA256.HashData(Encoding.UTF8.GetBytes(token));
|
||||
return Convert.ToHexString(hash)[..12];
|
||||
}
|
||||
|
||||
private static Bitmap CreateBitmap(byte[] bytes)
|
||||
{
|
||||
using var stream = new MemoryStream(bytes);
|
||||
|
||||
@@ -57,4 +57,25 @@ public sealed class SettingsStore
|
||||
public string EncryptPassword(string password) => _protectedStringService.Protect(password);
|
||||
|
||||
public string DecryptBackendApiToken(AppSettings settings) => _protectedStringService.Unprotect(settings.Backend.EncryptedApiToken);
|
||||
|
||||
public static string NormalizeBackendApiToken(string token)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(token))
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
var normalized = token.Trim().Trim('"', '\'').Trim();
|
||||
if (normalized.StartsWith("Authorization:", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
normalized = normalized["Authorization:".Length..].Trim();
|
||||
}
|
||||
|
||||
if (normalized.StartsWith("Bearer ", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
normalized = normalized["Bearer ".Length..].Trim();
|
||||
}
|
||||
|
||||
return normalized.Trim().Trim('"', '\'').Trim();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user