mirror of
https://github.com/fiodarsazanavets/aspire-13-examples.git
synced 2026-06-20 12:23:14 +00:00
Add Keycloak components to the Host app in the Keycloak example
This commit is contained in:
@@ -1,12 +1,49 @@
|
|||||||
|
using Microsoft.Extensions.Hosting;
|
||||||
|
using OnlineShop.AppHost.Extensions;
|
||||||
|
|
||||||
var builder = DistributedApplication.CreateBuilder(args);
|
var builder = DistributedApplication.CreateBuilder(args);
|
||||||
|
|
||||||
var apiService = builder.AddProject<Projects.OnlineShop_ApiService>("apiservice")
|
var idp = builder.AddKeycloakContainer(
|
||||||
.WithHttpHealthCheck("/health");
|
"idp", tag: "23.0")
|
||||||
|
.ImportRealms("Keycloak")
|
||||||
|
.WithExternalHttpEndpoints();
|
||||||
|
|
||||||
builder.AddProject<Projects.OnlineShop_Web>("webfrontend")
|
|
||||||
|
var apiService = builder.AddProject<Projects.OnlineShop_ApiService>("apiservice")
|
||||||
|
.WithHttpHealthCheck("/health")
|
||||||
|
.WithReference(idp)
|
||||||
|
.WaitFor(idp);
|
||||||
|
|
||||||
|
|
||||||
|
var webFrontend = builder
|
||||||
|
.AddProject<Projects.OnlineShop_Web>("webfrontend")
|
||||||
.WithExternalHttpEndpoints()
|
.WithExternalHttpEndpoints()
|
||||||
.WithHttpHealthCheck("/health")
|
.WithHttpHealthCheck("/health")
|
||||||
.WithReference(apiService)
|
.WithReference(apiService)
|
||||||
.WaitFor(apiService);
|
.WithReference(idp, env: "Identity__ClientSecret")
|
||||||
|
.WaitFor(idp);
|
||||||
|
|
||||||
|
if (builder.Environment.IsDevelopment())
|
||||||
|
{
|
||||||
|
var webAppHttp = webFrontend.GetEndpoint("http");
|
||||||
|
var webAppHttps = webFrontend.GetEndpoint("https");
|
||||||
|
|
||||||
|
idp.WithEnvironment("WEBAPP_HTTP", () =>
|
||||||
|
$"{webAppHttp.Scheme}://{webAppHttp.Host}:{webAppHttp.Port}");
|
||||||
|
|
||||||
|
if (webAppHttps.Exists)
|
||||||
|
{
|
||||||
|
idp.WithEnvironment("WEBAPP_HTTP_CONTAINERHOST",
|
||||||
|
webAppHttps);
|
||||||
|
idp.WithEnvironment("WEBAPP_HTTPS", () =>
|
||||||
|
$"{webAppHttps.Scheme}://{webAppHttps.Host}:{webAppHttps.Port}");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
idp.WithEnvironment("WEBAPP_HTTP_CONTAINERHOST",
|
||||||
|
webAppHttp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
builder.Build().Run();
|
builder.Build().Run();
|
||||||
|
|||||||
+86
@@ -0,0 +1,86 @@
|
|||||||
|
namespace OnlineShop.AppHost.Extensions;
|
||||||
|
|
||||||
|
internal static class KeycloakHostingExtensions
|
||||||
|
{
|
||||||
|
public static IResourceBuilder<TResource> WithReference<TResource>(
|
||||||
|
this IResourceBuilder<TResource> builder,
|
||||||
|
IResourceBuilder<KeycloakResource> keycloakBuilder,
|
||||||
|
string env) where TResource : IResourceWithEnvironment
|
||||||
|
{
|
||||||
|
builder.WithReference(keycloakBuilder);
|
||||||
|
builder.WithEnvironment(
|
||||||
|
env, keycloakBuilder.Resource.ClientSecret);
|
||||||
|
|
||||||
|
return builder;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static IResourceBuilder<KeycloakResource> AddKeycloakContainer(
|
||||||
|
this IDistributedApplicationBuilder builder,
|
||||||
|
string name,
|
||||||
|
int? port = null,
|
||||||
|
string? tag = null)
|
||||||
|
{
|
||||||
|
var keycloakContainer = new KeycloakResource(name)
|
||||||
|
{
|
||||||
|
ClientSecret = "some_secret"
|
||||||
|
};
|
||||||
|
|
||||||
|
var keycloak = builder.AddResource(keycloakContainer)
|
||||||
|
.WithAnnotation(new ContainerImageAnnotation
|
||||||
|
{
|
||||||
|
Registry = "quay.io",
|
||||||
|
Image = "keycloak/keycloak",
|
||||||
|
Tag = tag ?? "latest"
|
||||||
|
})
|
||||||
|
.WithHttpEndpoint(port: port, targetPort: 8080)
|
||||||
|
.WithEnvironment("KEYCLOAK_ADMIN", "admin")
|
||||||
|
.WithEnvironment("KEYCLOAK_ADMIN_PASSWORD", "admin")
|
||||||
|
.WithEnvironment("WEBAPP_CLIENT_SECRET", keycloakContainer.ClientSecret);
|
||||||
|
|
||||||
|
if (builder.ExecutionContext.IsRunMode)
|
||||||
|
{
|
||||||
|
keycloak.WithArgs("start-dev");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
keycloak.WithArgs("start");
|
||||||
|
}
|
||||||
|
|
||||||
|
return keycloak;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static IResourceBuilder<KeycloakResource>
|
||||||
|
ImportRealms(this IResourceBuilder<KeycloakResource>
|
||||||
|
builder, string source)
|
||||||
|
{
|
||||||
|
builder
|
||||||
|
.WithBindMount(source,
|
||||||
|
"/opt/keycloak/data/import")
|
||||||
|
.WithAnnotation(
|
||||||
|
new CommandLineArgsCallbackAnnotation(
|
||||||
|
args =>
|
||||||
|
{
|
||||||
|
args.Clear();
|
||||||
|
if (builder.ApplicationBuilder
|
||||||
|
.ExecutionContext.IsRunMode)
|
||||||
|
{
|
||||||
|
args.Add("start-dev");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
args.Add("start");
|
||||||
|
}
|
||||||
|
args.Add("--import-realm");
|
||||||
|
}));
|
||||||
|
|
||||||
|
return builder;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal class KeycloakResource(string name) :
|
||||||
|
ContainerResource(name),
|
||||||
|
IResourceWithServiceDiscovery
|
||||||
|
{
|
||||||
|
public string? ClientSecret { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -124,4 +124,13 @@ public static class Extensions
|
|||||||
|
|
||||||
return app;
|
return app;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Uri GetIdpAuthorityUri(this HttpClient httpClient)
|
||||||
|
{
|
||||||
|
var idpBaseUri = httpClient.BaseAddress
|
||||||
|
?? throw new InvalidOperationException(
|
||||||
|
$"HttpClient instance does not have a BaseAddress configured.");
|
||||||
|
return new Uri(idpBaseUri, "realms/OnlineShop/");
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user