Skip to content
Open
Show file tree
Hide file tree
Changes from 41 commits
Commits
Show all changes
46 commits
Select commit Hold shift + click to select a range
0df225d
**Add Keycloak with Postgres integration**
axies20 Aug 26, 2025
2e07fa8
Refactor Keycloak Postgres extension for improved configuration
axies20 Aug 26, 2025
1bf7ea7
Merge branch 'main' into KeycloakPostgres
axies20 Aug 26, 2025
90621f4
Refactor Keycloak Postgres extension for streamlined configuration
axies20 Aug 26, 2025
7a4fc17
Update src/CommunityToolkit.Aspire.Keycloak.Postgress/KeycloakPostgre…
axies20 Aug 27, 2025
9b11f66
Refactor Keycloak Postgres extension and restructure project
axies20 Aug 27, 2025
03cbc0a
Merge branch 'main' into KeycloakPostgres
axies20 Aug 27, 2025
53c7ca1
Update src/CommunityToolkit.Aspire.Keycloak.Extensions.Postgres/Keycl…
axies20 Aug 28, 2025
9c913c5
Update src/CommunityToolkit.Aspire.Keycloak.Extensions.Postgres/Keycl…
axies20 Aug 28, 2025
d77acaf
Update src/CommunityToolkit.Aspire.Keycloak.Extensions.Postgres/Keycl…
axies20 Aug 28, 2025
fcfad00
Merge remote-tracking branch 'origin/main' into KeycloakPostgres
axies20 Aug 28, 2025
6cd7d93
Merge branch 'main' into KeycloakPostgres
axies20 Aug 28, 2025
d4720a9
Remove Postgres-specific Keycloak extension and merge functionality i…
axies20 Aug 28, 2025
3962aa1
Merge remote-tracking branch 'origin/KeycloakPostgres' into KeycloakP…
axies20 Aug 28, 2025
beb9fe9
Merge branch 'main' into KeycloakPostgres
axies20 Aug 29, 2025
e01ce34
Update tests/CommunityToolkit.Aspire.Keycloak.Extensions.Postgres.Tes…
axies20 Aug 29, 2025
19c6f9a
Refactor Keycloak Postgres extension for code reuse and improved flex…
axies20 Aug 29, 2025
31a647b
Move Keycloak Postgres extension tests into core Keycloak extensions
axies20 Aug 29, 2025
cdd4b15
Merge branch 'main' into KeycloakPostgres
axies20 Sep 6, 2025
1ba736e
Add README and comprehensive tests for Keycloak PostgreSQL integration
axies20 Sep 6, 2025
1efdbbc
Merge remote-tracking branch 'origin/KeycloakPostgres' into KeycloakP…
axies20 Sep 6, 2025
afb6c43
Merge branch 'main' into KeycloakPostgres
axies20 Sep 15, 2025
993aa3e
Merge branch 'main' into KeycloakPostgres
axies20 Sep 16, 2025
6eeee8c
Remove outdated comment in KeycloakExtensionTests regarding server pa…
axies20 Sep 16, 2025
8514cab
Merge remote-tracking branch 'origin/KeycloakPostgres' into KeycloakP…
axies20 Sep 16, 2025
7513876
Add integration tests for Keycloak with Postgres and update project r…
axies20 Sep 16, 2025
8d7af9f
Add Keycloak Postgres example projects and enhance Aspire integration
axies20 Sep 16, 2025
2c66428
Remove unused Moq package reference from Keycloak extension tests pro…
axies20 Sep 16, 2025
d504e4c
Update Keycloak Postgres example projects and dependencies
axies20 Sep 16, 2025
5db02af
Update Aspire package version references to use variable-based approach
axies20 Sep 16, 2025
c5b5d8d
Merge branch 'main' into KeycloakPostgres
axies20 Sep 23, 2025
5424687
Update Directory.Packages.props and Keycloak tests for new package ve…
axies20 Sep 23, 2025
fe16c1f
Merge branch 'main' into KeycloakPostgres
axies20 Sep 28, 2025
50db669
Rename Keycloak Extensions and Examples to use "Hosting" for consistency
axies20 Sep 28, 2025
9d0a369
Merge remote-tracking branch 'origin/KeycloakPostgres' into KeycloakP…
axies20 Sep 28, 2025
96e174f
Merge branch 'main' into KeycloakPostgres
axies20 Oct 1, 2025
fedcf87
Merge branch 'main' into KeycloakPostgres
axies20 Oct 15, 2025
6c968b4
Merge branch 'CommunityToolkit:main' into KeycloakPostgres
axies20 Oct 20, 2025
b1d9793
Rename Keycloak Extensions to "Hosting" for consistency
axies20 Oct 20, 2025
a7422fe
Update Keycloak PostgreSQL extensions for hosting model compliance
axies20 Oct 20, 2025
bbbb8d4
Enhance XML docs for `WithPostgres` methods and fix project references
axies20 Oct 20, 2025
9055d7b
Rename Keycloak Hosting Extensions to Aspire.Hosting for consistency
axies20 Oct 21, 2025
81bb900
Fixing the naming again and some build issues
aaronpowell Oct 22, 2025
4a801e9
Adding the tests in
aaronpowell Oct 22, 2025
cab3674
Fixing more bad changes
aaronpowell Oct 22, 2025
1e5d94d
Dealing with more build errors
aaronpowell Oct 22, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion CommunityToolkit.Aspire.slnx
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,12 @@
<Project Path="examples/k6/CommunityToolkit.Aspire.Hosting.k6.AppHost/CommunityToolkit.Aspire.Hosting.k6.AppHost.csproj" />
<Project Path="examples/k6/CommunityToolkit.Aspire.Hosting.k6.ServiceDefaults/CommunityToolkit.Aspire.Hosting.k6.ServiceDefaults.csproj" />
</Folder>
<Folder Name="/examples/keycloak-postgres/">
<Project Path="examples\keycloak-postgres\CommunityToolkit.Aspire.Keycloak.Hosting.Extensions.AppHost\CommunityToolkit.Aspire.Keycloak.Hosting.Extensions.AppHost.csproj" Type="Classic C#" />
<Project Path="examples\keycloak-postgres\CommunityToolkit.Aspire.Keycloak.Hosting.Extensions.Dev\CommunityToolkit.Aspire.Keycloak.Hosting.Extensions.Dev.csproj" Type="Classic C#" />
<Project Path="examples\keycloak-postgres\CommunityToolkit.Aspire.Keycloak.Hosting.Extensions.Prod\CommunityToolkit.Aspire.Keycloak.Hosting.Extensions.Prod.csproj" Type="Classic C#" />
<Project Path="examples\keycloak-postgres\CommunityToolkit.Aspire.Keycloak.Hosting.Extensions.ServiceDefaults\CommunityToolkit.Aspire.Keycloak.Hosting.Extensions.ServiceDefaults.csproj" Type="Classic C#" />
</Folder>
<Folder Name="/examples/lavinmq/">
<Project Path="examples/lavinmq/CommunityToolkit.Aspire.Hosting.LavinMQ.AppHost/CommunityToolkit.Aspire.Hosting.LavinMQ.AppHost.csproj" />
<Project Path="examples/lavinmq/CommunityToolkit.Aspire.Hosting.LavinMQ.MassTransit/CommunityToolkit.Aspire.Hosting.LavinMQ.MassTransit.csproj" />
Expand Down Expand Up @@ -156,8 +162,8 @@
</Folder>
<Folder Name="/examples/surrealdb/">
<Project Path="examples/surrealdb/CommunityToolkit.Aspire.Hosting.SurrealDb.ApiService/CommunityToolkit.Aspire.Hosting.SurrealDb.ApiService.csproj" />
<Project Path="examples/surrealdb/CommunityToolkit.Aspire.Hosting.SurrealDb.ServiceDefaults/CommunityToolkit.Aspire.Hosting.SurrealDb.ServiceDefaults.csproj" />
<Project Path="examples/surrealdb/CommunityToolkit.Aspire.Hosting.SurrealDb.AppHost/CommunityToolkit.Aspire.Hosting.SurrealDb.AppHost.csproj" />
<Project Path="examples/surrealdb/CommunityToolkit.Aspire.Hosting.SurrealDb.ServiceDefaults/CommunityToolkit.Aspire.Hosting.SurrealDb.ServiceDefaults.csproj" />
</Folder>
<Folder Name="/src/">
<Project Path="src/CommunityToolkit.Aspire.EventStore/CommunityToolkit.Aspire.EventStore.csproj" />
Expand Down Expand Up @@ -205,6 +211,7 @@
<Project Path="src/CommunityToolkit.Aspire.OllamaSharp/CommunityToolkit.Aspire.OllamaSharp.csproj" />
<Project Path="src/CommunityToolkit.Aspire.RavenDB.Client/CommunityToolkit.Aspire.RavenDB.Client.csproj" />
<Project Path="src/CommunityToolkit.Aspire.SurrealDb/CommunityToolkit.Aspire.SurrealDb.csproj" />
<Project Path="src\CommunityToolkit.Aspire.Keycloak.Hosting.Extensions\CommunityToolkit.Aspire.Keycloak.Hosting.Extensions.csproj" Type="Classic C#" />
</Folder>
<Folder Name="/src/Dapr/">
<Project Path="src/CommunityToolkit.Aspire.Hosting.Azure.Dapr.Redis/CommunityToolkit.Aspire.Hosting.Azure.Dapr.Redis.csproj" />
Expand Down Expand Up @@ -258,6 +265,7 @@
<Project Path="tests/CommunityToolkit.Aspire.RavenDB.Client.Tests/CommunityToolkit.Aspire.RavenDB.Client.Tests.csproj" />
<Project Path="tests/CommunityToolkit.Aspire.SurrealDb.Tests/CommunityToolkit.Aspire.SurrealDb.Tests.csproj" />
<Project Path="tests/CommunityToolkit.Aspire.Testing/CommunityToolkit.Aspire.Testing.csproj" />
<Project Path="tests\CommunityToolkit.Aspire.Keycloak.Hosting.Extensions.Tests\CommunityToolkit.Aspire.Keycloak.Hosting.Extensions.Tests.csproj" Type="Classic C#" />
</Folder>
<Folder Name="/tests/Dapr/">
<Project Path="tests/CommunityToolkit.Aspire.Hosting.Azure.Dapr.Redis.Tests/CommunityToolkit.Aspire.Hosting.Azure.Dapr.Redis.Tests.csproj" />
Expand Down
5 changes: 5 additions & 0 deletions Directory.Packages.props
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
<Project>
<PropertyGroup>
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
<AspirePreviewVersion>9.4.1-preview.1.25408.4</AspirePreviewVersion>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This belongs in the Directory.Build.props file, and it should be just the suffix, so that when used we would do <PackageVersion Include="Aspire.Hosting.Keycloak" Version="$(AspireVersion)-$(AspirePreviewSuffix)" />, which ensures that we sync the Major.Minor.Patch across all packages.

