Base solution for your next web application
Open Closed

Microsoft Outlook connection using Graph #12032


User avatar
0
Bernard created

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)
  • User Avatar
    0
    ismcagdas created
    Support Team

    Hi @Bernard

    What is the problem you are having ?

  • User Avatar
    0
    Bernard created

    Hi I send you detail by email did you receive it ?

  • User Avatar
    0
    ismcagdas created
    Support Team

    Hi @Bernard,

    Have you tried removing the line below ?

    .AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme) Cause issue
    
  • User Avatar
    0
    Bernard created

    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

  • User Avatar
    0
    ismcagdas created
    Support Team

    Hi @Bernard

    I think this issue is resolved, is that correct ?

  • User Avatar
    0
    Bernard created

    Hi

    No, I not able to call AddMicrosoftIdentityWebApp And Openconnect because each uses the same scheme

  • User Avatar
    0
    ismcagdas created
    Support Team
  • User Avatar
    0
    Bernard created

    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&lt;AuthenticationSchemeBuilder&gt; configureBuilder)
        Microsoft.Extensions.Options.OptionsFactory&lt;TOptions&gt;.Create(string name)
        Microsoft.Extensions.Options.UnnamedOptionsManager&lt;TOptions&gt;.get_Value()
        Microsoft.AspNetCore.Authentication.AuthenticationSchemeProvider..ctor(IOptions&lt;AuthenticationOptions&gt; options, IDictionary&lt;string, AuthenticationScheme&gt; schemes)
        lambda_method47(Closure , object[] )
        Castle.Core.Internal.ReflectionUtil.Instantiate(ConstructorInfo ctor, object[] ctorArgs)
        Castle.Core.Internal.ReflectionUtil.Instantiate&lt;TBase&gt;(Type subtypeofTBase, object[] ctorArgs)
        Castle.MicroKernel.ComponentActivator.DefaultComponentActivator.CreateInstanceCore(ConstructorCandidate constructor, object[] arguments, Type implType)
    
  • User Avatar
    0
    Bernard created

    //MS Graph Authentification services.AddAuthentication().AddMicrosoftIdentityWebApp(configuration.GetSection("AzureAd")) .EnableTokenAcquisitionToCallDownstreamApi(configuration.GetValue<string>("DownstreamApi:Scopes")?.Split(' ')) .AddMicrosoftGraph(configuration.GetSection("DownstreamApi")) .AddInMemoryTokenCaches();

    Same issue

  • User Avatar
    0
    Bernard created

    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&lt;JsonClaimMap&gt;();
              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();**
    

    };

  • User Avatar
    0
    Bernard created

    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&lt;ERUDYDbContext&gt;(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&lt;IAppConfigurationAccessor&gt;();
    
         using (var scope = IocManager.CreateScope())
         {
             if (!SkipDbSeed && scope.Resolve&lt;DatabaseCheckHelper&gt;()
                     .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

  • User Avatar
    0
    ismcagdas created
    Support Team

    Hi @Bernard

    Are there any error logs on the server side ? If so, could you share it ?

  • User Avatar
    0
    Bernard created

    Hi What do you mean by server side ?

  • User Avatar
    0
    m.aliozkaya created
    Support Team

    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

  • User Avatar
    0
    m.aliozkaya created
    Support Team

    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

  • User Avatar
    0
    Bernard created

    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&lt;GraphProfileClient&gt;();
      services.AddScoped&lt;GraphEmailClient&gt;();
      //services.AddScoped&lt;GraphCalendarClient&gt;();
      //services.AddScoped&lt;GraphFilesClient&gt;();
    

    };

  • User Avatar
    0
    ismcagdas created
    Support Team

    Hi @Bernard

    Is this resolved ? If not, is it possible to share your project with [email protected] so we can check it ?

    Thanks,

  • User Avatar
    0
    Bernard created

    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

  • User Avatar
    0
    m.aliozkaya created
    Support Team

    Hi @Bernard,

    Can you tell me step by step what I should do to repeat the error?

  • User Avatar
    0
    Bernard created

    Hi I followed this example https://learn.microsoft.com/en-us/training/modules/msgraph-dotnet-core-show-user-emails/1-introduction

  • User Avatar
    0
    m.aliozkaya created
    Support Team

    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?

  • User Avatar
    0
    Bernard created

    Hi,

    You need to go to after login like a tenant with OpenIdConnect

  • User Avatar
    0
    m.aliozkaya created
    Support Team

    Hi @Bernard,

    Please replace this code at Startup.cs line 385

         endpoints.MapFallbackToPage("/_Host");
    

    to

         endpoints.MapRazorPages();
    

    And I also recommend adding Area attribute for ElsaDashboardController

        [Area("App")]
        public class ElsaDashboardController : ERUDYControllerBase
        {
            public IActionResult Index()
            {
                return View();
            }
        }
    

    I hope this helps. If the problem persists, please let us know.

  • User Avatar
    0
    Bernard created

    Hi I think your response is for another ticket #12036 If not I don’t understand your response for MS graph connecting

  • User Avatar
    0
    m.aliozkaya created
    Support Team

    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.