NikiforovAll / keycloak-authorization-services-dotnet

Authentication and Authorization with Keycloak and ASP.NET Core 🔐
https://nikiforovall.github.io/keycloak-authorization-services-dotnet/
MIT License
478 stars 113 forks source link

Is there any way to reload configuration of keycloak? #149

Open koureasstavros opened 3 weeks ago

koureasstavros commented 3 weeks ago

The following code is registered in the server side of my blazor hosted webassembly at works fine:

KeycloakClientInstallationCredentials keycloakClientInstallationCredentials = new();
keycloakClientInstallationCredentials.Secret = Parameters.openids_secret;
builder.Services.AddKeycloakWebApiAuthentication(options =>
{
    options.Realm = Parameters.transportation.openids_real;
    options.SslRequired = Parameters.transportation.openids_secure;
    options.AuthServerUrl = Parameters.transportation.openids_address_auth;
    options.Resource = Parameters.transportation.openids_client;
    options.Credentials = keycloakClientInstallationCredentials;
}

However there might be a case where I need to change theese parameters and switch to another keycloak, could this be reregistered and the service re-initiated without restarting the app?

I tried a few ways by using dynamic configuration: -The program.cs code:

builder.Configuration.AddConfiguration(dynamicConfig);
builder.Services.AddSingleton(dynamicConfigProvider);

-Some classes code:

public class DynamicConfigurationProvider : ConfigurationProvider
{
    public override void Set(string key, string? value)
    {
        Data[key] = value;
        OnReload();
    }
}

public class DynamicConfigurationSource : IConfigurationSource
{
    public IConfigurationProvider Build(IConfigurationBuilder builder)
    {
        return new DynamicConfigurationProvider();
    }
}

public class ConfigurationService
{
    private readonly IServiceProvider _serviceProvider;
    private readonly DynamicConfigurationProvider _dynamicConfigurationProvider;

    public ConfigurationService(IServiceProvider serviceProvider, DynamicConfigurationProvider dynamicConfigurationProvider)
    {
        _serviceProvider = serviceProvider;
        _dynamicConfigurationProvider = dynamicConfigurationProvider;
    }

    public void UpdateServices()
    {
        UpdateKeycloakSettings();
    }

    private void UpdateKeycloakSettings()
    {
        if (Parameters.transportation != null)
        {
            KeycloakClientInstallationCredentials keycloakClientInstallationCredentials = new();
            keycloakClientInstallationCredentials.Secret = Parameters.openids_secret;

            //TRIAL 1
            var authenticationBuilder = _serviceProvider.GetRequiredService<KeycloakBaseAuthenticationBuilder>();
            authenticationBuilder.Services.AddKeycloakWebApiAuthentication(options =>
            {
                options.Realm = Parameters.transportation.openids_real;
                options.SslRequired = Parameters.transportation.openids_secure;
                options.AuthServerUrl = Parameters.transportation.openids_address_auth;
                options.Resource = Parameters.transportation.openids_client;
                options.Credentials = keycloakClientInstallationCredentials;
            });

            //TRIAL 2
            var options = _serviceProvider.GetRequiredService<KeycloakAuthenticationOptions>();                
            options.Realm = Parameters.transportation.openids_real;
            options.SslRequired = Parameters.transportation.openids_secure;
            options.AuthServerUrl = Parameters.transportation.openids_address_auth; 
            options.Resource = Parameters.transportation.openids_client;
            options.Credentials = keycloakClientInstallationCredentials;

            //TRIAL 3
            //_dynamicConfigurationProvider.Set("Keycloak:realm", Parameters.transportation.openids_real);
            //_dynamicConfigurationProvider.Set("Keycloak:resource", Parameters.transportation.openids_client);
            //_dynamicConfigurationProvider.Set("Keycloak:ssl-required", Parameters.transportation.openids_secure);
            //_dynamicConfigurationProvider.Set("Keycloak:credentials:secret", Parameters.transportation.openids_secret);
            //_dynamicConfigurationProvider.Set("Keycloak:auth-server-url", Parameters.transportation.openids_address_auth);
        }
    }
}

TRIAL 1, throws an error 'No service for type 'Keycloak.AuthServices.Authentication.KeycloakBaseAuthenticationBuilder' has been registered.' TRIAL 2, throws an error 'No service for type 'Keycloak.AuthServices.Authentication.KeycloakAuthenticationOptions' has been registered.' TRIAL 3, does not seems to update service and old keycloak is validating the requests Maybe I am doing something wrong, any suggestion?

NikiforovAll commented 2 days ago

It is a very interesting scenario. I don't think it is something supported by the ASP.NET core itself. :<