<MoqVersion>4.20.72</MoqVersion>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This belongs in Directory.Build.props

</PropertyGroup>
<ItemGroup Label="Aspire Packages">
<!-- Aspire packages -->
Expand All @@ -18,6 +20,9 @@
<PackageVersion Include="Aspire.Hosting.MongoDB" Version="$(AspireVersion)" />
<PackageVersion Include="Aspire.Hosting.MySql" Version="$(AspireVersion)" />
<PackageVersion Include="Aspire.Hosting.SqlServer" Version="$(AspireVersion)" />
<PackageVersion Include="Aspire.Hosting.Keycloak" Version="$(AspirePreviewVersion)" />
<PackageVersion Include="Aspire.Keycloak.Authentication" Version="$(AspirePreviewVersion)" />
<PackageVersion Include="Moq" Version="$(MoqVersion)" />
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This belongs in the <ItemGroup Label="Testing"> section.

</ItemGroup>
<ItemGroup Label="Core Packages">
<!-- AspNetCore packages -->
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
using Aspire.Hosting;

var builder = DistributedApplication.CreateBuilder(args);

var postgres = builder.AddPostgres("keycloak-postgres-dev");
var dbDev = postgres.AddDatabase("db-dev");

var keycloakDev = builder.AddKeycloak("keycloak-dev")
.WithPostgres(dbDev);

