我已经设置了IdentityServer4,一个受保护的API(核心)项目以及各种客户端。匿名访问的客户端页面使用资源所有者流来访问API,并且需要登录的客户端页面使用用户凭证。一切正常。我的问题是,现在我想添加受保护的注册API方法。
新的注册方法要求API项目使用AspNetIdentity。具体来说,他们使用Identity的UserManager对象无法实例化,除非我将此代码添加到Startup.ConfigureServices中。
services.AddIdentity<ApplicationUser, IdentityRole>()
.AddEntityFrameworkStores<ApplicationDbContext>()
.AddDefaultTokenProviders();
但是添加此代码会破坏常规的IDServer4 Bearer身份验证。现在,API控制器上的Authorize标签将请求者发送到登录页面。有没有一种方法可以在没有上述代码的情况下创建好的userManager组件,从而使身份验证不起作用?
没有上面的代码,我得到以下错误:
Unable to resolve service for type 'Microsoft.AspNetCore.Identity.UserManager`1[TestAPICore.Models.ApplicationUser]' while attempting to activate *controller*
这是我的ConfigureServices方法:
public void ConfigureServices(IServiceCollection services)
{
services.Configure<AppSettings>(Configuration.GetSection("AppSettings"));
services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
services.AddAuthentication("Bearer")
.AddIdentityServerAuthentication(options =>
{
options.Authority = "http://localhost:5000";
options.RequireHttpsMetadata = false;
options.ApiName = "api1";
});
services.AddCors(o => o.AddPolicy("MyPolicy", builder =>
{
builder.AllowAnyOrigin()
.AllowAnyMethod()
.AllowAnyHeader();
}));
//// ADDING THIS CAUSES API requests to send back the login screen
//services.AddIdentity<ApplicationUser, IdentityRole>()
// .AddEntityFrameworkStores<ApplicationDbContext>()
// .AddDefaultTokenProviders();
// Add application services.
services.AddTransient<IEmailSender, EmailSender>();
services.AddMvc();
}
这项工作的想法吗?
更新:
要了解更多信息,似乎要调用services.AddIdentityCore<ApplicationUser>(cfg => {});
。我在.AddAuthentication
代码之前和之后都尝试过,但是仍然收到几乎相同的错误:
System.InvalidOperationException: Unable to resolve service for type 'Microsoft.AspNetCore.Identity.IUserStore`1[TestAPICore.Models.ApplicationUser]' while attempting to activate 'Microsoft.AspNetCore.Identity.UserManager`1[TestAPICore.Models.ApplicationUser]'.
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteFactory.CreateArgumentCallSites...
...这稍有不同,因为它不再引用我的控制器。
已解决!
这是起作用的...
IdentityBuilder builder = services.AddIdentityCore<ApplicationUser>(options => { });
builder = new IdentityBuilder(builder.UserType, typeof(IdentityRole), builder.Services);
builder.AddEntityFrameworkStores<ApplicationDbContext>();
谢谢,柯克,向我指出了正确的方向!
答案 0 :(得分:2)
为了让其他人受益,这是我用于API项目的整个ConfigureServices方法,该方法可以管理用户,但仍可以通过IdentityServer进行身份验证:
public void ConfigureServices(IServiceCollection services)
{
services.Configure<AppSettings>(Configuration.GetSection("AppSettings"));
services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
services.AddAuthentication("Bearer")
.AddIdentityServerAuthentication(options =>
{
options.Authority = "http://localhost:5000";
options.RequireHttpsMetadata = false;
options.ApiName = "api1";
});
services.AddCors(o => o.AddPolicy("MyPolicy", bld =>
{
bld.AllowAnyOrigin()
.AllowAnyMethod()
.AllowAnyHeader();
}));
// *** The Fix ***
IdentityBuilder builder = services.AddIdentityCore<ApplicationUser>(options => { });
builder = new IdentityBuilder(builder.UserType, typeof(IdentityRole), builder.Services);
builder.AddEntityFrameworkStores<ApplicationDbContext>();
// Add application services.
services.AddTransient<IEmailSender, EmailSender>();
services.AddMvc();
}