After I found correct place to enable self registration I managed to get login working with static appsettings.json settings . So now we need to get dynamic config working.
After login url looks like this. I removed some characters from those long values like state. If this helps anything. https://localhost:44369/Account/Register?isExternalLogin=True&externalLoginAuthSchema=AzureOpenId&returnUrl=%2Fconnect%2Fauthorize%3Fresponse_type%3Dcode%26client_id%3DSCM_App%26state%3DQmRYxUmlDVEhQ;%25252Fdashboard%26redirect_uri%3Dhttp%253A%252F%252Flocalhost%253A4200%252F%26scope%3Dopenid%2520offline_access%2520SCM%26code_challenge%3D4vcFgDJfIZgrYbPec%26code_challenge_method%3DS256%26nonce%3DQmRKTG9UYxUmlDVEhQ%26culture%3Dfi-FI%26ui-culture%3Dfi-FI%26returnUrl%3D%252Fdashboard
Forget to give you my ConfigureServices code. It is quite same as you suggested and what there was earlier.
context.Services.AddOptions()
.ConfigureOptions<AzureEntraIdTenantOptionsProvider>();
var authenticationBuilder = context.Services.AddAuthentication();
authenticationBuilder.AddOpenIdConnect("AzureOpenId", "Azure AD", options =>
{
options.Authority = "https://login.microsoftonline.com/" + configuration["AzureAd:TenantId"] + "/v2.0/";
options.ClientId = configuration["AzureAd:ClientId"];
options.ResponseType = OpenIdConnectResponseType.CodeIdToken;
options.CallbackPath = configuration["AzureAd:CallbackPath"];
options.ClientSecret = configuration["AzureAd:ClientSecret"];
options.RequireHttpsMetadata = false;
options.SaveTokens = true;
options.GetClaimsFromUserInfoEndpoint = true;
options.Scope.Add("email");
options.ClaimActions.MapJsonKey(ClaimTypes.NameIdentifier, "sub");
});
And here is out provider. We assumed that currentTenant is set here so our global ef filter should work here and tenantId parameter is added to query automaticly.
public class AzureEntraIdTenantOptionsProvider : IConfigureOptions<OpenIdConnectOptions>, ITransientDependency
{
private readonly IServiceProvider _serviceProvider;
public AzureEntraIdTenantOptionsProvider(IServiceProvider serviceProvider)
{
_serviceProvider = serviceProvider;
}
public void Configure(OpenIdConnectOptions options)
{
ISaasTenantIdentityProviderSettingsRepository saasTenantIdentityProviderSettingsService = _serviceProvider.GetRequiredService<ISaasTenantIdentityProviderSettingsRepository>();
var azureAdSettings = saasTenantIdentityProviderSettingsService.GetIdentityProviderSettings(IdentityProviderType.ENTRA_ID).Result;
var deserializedSettings = azureAdSettings?.Setting != null
? JsonConvert.DeserializeObject<AzureEntraIdSetting>(azureAdSettings?.Setting)
: null;
if (azureAdSettings != null && deserializedSettings.IsEnabled)
{
options.ClientId = deserializedSettings.ClientId;
options.ClientSecret = deserializedSettings.ClientSecret;
options.Authority = $"https://login.microsoftonline.com/{deserializedSettings.AzureTenantId}/v2.0";
options.ResponseType = OpenIdConnectResponseType.CodeIdToken;
options.SaveTokens = true;
options.GetClaimsFromUserInfoEndpoint = true;
options.CallbackPath = "/signin-azure";
options.RequireHttpsMetadata = false;
options.Scope.Add("email");
options.ClaimActions.MapJsonKey(ClaimTypes.NameIdentifier, "sub");
}
else
{
// Or configure default behavior
throw new UserFriendlyException("Azure Ad is not configured for you");
}
}
}
Hello, I'm collegue of LW and started to implement this feature. Now I have several problems for which I need your help. First problem is about AzureEntraIdTenantOptionsProvider. I managed to implement it and when debuging I noticed that it goes to constructor of provider but never goes to Configure method so authserver is not even trying to get dynamic OpenIdConnectOptions from provider and uses what was in appsettings.json.
Other problem is when trying to use Azure AD button. I managed to configure Entra Id login settings to our appsetting.json from where AddOpenIdConnect is getting default settings. And it redirects to microsoft site and after awile it goes back to register page as seen below. Is this normal routine when using external identity provider? How can I get Register button enable if it is required to get external login to work.
And last notice is that I only get login to work this much when I se this setting to None. It doesn't feel right thing to do. But is there any other way?
options.MinimumSameSitePolicy = Microsoft.AspNetCore.Http.SameSiteMode.None;
Collegue found that these were needed although we were not doing over module joins. [ReplaceDbContext(typeof(IForecastingDbContext))] and
modelBuilder.ConfigureForecasting();
So after all it was same problem as others have. I didn't just remember that our background process manager has own db context.
I will continue with solution I have with configurations. I will continue to listen this thread if you decide something.
No. My goal is to get verification link to work. Currently I need to add MVC settings to get it working even verification mail send is done via Angular front. In angular front there is (In your code)logic which check if responseType is code then use MVC and otherwise use Angular settings. I was guided to override that part of code to always use Angular settings. It seems to me to be little overkill. So maybe I just add those MVC settings for email verification which are mentioned eralier in this issue.
options.Applications["MVC"].Urls[AccountUrlNames.EmailConfirmation] =
"account/email-confirmation";
Default value is MVC style link which is not working for Angular front. Initial problem was that there was no domain part in link. that was solved by adding:
options.Applications["MVC"].RootUrl = configuration["App:SelfUrl"];
So after all for me it seems that my initial fix to add those settings to MVC side is easiest way. Maybe not most correct way but it works. Replacing that much of code instead seems overkill. Is our setup somehow wrong or weird or why we have this problem? Or is it actually problem in your code and you will fix it on later versions? Is the problem with using angular and having separate Auth server? Does this combo make that problem?
About thre replacement mechanic. I found this guide but what should be key for PersonalSettingsEmailComponent? https://abp.io/docs/latest/framework/ui/angular/component-replacement#how-to-replace-a-component
Yep that works. thanks. I will now test how it works in our test environment.