var dbUserName = builder.AddParameter("db-username", "postgres");
var dbPassword = builder.AddParameter("db-password", "Postgres!123");

var postgresProd = builder.AddPostgres("postgres-prod",
dbUserName, dbPassword);

var dbProd = postgresProd.AddDatabase("db-prod");

var keycloakProd = builder.AddKeycloak("keycloak-prod")
.WithPostgres(dbProd, dbUserName, dbPassword);


builder.AddProject<Projects.CommunityToolkit_Aspire_Keycloak_Hosting_Extensions_Dev>("project-dev")
.WithReference(keycloakDev)
.WaitFor(keycloakDev);

builder.AddProject<Projects.CommunityToolkit_Aspire_Keycloak_Hosting_Extensions_Prod>("project-prod")
.WithReference(keycloakProd)
.WaitFor(keycloakProd);
builder.Build().Run();
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<Project Sdk="Microsoft.NET.Sdk">

<Sdk Name="Aspire.AppHost.Sdk" Version="$(AspireAppHostSdkVersion)"/>

<PropertyGroup>
<OutputType>Exe</OutputType>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<TargetFramework>net9.0</TargetFramework>
<UserSecretsId>e5e65289-cf91-4bda-b628-28a68fb90841</UserSecretsId>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Aspire.Hosting"/>
<PackageReference Include="Aspire.Hosting.AppHost"/>
<PackageReference Include="Aspire.Hosting.Keycloak"/>
<PackageReference Include="Aspire.Hosting.PostgreSQL"/>
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\..\..\src\CommunityToolkit.Aspire.Keycloak.Hosting.Extensions\CommunityToolkit.Aspire.Keycloak.Hosting.Extensions.csproj" IsAspireProjectResource="false" />
<ProjectReference Include="..\CommunityToolkit.Aspire.Keycloak.Hosting.Extensions.Dev\CommunityToolkit.Aspire.Keycloak.Hosting.Extensions.Dev.csproj" />
<ProjectReference Include="..\CommunityToolkit.Aspire.Keycloak.Hosting.Extensions.Prod\CommunityToolkit.Aspire.Keycloak.Hosting.Extensions.Prod.csproj" />
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
{
"$schema": "https://json.schemastore.org/launchsettings.json",
"profiles": {
"https": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"applicationUrl": "https://localhost:17044;http://localhost:15216",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development",
"DOTNET_ENVIRONMENT": "Development",
"ASPIRE_DASHBOARD_OTLP_ENDPOINT_URL": "https://localhost:21202",
"ASPIRE_RESOURCE_SERVICE_ENDPOINT_URL": "https://localhost:22139"
}
},
"http": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"applicationUrl": "http://localhost:15216",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development",
"DOTNET_ENVIRONMENT": "Development",
"ASPIRE_DASHBOARD_OTLP_ENDPOINT_URL": "http://localhost:19292",
"ASPIRE_RESOURCE_SERVICE_ENDPOINT_URL": "http://localhost:20099"
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning",
"Aspire.Hosting.Dcp": "Warning"
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
@CommunityToolkit.Aspire.Keycloak.Extensions_HostAddress = http://localhost:5030

