-
Notifications
You must be signed in to change notification settings - Fork 526
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Create KeycloakRealmResource to represent the address of a realm #5092
Comments
@julioct @DamianEdwards - any thoughts on this? |
I have an implementation that I can submit. |
This is what I have now: /// <summary>
/// Adds a Keycloak Realm to the application model from a <see cref="IResourceBuilder{KeycloakRealmResource}"/>.
/// </summary>
/// <param name="builder">The Keycloak server resource builder.</param>
/// <param name="name">The name of the realm.</param>
/// <param name="realmName">The name of the realm. If not provided, the resource name will be used.</param>
/// <returns>A reference to the <see cref="IResourceBuilder{KeycloakRealmResource}"/>.</returns>
public static IResourceBuilder<KeycloakRealmResource> AddRealm(
this IResourceBuilder<KeycloakResource> builder,
string name,
string? realmName = null)
{
ArgumentNullException.ThrowIfNull(builder);
// Use the resource name as the realm name if it's not provided
realmName ??= name;
var keycloakRealm = new KeycloakRealmResource(name, realmName, builder.Resource);
return builder.ApplicationBuilder.AddResource(keycloakRealm);
}
/// <summary>
/// Represents a Keycloak Realm resource.
/// </summary>
/// <param name="name">The name of the realm resource.</param>
/// <param name="realmName">The name of the realm.</param>
/// <param name="parent">The Keycloak server resource associated with this database.</param>
public sealed class KeycloakRealmResource(string name, string realmName, KeycloakResource parent) : Resource(name), IResourceWithParent<KeycloakResource>, IResourceWithConnectionString
{
private EndpointReference? _parentEndpoint;
private EndpointReference ParentEndpoint => _parentEndpoint ??= new(Parent, "http");
/// <inheritdoc/>
public ReferenceExpression ConnectionStringExpression => ReferenceExpression.Create(
$"{ParentEndpoint.Property(EndpointProperty.Url)}/realms/{RealmName}");
/// <inheritdoc/>
public KeycloakResource Parent { get; } = parent;
/// <summary>
/// Gets the name of the realm.
/// </summary>
public string RealmName { get; } = realmName;
} I don't use any Keycloak Aspire components in my applications. Usually, it's just used like this: resourcebuild.WithEnvironment("JwtBearerOptions__Authority", realm); But, sometimes the application already has configuration for providers without resourcebuild
.WithEnvironment(ctx =>
{
var baseAddress = idp.Resource.ConnectionStringExpression;
ctx.EnvironmentVariables["JwtBearerOptions__Authority"] = baseAddress;
ctx.EnvironmentVariables["JwtBearerOptions__MetadataAddress"] = ReferenceExpression.Create($"{baseAddress}/.well-known/openid-configuration");
ctx.EnvironmentVariables["JwtBearerOptions__Configuration__Issuer"] = baseAddress;
ctx.EnvironmentVariables["JwtBearerOptions__Configuration__AuthorizationEndpoint"] = ReferenceExpression.Create($"{baseAddress}/protocol/openid-connect/auth");
ctx.EnvironmentVariables["JwtBearerOptions__Configuration__TokenEndpoint"] = ReferenceExpression.Create($"{baseAddress}/protocol/openid-connect/token");
ctx.EnvironmentVariables["JwtBearerOptions__Configuration__UserInfoEndpoint"] = ReferenceExpression.Create($"{baseAddress}/protocol/openid-connect/userinfo");
ctx.EnvironmentVariables["JwtBearerOptions__RequireHttpsMetadata"] = "false";
ctx.EnvironmentVariables["JwtBearerOptions__TokenValidationParameters__RequireSignedTokens"] = "false";
ctx.EnvironmentVariables["JwtBearerOptions__TokenValidationParameters__ValidateAudience"] = "false";
ctx.EnvironmentVariables["JwtBearerOptions__TokenValidationParameters__ValidateActor"] = "false";
ctx.EnvironmentVariables["JwtBearerOptions__TokenValidationParameters__ValidateIssuer"] = "false";
ctx.EnvironmentVariables["JwtBearerOptions__TokenValidationParameters__ValidateIssuerSigningKey"] = "false";
ctx.EnvironmentVariables["JwtBearerOptions__TokenValidationParameters__ValidateLifetime"] = "false";
})
; One improvement would be to create properties and expressions for all these paths. If it's OK with you, I can submit a PR with this, and we'll go from there. |
I don't think we're ready to work on a PR for this right now to be honest. This is an important area that we want to return to but Keycloak improvements aren't in scope for the next minor release or two so a PR at this point might not get much attention. That said, a draft PR from a fork where we can explore ideas together isn't at all a bad thing, just setting expectations. |
I've created a draft PR for this: #7120 for discussion and for those that need it to pick it up. Keycloak integration is still in preview. We can iterate on it. |
Background and Motivation
A Keycloak server may have several realms and the realms are what's important for applications.
But, at the moment,
JwtBearerOptions
does not support service discovery for authority and Keycloak has its own way of constructing the base address of the realm.It would be helpful, if "creating" a realm would create connection string for the realm.
Proposed API
On the Aspire host, there would be a
AddReal
method that would create a connections string to the realm.Usage Examples
On the service side, the service would only have to register the configuration:
The text was updated successfully, but these errors were encountered: