InvalidOperationException: Scheme already exists: Bearer
我最近恢复了一个已经hibernate了一年的项目的工作。它在AspNet Core 1.1上使用了Angular,并使用了OpenIddict 1.0的早期版本。它是使用VS2017开发的。
我将VS2017更新到最新版本(15.7.5),但该项目无法编译,并且当我修复编译错误时,它将无法运行。因此,最终我忍受了决定,决定将项目更新为Asp Net Core 2.1,并使用最新版本的OpenIddict。我有项目,因此可以编译,但是在启动时会在标题中给出错误,即" InvalidOperationException:方案已经存在:Bearer"
我看不出有什么问题。我知道在某个地方添加了另一个名为" Bearer"的方案,但我不知道在哪里。我将其完整包含在Startup.cs的下面。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 | using AspNet.Security.OpenIdConnect.Primitives; using Microsoft.AspNetCore.Builder; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using SIAngular.DBContexts; using SIAngular.Models; using SIAngular.Services; using OpenIddict.Abstractions; using System.IdentityModel.Tokens.Jwt; using Microsoft.IdentityModel.Tokens; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Authentication.JwtBearer; namespace SIAngular { public class Startup { public Startup(IHostingEnvironment env) { var builder = new ConfigurationBuilder() .SetBasePath(env.ContentRootPath) .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true) .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true) .AddEnvironmentVariables(); Configuration = builder.Build(); } public IConfiguration Configuration { get; } public void ConfigureServices(IServiceCollection services) { services.AddCors(); services.AddMvc(); services.AddDbContext<ApplicationDbContext>(options => { // Configure the context to use Microsoft SQL Server. options.UseSqlServer(Configuration.GetConnectionString("SqlConnection")); // Register the entity sets needed by OpenIddict. // Note: use the generic overload if you need // to replace the default OpenIddict entities. options.UseOpenIddict(); }); // Register the Identity services. services.AddIdentity<ApplicationUser, IdentityRole>() .AddEntityFrameworkStores<ApplicationDbContext>(); //.AddDefaultTokenProviders(); // Configure Identity to use the same JWT claims as OpenIddict instead // of the legacy WS-Federation claims it uses by default (ClaimTypes), // which saves you from doing the mapping in your authorization controller. services.Configure<IdentityOptions>(options => { options.ClaimsIdentity.UserNameClaimType = OpenIdConnectConstants.Claims.Name; options.ClaimsIdentity.UserIdClaimType = OpenIdConnectConstants.Claims.Subject; options.ClaimsIdentity.RoleClaimType = OpenIdConnectConstants.Claims.Role; }); services.AddOpenIddict() // Register the OpenIddict core services. .AddCore(options => { // Configure OpenIddict to use the Entity Framework Core stores and models. options.UseEntityFrameworkCore() .UseDbContext<ApplicationDbContext>(); }) // Register the OpenIddict server services. .AddServer(options => { // Register the ASP.NET Core MVC services used by OpenIddict. // Note: if you don't call this method, you won't be able to // bind OpenIdConnectRequest or OpenIdConnectResponse parameters. options.UseMvc(); // Enable the token endpoint. options .EnableTokenEndpoint("/connect/token"); options.AcceptAnonymousClients(); options.DisableScopeValidation(); // Note: the Mvc.Client sample only uses the code flow and the password flow, but you // can enable the other flows if you need to support implicit or client credentials. options.AllowPasswordFlow(); // Mark the"email","profile" and"roles" scopes as supported scopes. options.RegisterScopes(OpenIdConnectConstants.Scopes.Email, OpenIdConnectConstants.Scopes.Profile, OpenIddictConstants.Scopes.Roles); // During development, you can disable the HTTPS requirement. options.DisableHttpsRequirement(); // Note: to use JWT access tokens instead of the default // encrypted format, the following lines are required: // options.UseJsonWebTokens(); options.AddEphemeralSigningKey(); }) // Register the OpenIddict validation services. .AddValidation(); JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear(); JwtSecurityTokenHandler.DefaultOutboundClaimTypeMap.Clear(); services.AddAuthentication(o => { o.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme; }) .AddJwtBearer(options => { options.Authority ="http://localhost:53244/"; options.Audience ="resource_server"; options.RequireHttpsMetadata = false; //options.IncludeErrorDetails = true; options.TokenValidationParameters = new TokenValidationParameters { NameClaimType = OpenIdConnectConstants.Claims.Subject, RoleClaimType = OpenIdConnectConstants.Claims.Role }; }); services.AddTransient<IEmailSender, AuthMessageSender>(); services.AddTransient<ISmsSender, AuthMessageSender>(); } public void Configure(IApplicationBuilder app) { app.UseDeveloperExceptionPage(); app.UseAuthentication(); app.UseStaticFiles(); app.UseMvcWithDefaultRoute(); } } } |
有人可以解释一下我在做什么错。我的意图是遵循OpenIddict示例,但显然我在某个地方出错了。
完整的堆栈跟踪如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | System.InvalidOperationException: Scheme already exists: Bearer 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) at System.Lazy`1.ExecutionAndPublication(LazyHelper executionAndPublication, Boolean useDefaultConstructor) at System.Lazy`1.CreateValue() at Microsoft.Extensions.Options.OptionsCache`1.GetOrAdd(String name, Func`1 createOptions) at Microsoft.Extensions.Options.OptionsManager`1.Get(String name) at Microsoft.Extensions.Options.OptionsManager`1.get_Value() at Microsoft.AspNetCore.Authentication.AuthenticationSchemeProvider..ctor(IOptions`1 options, IDictionary`2 schemes) at Microsoft.AspNetCore.Authentication.AuthenticationSchemeProvider..ctor(IOptions`1 options) --- End of stack trace from previous location where exception was thrown --- at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitConstructor(ConstructorCallSite constructorCallSite, ServiceProviderEngineScope scope) at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(IServiceCallSite callSite, TArgument argument) at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitScoped(ScopedCallSite scopedCallSite, ServiceProviderEngineScope scope) at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitSingleton(SingletonCallSite singletonCallSite, ServiceProviderEngineScope scope) at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(IServiceCallSite callSite, TArgument argument) at Microsoft.Extensions.DependencyInjection.ServiceLookup.DynamicServiceProviderEngine.<>c__DisplayClass1_0.<RealizeService>b__0(ServiceProviderEngineScope scope) at Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngine.GetService(Type serviceType, ServiceProviderEngineScope serviceProviderEngineScope) at Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngine.GetService(Type serviceType) at Microsoft.Extensions.DependencyInjection.ServiceProvider.GetService(Type serviceType) at Microsoft.Extensions.Internal.ActivatorUtilities.ConstructorMatcher.CreateInstance(IServiceProvider provider) at Microsoft.Extensions.Internal.ActivatorUtilities.CreateInstance(IServiceProvider provider, Type instanceType, Object[] parameters) at Microsoft.AspNetCore.Builder.UseMiddlewareExtensions.<>c__DisplayClass4_0.<UseMiddleware>b__0(RequestDelegate next) at Microsoft.AspNetCore.Builder.Internal.ApplicationBuilder.Build() at Microsoft.AspNetCore.Hosting.Internal.WebHost.BuildApplication() at Microsoft.AspNetCore.Hosting.Internal.WebHost.StartAsync(CancellationToken cancellationToken) at Microsoft.AspNetCore.Hosting.WebHostExtensions.RunAsync(IWebHost host, CancellationToken token, String shutdownMessage) at Microsoft.AspNetCore.Hosting.WebHostExtensions.RunAsync(IWebHost host, CancellationToken token) at Microsoft.AspNetCore.Hosting.WebHostExtensions.Run(IWebHost host) at SIAngular.Program.Main(String[] args) in C:\\Users\\username\\Documents\\Visual Studio 2017\\Projects\\SIAngular\\Program.cs:line 20 |
我终于找到了答案,这可能对OpenIddict专家是显而易见的,但对临时用户却不然。
由于我使用的是JWT,因此不需要注册OpenIddict服务器选项后的