c# - 使用个人用户帐户将 IdentityServer 添加到 Razor 应用程序 - 发现多个 DbContext
问题描述
我创建了一个将身份验证设置为个人用户帐户的 Razor Pages 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
推荐阅读
- android - 如何在 RecyclerView 中突出显示并自动单击最近添加的项目
- javascript - 为什么我在 bouncycastle 中生成的 SHA512-ECDSA 密钥在 jsrsasign 中不匹配?
- css - 使用 mat-form-field 更改特定字段中的背景颜色
- python - Podio - 504 服务器错误:网址的网关超时
- reactjs - 在 Reactjs 和 Tailwind CSS 中创建默认缩略图
- java - 我使用 itextpdf 在 pdf 中生成了一些注释,但是当 acrobat reader 打开 pdf 时无法搜索到注释
- kubectl - 未找到 eksctl 管理的 CloudFormation 堆栈 > 错误:为集群加载 VPC 规范,
- python - 我如何在 Atom 中获取 python Discord 模块?
- javascript - 如何将 DATA 变量从 JS 导入新的 VUE3 组件,然后在 html DOM 中打印数据?:)
- docker - 云 NAT 配置失败?