GPW*_*GPW 18 jwt asp.net-identity-2 asp.net-core-webapi
(编辑 - 找到正确的解决方案!见下文)
好的 - 这是我第一次尝试使用.Net Core 2.0和身份验证,虽然我过去曾使用过Web API 2.0,并且在过去几年中对各种MVC和Webforms ASP项目进行了相当广泛的工作.
我正在尝试使用.Net Core创建一个仅限Web API的项目.这将形成多租户应用程序的后端以生成一些报告,因此我需要能够对用户进行身份验证.通常的方法是使用JWT - 首先验证用户生成令牌,然后将其传递给客户端以在每个API请求上使用.将使用EF Core存储和检索数据.
我按照这篇文章找到了这个设置的基本方法,我设法让它工作正常 - 我有一个接受用户名/密码的控制器并返回一个令牌(如果有效),并且一些授权策略设置基于索赔.
我需要的下一件事是实际管理用户/密码/等.我以为我只是使用.Net核心身份,因为我会有很多现成的代码来担心用户/角色,密码等.我使用的是自定义User类和UserRole派生自标准IdentityUser和IdentityRole类的类,但我现在已经恢复到标准的那个.
我遇到的问题是我无法弄清楚如何添加身份并注册所有各种服务(rolemanager,usermanager等)而不会破坏身份验证 - 基本上只要我将此行添加到我的Startup.ConfigureServices类中:
services.AddIdentity<IdentityUser, IdentityRole>()
.AddEntityFrameworkStores<MyContext>();
Run Code Online (Sandbox Code Playgroud)
这一切都出错了,当我收到请求时,我再也看不到任何索赔,所以所有的政策都锁定了,你无法得到任何东西.
如果我没有那些行,那么我最终会遇到与UserManager,RoleManager,UserStore等相关的错误.所有这些都没有注册DI.
那么......如何(如果可能的话)我可以注册身份并正确地将其连接到上下文,但是避免/删除对实际授权机制的任何更改?
我已经在网上看了很多,但是自从.Net Core 1.x以来已经发生了很多变化,所以很多教程等都不再有效了.
我不打算让这个API应用程序拥有任何前端代码,因此我现在不需要对表单或任何内容进行任何cookie身份验证.
编辑
确定,我现在发现在此代码中设置Startup.ConfigureServices()方法中的JWT身份验证:
services.AddAuthentication(
JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
{
>>breakpoint>>> options.TokenValidationParameters =
new TokenValidationParameters
{
ValidateIssuer = true,
ValidateAudience = true,
ValidateLifetime = true,
ValidateIssuerSigningKey = true,
ValidIssuer = "Blah.Blah.Bearer",
ValidAudience = "Blah.Blah.Bearer",
IssuerSigningKey =
JwtSecurityKey.Create("verylongsecretkey")
};
});
Run Code Online (Sandbox Code Playgroud)
如果我在指示的行上放置一个断点(通过">> breakpoint >>>"),那么当我不添加行来添加身份服务时它就会被击中,但是如果我确实添加了这些行,那么它就永远不会被击中.无论在我services.AddIdentity()拨打电话的方法中,都是如此.我知道这只是一个lambda,所以它稍后会被执行,但是有什么方法可以让AddIdentity的东西不设置身份验证,或者让代码立即删除它?我假设在某些时候有一些代码选择不运行Lambda for config我已经在那里设置,因为Identity的东西已经设置了它...
感谢您阅读所有内容,如果你有:)
编辑 - 找到答案
好,我最终发现这个GH问题基本上就是这个问题:https:
//github.com/aspnet/Identity/issues/1376
基本上我必须做的是双重的:
请确保调用services.AddIdentity<IdentityUser, IdentityContext()制成第一
更改呼叫以从以下位置添加身份验证:
services.AddAuthentication(
JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
...
Run Code Online (Sandbox Code Playgroud)
至:
services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(options =>
...
Run Code Online (Sandbox Code Playgroud)
这会令人烦恼地导致cookie被创建,但据我所知,这不会用于身份验证 - 它纯粹是[Authorize(Policy = "Administrator")]在对至少具有或类似设置的控制器/动作的请求上使用承载令牌.
我需要测试更多,如果我发现它不能以某种方式工作,我会尝试回到这里更新.
(已编辑 - 现在提供适当的解决方案作为答案)
GPW*_*GPW 23
我最终把解决方案放在一起,所以在用户总是学习的建议我编辑了我的帖子,我把它作为一个实际答案.
好的,这可以做得很好.首先,您需要使用我在上面的编辑中指出的身份验证选项 - 这很好.然后你需要使用services.AddIdentityCore<TUser>()而不是services.AddIdentity<TUser>().然而,这并没有为角色管理添加大量内容,并且显然缺少适当的构造函数来为其提供您想要使用的角色类型.这意味着在我的情况下我必须这样做:
IdentityBuilder builder = services.AddIdentityCore<IdentityUser>(opt =>
{
opt.Password.RequireDigit = true;
opt.Password.RequiredLength = 8;
opt.Password.RequireNonAlphanumeric = false;
opt.Password.RequireUppercase = true;
opt.Password.RequireLowercase = true;
}
);
builder = new IdentityBuilder(builder.UserType, typeof(IdentityRole), builder.Services);
builder
.AddEntityFrameworkStores<MyContext>();
//.AddDefaultTokenProviders();
builder.AddRoleValidator<RoleValidator<IdentityRole>>();
builder.AddRoleManager<RoleManager<IdentityRole>>();
builder.AddSignInManager<SignInManager<IdentityUser>>();
Run Code Online (Sandbox Code Playgroud)
完成后,接下来要确保在验证用户登录时(在发送令牌之前),确保使用SignInManager方法CheckPasswordSignInAsync而不是 PasswordSignInAsync:
public async Task<IdentityUser> GetUserForLogin(string userName, string password)
{
//find user first...
var user = await _userManager.FindByNameAsync(userName);
if (user == null)
{
return null;
}
//validate password...
var signInResult = await _signInManager.CheckPasswordSignInAsync(user, password, false);
//if password was ok, return this user.
if (signInResult.Succeeded)
{
return user;
}
return null;
}
Run Code Online (Sandbox Code Playgroud)
如果您使用该PasswordSignInAsync方法,那么您将收到运行时错误.没有配置IAuthenticationSignInHandler.
我希望这在某些方面对某人有帮助.
| 归档时间: |
|
| 查看次数: |
5454 次 |
| 最近记录: |