我创建了一个Asp。Net Core 2.1 Web Api,使用Identity Server 4进行承载令牌身份验证。我有两个数据库上下文,一个用于标识,另一个用于自定义应用程序的数据访问。我希望能够在我的控制器中使用依赖注入,在我的WebApi中使用UserManager和UserStore。
问题是,一旦我添加了DI的"相关"代码,我的控制器方法就会抛出302,并试图将我重定向到登录URL。这就像我的承载身份验证被覆盖了一样。下面是我的Startup.cs的样子。你有什么想法吗?
public void ConfigureServices(IServiceCollection services)
{
string connectionString = Configuration.GetConnectionString("DefaultConnection");
var migrationsAssembly = typeof(Startup).GetTypeInfo().Assembly.GetName().Name;
services.AddDbContext<CustomContext>(options =>
options.UseSqlServer(connectionString));
// start of the stuff that should add the usermanager and userstore
services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(connectionString));
services.AddIdentity<ApplicationUser, IdentityRole>()
.AddEntityFrameworkStores<ApplicationDbContext>()
.AddDefaultTokenProviders();
// end of the stuff
services.AddMvcCore()
.AddAuthorization()
.AddJsonFormatters();
services.AddAuthentication("Bearer")
.AddIdentityServerAuthentication(options =>
{
options.Authority = "http://authenticate.com";
options.RequireHttpsMetadata = false;
options.ApiName = "api1";
});
services.AddCors(options =>
{
// this defines a CORS policy called "default"
options.AddPolicy("default", policy =>
{
policy.AllowAnyOrigin()
.AllowAnyHeader()
.AllowAnyMethod()
.AllowCredentials();
});
});
}
public void Configure(IApplicationBuilder app)
{
app.UseAuthentication();
app.UseCors("default");
app.UseMvc();
}
控制器看起来像这样:
public class PlayerController : BaseApiController
{
private readonly UserManager<ApplicationUser> userManager;
public PlayerController(UserManager<ApplicationUser> _userManager)
{
userManager = _userManager;
}
.....
}
使用BaseApiController如下:
[Route("api/[controller]")]
[Authorize]
public class BaseApiController : Controller
{
...
}
services.AddIdentity<TUser>()
添加一个";不必要的";身份验证配置,因为您已经有了来自services.AddAuthentication("Bearer").AddIdentityServerAuthentication()
配置的承载方案。请查看下面的AddIdentity()
代码。请注意,还添加了多少个方案(包括cookie方案(。
public static IdentityBuilder AddIdentity<TUser, TRole>(
this IServiceCollection services,
Action<IdentityOptions> setupAction)
where TUser : class
where TRole : class
{
// Services used by identity
services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = IdentityConstants.ApplicationScheme;
options.DefaultChallengeScheme = IdentityConstants.ApplicationScheme;
options.DefaultSignInScheme = IdentityConstants.ExternalScheme;
})
.AddCookie(IdentityConstants.ApplicationScheme, o =>
{
o.LoginPath = new PathString("/Account/Login");
o.Events = new CookieAuthenticationEvents
{
OnValidatePrincipal = SecurityStampValidator.ValidatePrincipalAsync
};
})
.AddCookie(IdentityConstants.ExternalScheme, o =>
{
o.Cookie.Name = IdentityConstants.ExternalScheme;
o.ExpireTimeSpan = TimeSpan.FromMinutes(5);
})
.AddCookie(IdentityConstants.TwoFactorRememberMeScheme, o =>
{
o.Cookie.Name = IdentityConstants.TwoFactorRememberMeScheme;
o.Events = new CookieAuthenticationEvents
{
OnValidatePrincipal = SecurityStampValidator.ValidateAsync<ITwoFactorSecurityStampValidator>
};
})
.AddCookie(IdentityConstants.TwoFactorUserIdScheme, o =>
{
o.Cookie.Name = IdentityConstants.TwoFactorUserIdScheme;
o.ExpireTimeSpan = TimeSpan.FromMinutes(5);
});
// cut for brevity
return new IdentityBuilder(typeof(TUser), typeof(TRole), services);
}
你不需要那个。您需要的是:
services.AddIdentityCore<TUser>()
其不添加另一个认证配置。