繁体   English   中英

使用个人用户帐户将 IdentityServer 添加到 Razor 应用程序 - 找到多个 DbContext

[英]Adding IdentityServer to Razor app with Individual User Accounts - More than one DbContext was found

我创建了一个 Razor 页面 Web 应用程序,身份验证设置为个人用户帐户。

然后我尝试将 IdentityServer4 添加到 Startup,这样我也可以支持 {{base_url}}/connect/token 来获取 access_token。

当我调用 {{base_url}}/connect/token 时,出现 500 错误,控制台日志显示 Clients 表不存在。

然后我尝试执行添加迁移,但出现错误:找到多个 DbContext。

下面是我的 Startup.cs 文件...这里有什么我应该修复的,这样就没有(看似)两个 DbContexts 了吗?

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Hosting;
using Microsoft.EntityFrameworkCore;
using MyIdentityServer.Data;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using MyIdentityServer.Entities;
using MyIdentityServer.Services;
using Microsoft.AspNetCore.Identity.UI.Services;
using MyIdentityServer.IdentityServer;
using System.Reflection;

namespace MyIdentityServer
{
    public class Startup
    {
        public Startup(IWebHostEnvironment environment, IConfiguration configuration)
        {
            Environment = environment;
            Configuration = configuration;
        }

        public IWebHostEnvironment Environment { get; }
        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)
        {
            var connectionString = Configuration.GetConnectionString("DefaultConnection");
            string migrationsAssembly = typeof(Startup).GetTypeInfo().Assembly.GetName().Name;

            services.AddDbContext<ApplicationDbContext>(options =>
                options.UseSqlServer(connectionString));

            services.AddIdentity<ApplicationUser, IdentityRole>(config =>
            {
                config.SignIn.RequireConfirmedEmail = false;
            })
                .AddEntityFrameworkStores<ApplicationDbContext>()
                .AddDefaultTokenProviders();

            var builder = services.AddIdentityServer(options =>
            {
                options.Events.RaiseErrorEvents = true;
                options.Events.RaiseInformationEvents = true;
                options.Events.RaiseFailureEvents = true;
                options.Events.RaiseSuccessEvents = true;
                options.EmitStaticAudienceClaim = true;
            })
            // .AddInMemoryPersistedGrants()
            /*
            .AddInMemoryIdentityResources(IdentityServerConfig.IdentityResources)
            .AddInMemoryApiScopes(IdentityServerConfig.ApiScopes)
            .AddInMemoryClients(IdentityServerConfig.Clients)
            */
            .AddConfigurationStore(options =>
            {
                options.ConfigureDbContext = builder => builder.UseSqlServer(connectionString, sql => sql.MigrationsAssembly(migrationsAssembly));
            })
            .AddOperationalStore(options =>
            {
                options.ConfigureDbContext = builder => builder.UseSqlServer(connectionString, sql => sql.MigrationsAssembly(migrationsAssembly));                            
                options.EnableTokenCleanup = true; // this enables automatic token cleanup. this is optional. 
                options.TokenCleanupInterval = 30;
            })
            .AddAspNetIdentity<ApplicationUser>();

            services.Configure<SmtpSettings>(Configuration.GetSection("SmtpSettings"));
            services.AddTransient<IEmailSender, AuthMessageSender>();
            services.AddTransient<ISmsSender, AuthMessageSender>();
            services.AddScoped<IDecryptCookieService, DecryptCookieService>();
        
            services.AddAuthentication()
              .AddFacebook(facebookOptions =>
              {
                  facebookOptions.AppId = Configuration["Authentication:Facebook:AppId"];
                  facebookOptions.AppSecret = Configuration["Authentication:Facebook:AppSecret"];
                  facebookOptions.AccessDeniedPath = "/AccessDeniedPathInfo";
              })
              .AddTwitter(twitterOptions =>
              {
                  twitterOptions.ConsumerKey = Configuration["Authentication:Twitter:ConsumerAPIKey"];
                  twitterOptions.ConsumerSecret = Configuration["Authentication:Twitter:ConsumerSecret"];
                  twitterOptions.RetrieveUserDetails = true;
              });

            services.AddControllersWithViews();
            services.AddRazorPages();
        }

        // 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();
                app.UseDatabaseErrorPage();
            }
            else
            {
                app.UseExceptionHandler("/Error");
                // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
                app.UseHsts();
            }

            app.UseHttpsRedirection();
            app.UseStaticFiles();

            app.UseRouting();

            app.UseIdentityServer();

            app.UseAuthentication();
            app.UseAuthorization(); // <- allows the use of [Authorize] on controllers and action

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllers();
                endpoints.MapRazorPages();
            });
        }
    }
}

另外,在数据文件夹中:

using System;
using System.Collections.Generic;
using System.Text;
using MyIdentityServer.IdentityServer;
using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore;

namespace MyIdentityServer.Data
{
    public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
    {
        public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
            : base(options)
        {
        }
    }
}

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Identity;

namespace MyIdentityServer.IdentityServer
{
    public class ApplicationUser : IdentityUser
    {
    }
}

好的...所以事实证明 IdentityServer4(当按上述方式实现时)确实添加了两个额外的上下文:

// add-migration -context ApplicationDbContext
// add-migration -context PersistedGrantDbContext
// add-migration -context ConfigurationDbContext

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM