Hi,
I'm trying to implement the ability to read Outlook emails in my application (https://learn.microsoft.com/en-us/training/modules/msgraph-dotnet-core-show-user-emails/1-introduction), but I'm facing a problem because Graph needs to launch the services services // Add support for OpenId authentication .AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme) failed
because an OpendConnectId Schema already exists
I think This code causes issue in Startup.cs
services // 2. Add support for OpenId authentication
.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
.AddMicrosoftIdentityWebApp(Configuration)
How to fix this problem THANKS
32 Answer(s)
-
0
Hi @Bernard
What is the problem you are having ?
-
0
Hi I send you detail by email did you receive it ?
-
0
Hi @Bernard,
Have you tried removing the line below ?
.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme) Cause issue
-
0
Hi,
Any idea ? For having 2 schemes when Connecting ?
I think it should be something like this : https://stackoverflow.com/questions/49694383/use-multiple-jwt-bearer-authentication but for Openconnect
-
0
Hi @Bernard
I think this issue is resolved, is that correct ?
-
0
Hi
No, I not able to call AddMicrosoftIdentityWebApp And Openconnect because each uses the same scheme
-
0
-
0
I follow your example like :
var authenticationBuilder = services.AddAuthentication(); if (bool.Parse(configuration["Authentication:OpenId:IsEnabled"])) { if (bool.Parse(configuration["Authentication:AllowSocialLoginSettingsPerTenant"])) { services.AddSingleton<IOptionsMonitor<OpenIdConnectOptions>, TenantBasedOpenIdConnectOptions>(); } authenticationBuilder.AddOpenIdConnect(options => { options.ClientId = configuration["Authentication:OpenId:ClientId"]; options.Authority = configuration["Authentication:OpenId:Authority"]; options.SignedOutRedirectUri = configuration["App:WebSiteRootAddress"] + "Account/Logout"; options.ResponseType = configuration["Authentication:OpenId:ResponseType"]; options.TokenValidationParameters = new TokenValidationParameters() { ValidateIssuer = bool.Parse(configuration["Authentication:OpenId:ValidateIssuer"]) }; options.Events.OnTokenValidated = context => { var jsonClaimMappings = new List<JsonClaimMap>(); configuration.GetSection("Authentication:OpenId:ClaimsMapping").Bind(jsonClaimMappings); context.AddMappedClaims(jsonClaimMappings); return Task.FromResult(0); }; var clientSecret = configuration["Authentication:OpenId:ClientSecret"]; if (!clientSecret.IsNullOrEmpty()) { options.ClientSecret = clientSecret; } }); }; authenticationBuilder.AddMicrosoftIdentityWebApp(configuration.GetSection("AzureAd")) .EnableTokenAcquisitionToCallDownstreamApi(configuration.GetValue<string>("DownstreamApi:Scopes")?.Split(' ')) .AddMicrosoftGraph(configuration.GetSection("DownstreamApi")) .AddInMemoryTokenCaches();
but it cause issue
An error occurred while starting the application. InvalidOperationException: Scheme already exists: OpenIdConnect
Microsoft.AspNetCore.Authentication.AuthenticationOptions.AddScheme(string name, Action<AuthenticationSchemeBuilder> configureBuilder) ComponentActivatorException: ComponentActivator: could not instantiate Microsoft.AspNetCore.Authentication.AuthenticationSchemeProvider
Castle.MicroKernel.ComponentActivator.DefaultComponentActivator.CreateInstanceCore(ConstructorCandidate constructor, object[] arguments, Type implType)
InvalidOperationException: Scheme already exists: OpenIdConnect Microsoft.AspNetCore.Authentication.AuthenticationOptions.AddScheme(string name, Action<AuthenticationSchemeBuilder> configureBuilder) Microsoft.Extensions.Options.OptionsFactory<TOptions>.Create(string name) Microsoft.Extensions.Options.UnnamedOptionsManager<TOptions>.get_Value() Microsoft.AspNetCore.Authentication.AuthenticationSchemeProvider..ctor(IOptions<AuthenticationOptions> options, IDictionary<string, AuthenticationScheme> schemes) lambda_method47(Closure , object[] ) Castle.Core.Internal.ReflectionUtil.Instantiate(ConstructorInfo ctor, object[] ctorArgs) Castle.Core.Internal.ReflectionUtil.Instantiate<TBase>(Type subtypeofTBase, object[] ctorArgs) Castle.MicroKernel.ComponentActivator.DefaultComponentActivator.CreateInstanceCore(ConstructorCandidate constructor, object[] arguments, Type implType)
-
0
//MS Graph Authentification services.AddAuthentication().AddMicrosoftIdentityWebApp(configuration.GetSection("AzureAd")) .EnableTokenAcquisitionToCallDownstreamApi(configuration.GetValue<string>("DownstreamApi:Scopes")?.Split(' ')) .AddMicrosoftGraph(configuration.GetSection("DownstreamApi")) .AddInMemoryTokenCaches();
Same issue
-
0
Hi Ismail,
I finally found the good way :
// Retrieve required permissions from appsettings string[] initialScopes = configuration.GetValue<string>("DownstreamApi:Scopes")?.Split(' ');
var authenticationBuilder = services.AddAuthentication(options => { options.DefaultScheme = "OpenIdConnect"; options.DefaultChallengeScheme = "AzureAd";
if (bool.Parse(configuration["Authentication:OpenId:IsEnabled"])) { if (bool.Parse(configuration["Authentication:AllowSocialLoginSettingsPerTenant"])) { services.AddSingleton<IOptionsMonitor<OpenIdConnectOptions>, TenantBasedOpenIdConnectOptions>(); }
authenticationBuilder.AddOpenIdConnect(options => { options.ClientId = configuration["Authentication:OpenId:ClientId"]; options.Authority = configuration["Authentication:OpenId:Authority"]; options.SignedOutRedirectUri = configuration["App:WebSiteRootAddress"] + "Account/Logout"; options.ResponseType = configuration["Authentication:OpenId:ResponseType"]; options.TokenValidationParameters = new TokenValidationParameters() { ValidateIssuer = bool.Parse(configuration["Authentication:OpenId:ValidateIssuer"]) }; options.Events.OnTokenValidated = context => { var jsonClaimMappings = new List<JsonClaimMap>(); configuration.GetSection("Authentication:OpenId:ClaimsMapping").Bind(jsonClaimMappings); context.AddMappedClaims(jsonClaimMappings); return Task.FromResult(0); }; var clientSecret = configuration["Authentication:OpenId:ClientSecret"]; if (!clientSecret.IsNullOrEmpty()) { options.ClientSecret = clientSecret; } })**.AddMicrosoftIdentityWebApp(options => { options.ClientId = configuration["Authentication:AzureAd:ClientId"]; options.Instance= configuration["Authentication:AzureAd:Instance"]; options.TenantId = configuration["Authentication:AzureAd:TenantId"]; options.SignedOutRedirectUri = configuration["App:WebSiteRootAddress"] + "Account/Logout"; var clientSecret = configuration["Authentication:AzureAd:ClientSecret"]; if (!clientSecret.IsNullOrEmpty()) { options.ClientSecret = clientSecret; } }, null, "AzureAd") .EnableTokenAcquisitionToCallDownstreamApi(initialScopes) .AddMicrosoftGraph(configuration.GetSection("DownstreamApi")) .AddInMemoryTokenCaches();**
};
-
0
Hi,
The OpenconnectId and Microsoft graph connection seems to work well now. But I'm facing another issue now. When I want to view emails I am systemically redirected by this method which seems to pose an issue.
ERUDYEntityFrameworkCoreModule
[DependsOn( typeof(AbpZeroCoreEntityFrameworkCoreModule), typeof(ERUDYCoreModule) )] public class ERUDYEntityFrameworkCoreModule : AbpModule { /* Used it tests to skip DbContext registration, in order to use in-memory database of EF Core */ public bool SkipDbContextRegistration { get; set; }
public bool SkipDbSeed { get; set; } public override void PreInitialize() { if (!SkipDbContextRegistration) { Configuration.Modules.AbpEfCore().AddDbContext<ERUDYDbContext>(options => { if (options.ExistingConnection != null) { ERUDYDbContextConfigurer.Configure(options.DbContextOptions, options.ExistingConnection); } else { ERUDYDbContextConfigurer.Configure(options.DbContextOptions, options.ConnectionString); } }); } // Set this setting to true for enabling entity history. Configuration.EntityHistory.IsEnabled = false; // Uncomment below line to write change logs for the entities below: // Configuration.EntityHistory.Selectors.Add("ERUDYEntities", EntityHistoryHelper.TrackedTypes); // Configuration.CustomConfigProviders.Add(new EntityHistoryConfigProvider(Configuration)); } public override void Initialize() { IocManager.RegisterAssemblyByConvention(typeof(ERUDYEntityFrameworkCoreModule).GetAssembly()); } public override void PostInitialize() { var configurationAccessor = IocManager.Resolve<IAppConfigurationAccessor>(); using (var scope = IocManager.CreateScope()) { if (!SkipDbSeed && scope.Resolve<DatabaseCheckHelper>() .Exist(configurationAccessor.Configuration["ConnectionStrings:Default"])) { SeedHelper.SeedHostDb(IocManager); } } }
}
And the resut email display is :
Have you an idea of what causes this issue ?
Thks very much
-
0
Hi @Bernard
Are there any error logs on the server side ? If so, could you share it ?
-
0
Hi What do you mean by server side ?
-
0
Hi @Bernard,
Can you repeat the error and send us the error log that occurred at that time?
If you are using an Angular project it is located in:
*.Host > App_Data > Logs
other way it is located in*.Mvc> App_Data > Logs
-
0
Hi @Bernard,
When I examine the logs, I see they have the same error. Can you try setting the authentication scope where you use the code, like the document?
https://github.com/AzureAD/microsoft-identity-web/wiki/multiple-authentication-schemes
-
0
Hi,
Same issue with this code :
if (bool.Parse(configuration["Authentication:OpenId:IsEnabled"])) { //if (bool.Parse(configuration["Authentication:AllowSocialLoginSettingsPerTenant"])) //{ // services.AddSingleton<IOptionsMonitor<OpenIdConnectOptions>, TenantBasedOpenIdConnectOptions>(); //}
services // Add support for OpenId authentication .AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme) .AddMicrosoftIdentityWebApp(configuration, "Authentication:AzureAd") .EnableTokenAcquisitionToCallDownstreamApi(initialScopes) .AddMicrosoftGraph(configuration.GetSection("Authentication:DownstreamApi")) .AddInMemoryTokenCaches(); // Require an authenticated user //services.AddControllersWithViews(options => //{ // var policy = new AuthorizationPolicyBuilder() // .RequireAuthenticatedUser() // .Build(); // options.Filters.Add(new AuthorizeFilter(policy)); //}); //services // // Add Razor Pages support // .AddRazorPages() // // Add Microsoft Identity UI pages that provide user // .AddMicrosoftIdentityUI(); services.AddScoped<GraphProfileClient>(); services.AddScoped<GraphEmailClient>(); //services.AddScoped<GraphCalendarClient>(); //services.AddScoped<GraphFilesClient>();
};
-
0
Hi @Bernard
Is this resolved ? If not, is it possible to share your project with [email protected] so we can check it ?
Thanks,
-
0
Hi,
Thank you for your help, I really appreciate it As the file is large, I will send it to you via Wetransfer.
https://we.tl/t-mXXIpSAVOT
Good luck
-
0
Hi @Bernard,
Can you tell me step by step what I should do to repeat the error?
-
0
Hi I followed this example https://learn.microsoft.com/en-us/training/modules/msgraph-dotnet-core-show-user-emails/1-introduction
-
0
Hi @Bernard
I downloaded and ran the application, and I did not encounter any errors. I have no idea where the error is or how it occurred. Can you tell me which page I need to open and where I need to click so that I can see the error you saw in the logs?
-
0
-
0
Hi @Bernard,
Please replace this code at
Startup.cs
line 385endpoints.MapFallbackToPage("/_Host");
to
endpoints.MapRazorPages();
And I also recommend adding
Area
attribute forElsaDashboardController
[Area("App")] public class ElsaDashboardController : ERUDYControllerBase { public IActionResult Index() { return View(); } }
I hope this helps. If the problem persists, please let us know.
-
0
Hi @Bernard,
The reason why the mail page was not working was related to this and now the mail page should be working. I will take a look for js issues about Elsa.