GET {{CommunityToolkit.Aspire.Keycloak.Extensions_HostAddress}}/weatherforecast/
Accept: application/json

###
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<Project Sdk="Microsoft.NET.Sdk.Web">

<PropertyGroup>
<TargetFramework>net9.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Aspire.Keycloak.Authentication" />
<PackageReference Include="Microsoft.AspNetCore.OpenApi" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\CommunityToolkit.Aspire.Keycloak.Hosting.Extensions.ServiceDefaults\CommunityToolkit.Aspire.Keycloak.Hosting.Extensions.ServiceDefaults.csproj" />
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
using CommunityToolkit.Aspire.Keycloak.Hosting.Extensions.AppHost.ServiceDefaults;

var builder = WebApplication.CreateBuilder(args);
builder.AddServiceDefaults();

builder.Services.AddAuthentication()
.AddKeycloakJwtBearer("keycloak-dev", "master", jwt =>
{
if (builder.Environment.IsDevelopment())
{
//for development only
jwt.RequireHttpsMetadata = false;
}


});

var app = builder.Build();


app.UseHttpsRedirection();

var summaries = new[]
{
"Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
};

app.MapGet("/weatherforecast", () =>
{
var forecast = Enumerable.Range(1, 5).Select(index =>
new WeatherForecast
(
DateOnly.FromDateTime(DateTime.Now.AddDays(index)),
Random.Shared.Next(-20, 55),
summaries[Random.Shared.Next(summaries.Length)]
))
.ToArray();
return forecast;
})
.WithName("GetWeatherForecast");

