Open Closed

ExternalProviderSettingsHelper after upgrade to 9.2.3 from 9.0.4 not working #9700


User avatar
0
sghorakavi@cpat.com created
  • Steps to reproduce the issue: UPgraded project from 9.0.4 to 9.2.3 version of Volo. We had Helper override methods for class "ExternalProviderSettingsHelper". We need them to save tenant specific external login settings. GetByNameAsync(string name, bool fallBackToHost = false) and public override async Task SetAsync(List<ExternalProviderSettings> settings) not working now. Please help.

66 Answer(s)
  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    hi

    Please send a mail to liming.ma@volosoft.com

    I will share the latest source code of ExternalProviderSettingsHelper.

    Thanks.

  • User Avatar
    0
    sghorakavi@cpat.com created

    done, thank you

  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    hi

    I have sent the source code.

    Thanks.

  • User Avatar
    0
    sghorakavi@cpat.com created

    Thank you for the code. But where should I use it. I have code like below. It used tow work before with 9.0.4 now it is not saving settings for External provider. please check public override async Task SetAsync(List<ExternalProviderSettings> settings) method. I have updated parameters for it to build with 9.2.3

    public class Shared_TMSExternalProviderSettingsHelper : ExternalProviderSettingsHelper { private readonly ICurrentTenant _currentTenant; private readonly AbpExternalProviderOptions _externalProviderOptions; private readonly Volo.Abp.SettingManagement.ISettingManager _settingManager; private readonly IJsonSerializer _jsonSerializer;

    public Shared_TMSExternalProviderSettingsHelper(
        ICurrentTenant currentTenant,
        IOptions&lt;AbpExternalProviderOptions&gt; externalProvidersOptions,
        Volo.Abp.SettingManagement.ISettingManager settingManager,
        IJsonSerializer jsonSerializer,
        ISettingEncryptionService stringEncryptionService,
        ISettingDefinitionManager settingDefinitionManager) : base(currentTenant, externalProvidersOptions, settingManager, jsonSerializer, stringEncryptionService, settingDefinitionManager)
    {
        _currentTenant = currentTenant;
        _externalProviderOptions = externalProvidersOptions.Value;
        _settingManager = settingManager;
        _jsonSerializer = jsonSerializer;
    }
    
    public override async Task&lt;List&lt;ExternalProviderSettings&gt;> GetAllAsync()
    {
        var allSettings = new List&lt;ExternalProviderSettings&gt;();
    
        List&lt;ExternalProviderSettings&gt; hostSettingsList;
        using (_currentTenant.Change(_currentTenant.Id))
        {
            hostSettingsList = await GetSettingsListOrNullAsync(GlobalSettingValueProvider.ProviderName, null);
        }
    
        var settingsList = _currentTenant.IsAvailable
            ? await GetSettingsListOrNullAsync(TenantSettingValueProvider.ProviderName, _currentTenant.Id?.ToString())
            : hostSettingsList;
    
        foreach (var externalProviderDefinition in _externalProviderOptions.Definitions)
        {
            var newSettings = CreateSettings(externalProviderDefinition);
            var existSettings = settingsList?.FirstOrDefault(x => x.Name == externalProviderDefinition.Name);
            if (existSettings != null)
            {
                CloneSettings(existSettings, newSettings);
            }
    
            if (_currentTenant.IsAvailable)
            {
                newSettings.Enabled = settingsList?.FirstOrDefault(x => x.Name == externalProviderDefinition.Name)?.Enabled
                                      ?? false;
            }
    
            allSettings.Add(newSettings);
        }
    
        return allSettings;
    }
    public async Task&lt;ExternalProviderSettings&gt; GetByNameAsync(string name, bool fallBackToHost = false)
    {
        var definition = _externalProviderOptions.Definitions.FirstOrDefault(x => x.Name == name);
        if (definition == null)
        {
            throw new Exception($"External provider with {name} not definition!");
        }
    
        if (_currentTenant.IsAvailable)
        {
            var settings = await GetSettingsAsync(definition, TenantSettingValueProvider.ProviderName, _currentTenant.Id?.ToString());
    
            if (settings.Enabled || !fallBackToHost)
            {
                return settings;
            }
        }
    
        return await GetSettingsAsync(definition, GlobalSettingValueProvider.ProviderName, null); ;
    } 
    
    
    public virtual ExternalProviderDefinition GetDefinitionsByNameOrNull(string name)
    {
        return _externalProviderOptions.Definitions.FirstOrDefault(x => x.Name == name);
    }
    
    
    //public async Task SetAsync(List&lt;ExternalProviderSettings&gt; settings)
    //{
    //    foreach (var setting in settings)
    //    {
    //        var prefix = $"Abp.ExternalLogin.{setting.Name}";
    
    //        await _settingManager.SetForTenantAsync(_currentTenant.Id, $"{prefix}.ClientId", setting.ClientId);
    //        await _settingManager.SetForTenantAsync(_currentTenant.Id, $"{prefix}.ClientSecret", setting.ClientSecret);
    //        await _settingManager.SetForTenantAsync(_currentTenant.Id, $"{prefix}.IsEnabled", setting.IsEnabled.ToString().ToLowerInvariant());
    //    }
    //}
    
    
     public override async Task SetAsync(List&lt;ExternalProviderSettings&gt; settings)
      {
       
         foreach (var setting in settings)
         {
             var definition = _externalProviderOptions.Definitions.FirstOrDefault(x => x.Name == setting.Name);
             if (definition == null)
             {
                 throw new Exception($"External provider with {settings[0].Name} not definition!");
             }
    
             var newSettings = CreateSettings(definition);
    
             CloneSettings(setting, newSettings);
    
             if (_currentTenant.IsAvailable)
             {
                 newSettings.Enabled = setting.Enabled;
             }
    
             var existSettingsList = (_currentTenant.IsAvailable
                 ? await GetSettingsListOrNullAsync(TenantSettingValueProvider.ProviderName, _currentTenant.Id?.ToString())
                 : await GetSettingsListOrNullAsync(GlobalSettingValueProvider.ProviderName, null)) ?? new List&lt;ExternalProviderSettings&gt;();
    
             existSettingsList.RemoveAll(x => x.Name == definition.Name);
             existSettingsList.Add(newSettings);
    
             if (_currentTenant.IsAvailable)
             {
                 await _settingManager.SetForCurrentTenantAsync(AccountSettingNames.ExternalProviders, _jsonSerializer.Serialize(existSettingsList));
             }
             else
             {
                 await _settingManager.SetGlobalAsync(AccountSettingNames.ExternalProviders, _jsonSerializer.Serialize(existSettingsList));
             }
         } 
    }
    
    
    
    protected virtual async Task&lt;ExternalProviderSettings&gt; GetSettingsAsync(
        ExternalProviderDefinition definition,
        string providerName,
        string providerKey)
    {
        var newSettings = CreateSettings(definition);
    
        var settingsList = await GetSettingsListOrNullAsync(providerName, providerKey);
        var existSettings = settingsList?.FirstOrDefault(x => x.Name == definition.Name);
        if (existSettings != null)
        {
            CloneSettings(existSettings, newSettings);
        }
    
        return newSettings;
    }
    
    protected virtual async Task&lt;List&lt;ExternalProviderSettings&gt;> GetSettingsListOrNullAsync(
        string providerName,
        string providerKey)
    {
        var settings = await _settingManager.GetOrNullAsync(AccountSettingNames.ExternalProviders, providerName, providerKey, false);
        return settings.IsNullOrWhiteSpace() ? null : _jsonSerializer.Deserialize&lt;List&lt;ExternalProviderSettings&gt;>(settings);
    }
    
    protected virtual ExternalProviderSettings CreateSettings(ExternalProviderDefinition definition)
    {
        return new ExternalProviderSettings
        {
            Name = definition.Name,
            Enabled = false,
    
            Properties = definition.Properties.
                Where(x => !x.IsSecret).
                Select(x => new ExternalProviderSettingsProperty(x.PropertyName, null)).
                ToList(),
    
            SecretProperties = definition.Properties.
                Where(x => x.IsSecret).
                Select(x => new ExternalProviderSettingsProperty(x.PropertyName, null)).
                ToList()
        };
    }
    
    protected virtual void CloneSettings(ExternalProviderSettings source, ExternalProviderSettings dest)
    {
        dest.Name = source.Name;
        dest.Enabled = source.Enabled;
        foreach (var item in dest.Properties)
        {
            item.Value = source.Properties.FirstOrDefault(x => x.Name.Equals(item.Name, StringComparison.InvariantCultureIgnoreCase))?.Value;
        }
        foreach (var item in dest.SecretProperties)
        {
            item.Value = source.SecretProperties.FirstOrDefault(x => x.Name.Equals(item.Name, StringComparison.InvariantCultureIgnoreCase))?.Value;
        }
    }
    

    }

  • User Avatar
    0
    sghorakavi@cpat.com created

    please check my response above. I am trying to save settings of subdomain tenant. It is erroring.

  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    Can you just remove your custom Shared_TMSExternalProviderSettingsHelper?

    Why did you override the ExternalProviderSettingsHelper?

  • User Avatar
    0
    sghorakavi@cpat.com created

    It was done to save tenant specific external login options. One tenant need AD another needs Ping.

  • User Avatar
    0
    sghorakavi@cpat.com created

    will it work without override ?

  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    hi

    You can try it. We have changed this feature. You can also try with a new template.

    Thanks.

  • User Avatar
    0
    sghorakavi@cpat.com created

    Sure, let me try. New template ? Which file ?

  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    You can set the client id and secret in the host and different tenants. no need to change anything.

    The MVC app template will be fine.

  • User Avatar
    0
    sghorakavi@cpat.com created

    if I change clientID and secret in the UI for the tenant, will it work automatically in 9.2.3 version? No code change is needed ?

  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    Yes. you can try that.

  • User Avatar
    0
    sghorakavi@cpat.com created

    I removed that file and recompiled. It does not save settings (PingID ) information for tenant. If I login without tenant, it saved data. We need to save data for tenant.

  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    hi

    Can you share full steps to show this problem?

    I will use new template project to test it

    Thanks.

  • User Avatar
    0
    sghorakavi@cpat.com created

    sure. 1- login to non tenant 2- go to settings (External provider) 3- add client id,client secret etc for Microsoft (AD) 4- save 5- create tenantA 6- login as admin for the tenantA 7- go to settings (External provider) 8- Update pingID settings 9- save 10- logout from tenant 11- login to tenant 12- settings entered in step 8 above is missing

    Please try and let me know. Thank you

  • User Avatar
    0
    sghorakavi@cpat.com created

    Users page is not working as well. This is another issue when we upgraded

  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    hi

    8- Update pingID settings 12- settings entered in step 8 above is missing

    Can you share some screenshots

    Thanks.

  • User Avatar
    0
    sghorakavi@cpat.com created

    sure.

  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    hi

    I tested the host and tenant to set Google clientid/secret, and it works.

    Host and tenant will use different login info.

    Thanks

  • User Avatar
    0
    sghorakavi@cpat.com created

    I switched to tenant from host and set Microsoft. -> Saved it-> After move to another tab-> Microsoft check box is gone. ->Audit Logs->go back to external now-> (check box is gone)

  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    hi

    Can you try with a new database or clear the setting from database.

    If still not working can share your test project?

    Liming.Ma@volosoft.com

    Thanks.

  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    Unlocked. Please share the problem details. Thanks

  • User Avatar
    0
    sghorakavi@cpat.com created

    Thank you, Login to http://dev.approach.cpat.com

    1. Administrator -> settings -> external provider
    2. Selct Microsoft for host admin
    3. login to cpattest tenant: http://cpattest.dev.approach.cpat.com
    4. select PingOne from Administrator -> settings -> external provider
    5. logout of tenant
    6. login again to cpattest tenant
    7. the external provider is missing

  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    hi Can you try with a new database or clear the setting from database.

    If still not working can share your test project?

    liming.ma@volosoft.com

    Thanks.

Learn More, Pay Less
33% OFF
All Trainings!
Get Your Deal
Mastering ABP Framework Book
The Official Guide
Mastering
ABP Framework
Learn More
Mastering ABP Framework Book
Made with ❤️ on ABP v10.0.0-preview. Updated on September 12, 2025, 10:20