Jordi van Dijk
Jordi van Dijk

Reputation: 1

System.InvalidOperationException: Scheme already exists: Identity.Application when using [auhtorize]

I use custom identity objects in my .net core mvc api. This works fine with creating users/roles etc. But as soon as i ad an [authorize] tag to one of my controller the following message shows.

> System.InvalidOperationException: Scheme already exists: Identity.Application
   at Microsoft.AspNetCore.Authentication.AuthenticationOptions.AddScheme(String name, Action`1 configureBuilder)
   at Microsoft.AspNetCore.Authentication.AuthenticationBuilder.<>c__DisplayClass4_0`2.<AddSchemeHelper>b__0(AuthenticationOptions o)
   at Microsoft.Extensions.Options.ConfigureNamedOptions`1.Configure(String name, TOptions options)
   at Microsoft.Extensions.Options.OptionsFactory`1.Create(String name)
   at Microsoft.Extensions.Options.OptionsManager`1.<>c__DisplayClass5_0.<Get>b__0()
   at System.Lazy`1.ViaFactory(LazyThreadSafetyMode mode)
--- End of stack trace from previous location where exception was thrown ---
   at System.Lazy`1.CreateValue()
   at Microsoft.AspNetCore.Authentication.AuthenticationSchemeProvider..ctor(IOptions`1 options, IDictionary`2 schemes)
   at Microsoft.AspNetCore.Authentication.AuthenticationSchemeProvider..ctor(IOptions`1 options)
   at System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor, Boolean wrapExceptions)
   at System.Reflection.RuntimeConstructorInfo.Invoke(BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitConstructor(ConstructorCallSite constructorCallSite, RuntimeResolverContext context)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSiteMain(ServiceCallSite callSite, TArgument argument)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitCache(ServiceCallSite callSite, RuntimeResolverContext context, ServiceProviderEngineScope serviceProviderEngine, RuntimeResolverLock lockType)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitRootCache(ServiceCallSite singletonCallSite, RuntimeResolverContext context)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(ServiceCallSite callSite, TArgument argument)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitConstructor(ConstructorCallSite constructorCallSite, RuntimeResolverContext context)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSiteMain(ServiceCallSite callSite, TArgument argument)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitCache(ServiceCallSite callSite, RuntimeResolverContext context, ServiceProviderEngineScope serviceProviderEngine, RuntimeResolverLock lockType)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitScopeCache(ServiceCallSite singletonCallSite, RuntimeResolverContext context)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(ServiceCallSite callSite, TArgument argument)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.Resolve(ServiceCallSite callSite, ServiceProviderEngineScope scope)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.DynamicServiceProviderEngine.<>c__DisplayClass1_0.<RealizeService>b__0(ServiceProviderEngineScope scope)
   at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(IServiceProvider provider, Type serviceType)
   at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService[T](IServiceProvider provider)
   at Microsoft.AspNetCore.Authentication.AuthenticationHttpContextExtensions.ChallengeAsync(HttpContext context, String scheme, AuthenticationProperties properties)
   at Microsoft.AspNetCore.Authentication.AuthenticationHttpContextExtensions.ChallengeAsync(HttpContext context, AuthenticationProperties properties)
   at Microsoft.AspNetCore.Mvc.ChallengeResult.ExecuteResultAsync(ActionContext context)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAlwaysRunResultFilters>g__Awaited|26_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeFilterPipelineAsync>g__Awaited|19_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Logged|17_1(ResourceInvoker invoker)
   at Microsoft.AspNetCore.Builder.RouterMiddleware.Invoke(HttpContext httpContext)
   at AspNetCoreRateLimit.RateLimitMiddleware`1.Invoke(HttpContext context)
   at Swashbuckle.AspNetCore.SwaggerUI.SwaggerUIMiddleware.Invoke(HttpContext httpContext)
   at Swashbuckle.AspNetCore.Swagger.SwaggerMiddleware.Invoke(HttpContext httpContext, ISwaggerProvider swaggerProvider)
   at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)

I am not calling the identity twice in my code, it runs fine until it hits a endpoint that needs authorization.

my code is as follows :

startup.cs

      {
          public Startup(IConfiguration configuration) => Configuration = configuration;
  
          public IConfiguration Configuration
          {
              get;
          }
  
          // This method gets called by the runtime. Use this method to add services to the container. 
          public void ConfigureServices(IServiceCollection services)
          {
              services.AddIdentity<AspNetUser, AspNetRoles>()
                          .AddEntityFrameworkStores<DbApiContext>()
                          .AddDefaultTokenProviders();
  
              services.InstallServicesInAssembly(Configuration);
              services.AddAutoMapper(typeof(Startup));
              services.AddOptions();
              services.AddControllers().AddNewtonsoftJson(options =>
                  options.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore
              );
  
  
  
  
              services.AddHttpsRedirection(options =>
              {
                  options.RedirectStatusCode = StatusCodes.Status307TemporaryRedirect;
                  options.HttpsPort = 443;
              });
  
              services.Configure<FmeSettings>(Configuration.GetSection("FmeSettings"));
          }
  
          // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. 
          public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
          {
              if (env.IsDevelopment())
              {
                  app.UseDeveloperExceptionPage();
              }
              else
              {
                  app.UseHsts();
              }
  
              app.UseHttpsRedirection();
              app.UseStaticFiles();
              app.UseRouting();
  
              Options.SwaggerOptions swaggerOptions = new Options.SwaggerOptions();
              Configuration.GetSection(nameof(Options.SwaggerOptions)).Bind(swaggerOptions);
  
  
  
              app.UseSwagger(option => option.RouteTemplate = swaggerOptions.JsonRoute);
  
              app.UseSwaggerUI(x =>
              {
                  x.SwaggerEndpoint("../v1/swagger.json", swaggerOptions.Description);
                  x.RoutePrefix = "";
                  x.DocumentTitle = "Tercera API";
                  x.InjectStylesheet("/swagger-ui/custom.css");
                  x.InjectJavascript("/swagger-ui/custom.js", "text/javascript");
              });
  
              app.UseClientRateLimiting();
  #pragma warning disable MVC1005 // Cannot use UseMvc with Endpoint Routing. 
              app.UseMvc();
  #pragma warning restore MVC1005 // Cannot use UseMvc with Endpoint Routing. 
          }
      }
  }```


fucntion I call when i get this messaga:

```         [HttpGet(ApiRoutes.Users.ReadUsers)]
      [Authorize(Roles = "PROJECTLEIDER, BALIEMEDEWERKER")]
      public async Task<ActionResult<List<AspNetUser>>> GetAllUsersAsync()
      {
          try
          {
              List<AspNetUser> users = await this._userManager.Users.ToListAsync();
              return users;
          }
          catch (Exception e)
          {
              return BadRequest();
          }
      } ```

Upvotes: 0

Views: 4732

Answers (3)

dampee
dampee

Reputation: 3447

For me it was the file /Areas/Identity/IdentityHostingStartup.cs which was created after scaffolding the asp.net Identity UI views.

This contained services.AddDefaultIdentity<ApplicationUser>(options => ...).

So do not only search for .AddIdentity in your project but also for .AddDefaultIdentity

Upvotes: 2

Md Samrat Akbor
Md Samrat Akbor

Reputation: 75

I've got a similar bug but in my case, I've injected "service.AddIdentity()" more than once, so this error shows that the problem is solved when I remove one.

services.AddIdentity<ApplicationUser, IdentityRole>(options =>
            {
                options.Password.RequireDigit = identityDefaultOptions.PasswordRequireDigit;
                options.Password.RequiredLength = identityDefaultOptions.PasswordRequiredLength;
                options.Password.RequireNonAlphanumeric = identityDefaultOptions.PasswordRequireNonAlphanumeric;
                options.Password.RequireUppercase = identityDefaultOptions.PasswordRequireUppercase;
                options.Password.RequireLowercase = identityDefaultOptions.PasswordRequireLowercase;
                options.Password.RequiredUniqueChars = identityDefaultOptions.PasswordRequiredUniqueChars;
                // Lockout settings
                options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromMinutes(identityDefaultOptions.LockoutDefaultLockoutTimeSpanInMinutes); options.Lockout.MaxFailedAccessAttempts = identityDefaultOptions.LockoutMaxFailedAccessAttempts;
                options.Lockout.AllowedForNewUsers = identityDefaultOptions.LockoutAllowedForNewUsers;// User settings
                options.User.RequireUniqueEmail = identityDefaultOptions.UserRequireUniqueEmail;// email confirmation require
options.SignIn.RequireConfirmedEmail = identityDefaultOptions.SignInRequireConfirmedEmail;
            }).AddEntityFrameworkStores<ApplicationDbContext>().AddDefaultTokenProviders();

Upvotes: 3

Jordi van Dijk
Jordi van Dijk

Reputation: 1

I've fixed it after reading the docs (I know should have done that in the first place).

A colleague of me had created a DbInstalller class where he declared the identity store and added the Identity. I Did not know this existed. this was the causing the problem for me.

Upvotes: 0

Related Questions