| File: Dashboard\DashboardServiceAuth.cs | Web Access |
| Project: src\src\Aspire.Hosting\Aspire.Hosting.csproj (Aspire.Hosting) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System.Security.Claims; using System.Text.Encodings.Web; using Microsoft.AspNetCore.Authentication; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; namespace Aspire.Hosting.Dashboard; internal static class ResourceServiceApiKeyAuthorization { public const string PolicyName = "ResourceServiceApiKeyPolicy"; } internal static class ResourceServiceApiKeyAuthenticationDefaults { public const string AuthenticationScheme = "ResourceServiceApiKey"; } internal sealed class ResourceServiceApiKeyAuthenticationOptions : AuthenticationSchemeOptions { } internal sealed class ResourceServiceApiKeyAuthenticationHandler( IOptionsMonitor<ResourceServiceOptions> resourceServiceOptions, IOptionsMonitor<ResourceServiceApiKeyAuthenticationOptions> options, ILoggerFactory logger, UrlEncoder encoder) : AuthenticationHandler<ResourceServiceApiKeyAuthenticationOptions>(options, logger, encoder) { private const string ApiKeyHeaderName = "x-resource-service-api-key"; protected override Task<AuthenticateResult> HandleAuthenticateAsync() { var options = resourceServiceOptions.CurrentValue; if (options.AuthMode is ResourceServiceAuthMode.ApiKey) { if (!Request.Headers.TryGetValue(ApiKeyHeaderName, out var headerValues)) { return Task.FromResult(AuthenticateResult.Fail($"'{ApiKeyHeaderName}' header not found")); } if (headerValues.Count != 1) { return Task.FromResult(AuthenticateResult.Fail($"Expecting only a single '{ApiKeyHeaderName}' header.")); } if (!CompareHelpers.CompareKey(expectedKeyBytes: options.GetApiKeyBytes(), requestKey: headerValues.ToString())) { return Task.FromResult(AuthenticateResult.Fail($"Invalid '{ApiKeyHeaderName}' header value.")); } } return Task.FromResult( AuthenticateResult.Success( new AuthenticationTicket( principal: new ClaimsPrincipal(new ClaimsIdentity( claims: [], authenticationType: ResourceServiceApiKeyAuthenticationDefaults.AuthenticationScheme)), authenticationScheme: Scheme.Name))); } }