Недавно я возобновил работу над проектом, который бездействовал в течение года. Он использовал Angular на AspNet Core 1.1 и использовал раннюю версию OpenIddict 1.0. Он был разработан с использованием VS2017.
Я обновил VS2017 до последней версии (15.7.5), но проект не скомпилировался, и когда я исправил ошибки компиляции, он не запустился. Так что в конце концов я укусил пулю и решил обновить проект до Asp Net Core 2.1 и использовать последнюю версию OpenIddict. У меня есть проект, поэтому он компилируется, но при запуске выдает ошибку в заголовке, а именно "InvalidOperationException: Scheme уже существует: Bearer"
Я не вижу, что не так. Я понимаю, что где-то добавляется вторая схема под названием «Носитель», но не могу понять где. Я прилагаю ниже мой Startup.cs полностью.
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, но явно где-то ошибся.
Полная трассировка стека выглядит следующим образом:
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