dotnet / docs-aspire

This repository contains .NET Aspire documentation.
https://learn.microsoft.com/dotnet/aspire
MIT License
75 stars 95 forks source link

Keycloak - The MetadataAddress or Authority must use HTTPS #1760

Open michaelmcneilnet opened 1 week ago

michaelmcneilnet commented 1 week ago

Is there an existing issue for this?

Describe the bug

When running my API withRequireHttpsMetadata as true, I get the following output in my API logs:

fail: Microsoft.AspNetCore.Server.Kestrel[13]
      Connection id "0HN74G9JA3UFA", Request id "0HN74G9JA3UFA:00000001": An unhandled exception was thrown by the application.
      System.InvalidOperationException: The MetadataAddress or Authority must use HTTPS unless disabled for development by setting RequireHttpsMetadata=false.
         at Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerPostConfigureOptions.PostConfigure(String name, JwtBearerOptions options)
         at Microsoft.Extensions.Options.OptionsFactory`1.Create(String name)
         at System.Lazy`1.ViaFactory(LazyThreadSafetyMode mode)
         at System.Lazy`1.ExecutionAndPublication(LazyHelper executionAndPublication, Boolean useDefaultConstructor)
         at System.Lazy`1.CreateValue()
         at Microsoft.Extensions.Options.OptionsCache`1.GetOrAdd[TArg](String name, Func`3 createOptions, TArg factoryArgument)
         at Microsoft.AspNetCore.Authentication.AuthenticationHandler`1.InitializeAsync(AuthenticationScheme scheme, HttpContext context)
         at Microsoft.AspNetCore.Authentication.AuthenticationHandlerProvider.GetHandlerAsync(HttpContext context, String authenticationScheme)
         at Microsoft.AspNetCore.Authentication.AuthenticationService.AuthenticateAsync(HttpContext context, String scheme)
         at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
         at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpProtocol.ProcessRequests[TContext](IHttpApplication`1 application)

Expected Behavior

I would expect the Keycloak integration to set the Authority in a compatible way.

Steps To Reproduce

API Program.cs:

services.AddAuthentication()
    .AddKeycloakJwtBearer("keycloak", realm: "XX", options =>
    {
        options.Audience = "XX.api";
        options.RequireHttpsMetadata = true;
    });

I can see that AspireKeycloakExtensions.AddKeycloakJwtBearer sets the Authority using

private static string GetAuthorityUri(
    string serviceName,
    string realm)
{
    return $"https+http://{serviceName}/realms/{realm}";
}

Could it be that the +http part causes the error?

Exceptions (if any)

No response

.NET Version info

.NET SDK: Version: 9.0.100-rc.1.24452.12 Commit: 81a714c6d3 Workload version: 9.0.100-manifests.67cd1eb6 MSBuild version: 17.12.0-preview-24422-09+d17ec720d

Runtime Environment: OS Name: Windows OS Version: 10.0.22631 OS Platform: Windows RID: win-x64 Base Path: C:\Program Files\dotnet\sdk\9.0.100-rc.1.24452.12\

.NET workloads installed: Configured to use loose manifests when installing new manifests. [aspire] Installation Source: VS 17.12.35323.107 Manifest Version: 8.2.0/8.0.100 Manifest Path: C:\Program Files\dotnet\sdk-manifests\8.0.100\microsoft.net.sdk.aspire\8.2.0\WorkloadManifest.json Install Type: FileBased

Host: Version: 9.0.0-rc.1.24431.7 Architecture: x64 Commit: static

.NET SDKs installed: 9.0.100-rc.1.24452.12 [C:\Program Files\dotnet\sdk]

.NET runtimes installed: Microsoft.AspNetCore.App 6.0.33 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App] Microsoft.AspNetCore.App 8.0.8 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App] Microsoft.AspNetCore.App 9.0.0-rc.1.24452.1 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App] Microsoft.NETCore.App 6.0.15 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App] Microsoft.NETCore.App 6.0.33 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App] Microsoft.NETCore.App 8.0.8 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App] Microsoft.NETCore.App 9.0.0-rc.1.24431.7 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App] Microsoft.WindowsDesktop.App 6.0.15 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App] Microsoft.WindowsDesktop.App 6.0.33 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App] Microsoft.WindowsDesktop.App 8.0.8 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App] Microsoft.WindowsDesktop.App 9.0.0-rc.1.24452.1 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]

Other architectures found: x86 [C:\Program Files (x86)\dotnet] registered at [HKLM\SOFTWARE\dotnet\Setup\InstalledVersions\x86\InstallLocation]

Environment variables: Not set

global.json file: Not found

Anything else?

<PackageVersion Include="Aspire.Hosting.AppHost" Version="9.0.0-preview.4.24502.4" />
<PackageVersion Include="Aspire.Hosting.Keycloak" Version="9.0.0-preview.4.24467.1" />
<PackageVersion Include="Aspire.Keycloak.Authentication" Version="9.0.0-preview.4.24477.7" />
michaelmcneilnet commented 1 week ago

Just confirmed the +http is the issue. If I manually set the Authority to https only, rather than let the Aspire integration set it, error is resolved:

services.AddAuthentication()
    .AddKeycloakJwtBearer("keycloak", realm: "XX", options =>
    {
        options.Audience = "XX.api";
        options.Authority = "https://keycloak/realms/XX";
        options.RequireHttpsMetadata = true;
    });

Error is being thrown from:

https://github.com/dotnet/aspnetcore/blob/9497495d4123d4508c0c7a3148fb270ea37dcd87/src/Security/Authentication/JwtBearer/src/JwtBearerPostConfigureOptions.cs#L47

which checks the Authority starts with https://