-
-
Notifications
You must be signed in to change notification settings - Fork 288
Open
Labels
Description
Andrew,
Until you release a patch for the HttpContextStrategy, I took your advise and used the delegate strategy and I also set the OpenIdConnectOptions per tenant.
services.AddMultiTenant<AppTenantInfo>()
.WithClaimStrategy()
.WithDelegateStrategy<DefaultHttpContext, AppTenantInfo>(httpContext =>
{
if (httpContext.Request.Query.TryGetValue("tenant", out StringValues tenantIdentifier) &&
!StringValues.IsNullOrEmpty(tenantIdentifier))
{
return Task.FromResult<string?>(tenantIdentifier[0]);
}
return Task.FromResult<string?>(null);
})
// .WithStaticStrategy(defaultTenantIdentifier)
.WithHttpRemoteStore(httpRemoteStore, clientBuilder =>
{
clientBuilder.AddHttpMessageHandler<TenantRemoteStoreDelegatingHandler>();
})
// .WithConfigurationStore()
.WithPerTenantAuthentication();
services.ConfigureAllPerTenant<OpenIdConnectOptions, AppTenantInfo>((options, tenant) =>
{
options.RequireHttpsMetadata = webHostEnvironment.IsProduction();
options.Authority = $"http://identity.api:80/{tenant.Identifier}";
options.Events = OpenIdConnectOptionsExtensions.CreateTenantAwareEvents(webHostEnvironment);
});
Here is the static method
public static OpenIdConnectEvents CreateTenantAwareEvents(IWebHostEnvironment env)
{
return new OpenIdConnectEvents
{
OnRedirectToIdentityProvider = context =>
{
var logger = context.HttpContext.RequestServices.GetRequiredService<ILoggerFactory>()
.CreateLogger("OpenIdConnectEvents");
// Read tenant info from the current HttpContext (Finbuckle)
var multiTenantContext = context.HttpContext.GetMultiTenantContext<AppTenantInfo>();
var tenant = multiTenantContext?.TenantInfo;
logger.LogInformation("OnRedirectToIdentityProvider for tenant: {TenantId}", tenant?.Identifier ?? "null");
if (tenant is not null)
{
//context.Options.Authority = $"{tenant.JwtAuthority}/{tenant.Identifier}";
// Use tenant-specific issuer/authority for the redirect
context.ProtocolMessage.IssuerAddress = $"{tenant.JwtAuthority}/{tenant.Identifier}/connect/authorize";
context.ProtocolMessage.UiLocales = Thread.CurrentThread.CurrentUICulture.Name;
if (env.IsDevelopment())
{
// discovery metadata for dev environment
context.Options.RequireHttpsMetadata = false;
context.Options.MetadataAddress = $"http://identity.api:80/{tenant.Identifier}/.well-known/openid-configuration";
}
}
// carry forward any prompt stored in auth properties
if (context.Properties.Items.TryGetValue("prompt", out var prompt))
{
context.ProtocolMessage.Prompt = prompt;
}
return Task.CompletedTask;
},
OnRemoteFailure = context =>
{
context.Response.Redirect("/StatusCode?statusCode=500");
context.HandleResponse();
return Task.CompletedTask;
},
OnAccessDenied = context =>
{
if (context.Request.QueryString.Value is not null)
{
var requestQuery = HttpUtility.ParseQueryString(context.Request.QueryString.Value);
const string descriptionField = "error_description";
const string cancelledCode = "user_canceled_login";
var descriptionFieldValue = requestQuery[descriptionField];
if (!string.IsNullOrEmpty(descriptionFieldValue) &&
descriptionFieldValue.Equals(cancelledCode, StringComparison.OrdinalIgnoreCase))
{
context.Response.Redirect("/");
context.HandleResponse();
return Task.CompletedTask;
}
}
context.Response.Redirect("/StatusCode?statusCode=401");
context.HandleResponse();
return Task.CompletedTask;
}
};
}
When a tenant is found and resolved using the DelegateStrategy, the OpenIdConnectOptions are NOT set for the resolved tenant. However, if I use the StaticStrategy and ConfigurationStore the options do get set for the tenant when a challenge is made.