app.Run();

record WeatherForecast(DateOnly Date, int TemperatureC, string? Summary)
{
public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"$schema": "https://json.schemastore.org/launchsettings.json",
"profiles": {
"http": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": false,
"applicationUrl": "http://localhost:5030",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"https": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": false,
"applicationUrl": "https://localhost:7041;http://localhost:5030",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
@CommunityToolkit.Aspire.Keycloak.Extensions.Prod_HostAddress = http://localhost:5286

GET {{CommunityToolkit.Aspire.Keycloak.Extensions.Prod_HostAddress}}/weatherforecast/
Accept: application/json

###
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<Project Sdk="Microsoft.NET.Sdk.Web">

<PropertyGroup>
<TargetFramework>net9.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Aspire.Keycloak.Authentication"/>
<PackageReference Include="Microsoft.AspNetCore.OpenApi"/>
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\CommunityToolkit.Aspire.Keycloak.Hosting.Extensions.ServiceDefaults\CommunityToolkit.Aspire.Keycloak.Hosting.Extensions.ServiceDefaults.csproj" />
</ItemGroup>
</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
using CommunityToolkit.Aspire.Keycloak.Hosting.Extensions.AppHost.ServiceDefaults;

var builder = WebApplication.CreateBuilder(args);
builder.AddServiceDefaults();

builder.Services.AddAuthentication()
.AddKeycloakJwtBearer("keycloak-prod", "master", jwt =>
{
if (builder.Environment.IsDevelopment())
{
//for development only
jwt.RequireHttpsMetadata = false;
}
});

var app = builder.Build();


app.UseHttpsRedirection();

var summaries = new[]
{
"Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
};

app.MapGet("/weatherforecast", () =>
{
var forecast = Enumerable.Range(1, 5).Select(index =>
new WeatherForecast
(
DateOnly.FromDateTime(DateTime.Now.AddDays(index)),
Random.Shared.Next(-20, 55),
summaries[Random.Shared.Next(summaries.Length)]
))
.ToArray();
return forecast;
})
.WithName("GetWeatherForecast");

app.Run();

record WeatherForecast(DateOnly Date, int TemperatureC, string? Summary)
{
public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"$schema": "https://json.schemastore.org/launchsettings.json",
"profiles": {
"http": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": false,
"applicationUrl": "http://localhost:5286",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"https": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": false,
"applicationUrl": "https://localhost:7134;http://localhost:5286",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net9.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<IsAspireSharedProject>true</IsAspireSharedProject>
<RootNamespace>CommunityToolkit.Aspire.Keycloak.Hosting.Extensions.AppHost.ServiceDefaults</RootNamespace>
</PropertyGroup>

<ItemGroup>
<FrameworkReference Include="Microsoft.AspNetCore.App"/>

<PackageReference Include="Microsoft.Extensions.Http.Resilience"/>
<PackageReference Include="Microsoft.Extensions.ServiceDiscovery"/>
<PackageReference Include="OpenTelemetry.Exporter.OpenTelemetryProtocol"/>
<PackageReference Include="OpenTelemetry.Extensions.Hosting"/>
<PackageReference Include="OpenTelemetry.Instrumentation.AspNetCore"/>
<PackageReference Include="OpenTelemetry.Instrumentation.Http"/>
<PackageReference Include="OpenTelemetry.Instrumentation.Runtime"/>
</ItemGroup>

</Project>
Loading