2023-02-15 329
(编辑 – 找到正确的修复!请参阅下文)
确定 – 这是我的第一次尝试.NET Core 2.0和身份验证,尽管我过去已经用Web API 2.0完成了事物,并且在过去几年中的各种MVC和Webforms ASP项目中已经相当广泛地工作了.
我正在尝试使用.NET核心创建一个Web API项目.这将形成一个多租户应用程序的后端,用于生成一些报告,因此我需要能够验证用户.似乎通常的方法是使用JWT – 首先验证用户生成令牌,然后将其传递给客户端以在每个API请求上使用.使用EF核心存储和检索数据.
我遵循这篇文章是一种基本的方式要获得此设置,我设法才能完成此操作确定 – 我有一个控制器接受用户名/密码,如果有效,则返回令牌,以及根据权利要求组成的一些授权策略.
我需要的下一件事是实际管理用户/密码/等.我以为我只是用.NET核心标识为此,我将有很多现成的代码担心用户/角色,密码等.我使用的是派生的自定义User class和UserRole类从标准IdentityUser和IdentityRole类,但是我从现在恢复到标准.
我所拥有的问题是,我不能弄清楚如何添加身份和注册所有各种服务(RoleManager,Usermanager等)而不破坏身份验证 – 基本上一旦我将此行添加到我的Startup.ConfigureServices类:
services.AddIdentity<IdentityUser, IdentityRole>()
.AddEntityFrameworkStores<MyContext>();
这一切都出错了,当我收到请求时,我再也无法看到任何索赔,所以所有的政策只是锁定,你无法得到任何东西.
如果我没有这些行,那么我最终会出现与usermanager,rolemanager,userstore等相关的错误.
所以……如何(如果有可能)我可以将身份注册并正确挂钩,但避免/删除实际授权机制的任何更改?
我已经查看了一点在线,但很多这一点自从.NET核心1.x自了.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")
};
});
如果我在指示的行放置断点(通过”>>断点>>>”)然后当我 not 添加行以添加标识服务时,它会被命中,但如果我添加那些行,然后它永远不会击中.无论在方法中,我将services.AddIdentity()呼叫中的何处都是如此.我得到这只是一个lambda,所以它在稍后的点处被执行,但有没有办法我可以获得addiderity的东西来没有设置身份验证,或者使代码立即删除它?我在某些时候假设有一些代码,选择没有运行我在那里设置的Confif的兰姆达,因为身份的东西已经设置了…
感谢您阅读所有,如果您有:)
编辑 – 找到答案
好的,我最终发现这个GH问题基本上完全是这个问题:
https://github.com/aspnet/identity/issues/1376
基本上我要做的是双重的:
确保对services.AddIdentity<IdentityUser, IdentityContext()的呼叫进行了首先
更改呼叫以添加aude:
services.AddAuthentication(
JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
...
到:
services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(options =>
...
这会令人作呕地导致创建的cookie,但是,只要我可以告诉它,这不是用于身份验证 – 它纯粹是使用对控制器/动作的持票人令牌的求助令牌,这些控制器/动作有[Authorize(Policy = “Administrator”)]或类似集合至少.
我需要测试更多,如果我发现它没有以某种方式工作,我会尝试更新这个.
(编辑 – 将适当的解决方案放在答案中)
我最终将解决方案放在一起,所以关于用户的建议,始终是我编辑了我的帖子,我将其作为实际答案.
好的,这可以正确完成.首先,您需要使用我在上面的编辑中指出的身份验证选项 – 这很好.
然后,您需要使用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>>();
如此,下一件事是确保在验证用户登录时(在发送令牌之前)时,请务必使用SignInManager方法CheckPasswordSignInAsync和 Not :
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;
}
如果使用PasswordSignInAsync方法,那么您将获得运行时错误.没有配置iaguthenticationsignInmandler.
我希望这有助于某人.
我已经从github中提取了AddIdentity代码,并创建了一个基于它的扩展方法,它不会添加默认cookie身份验证器,它现在非常类似于内置的AddIdentityCore,但可以接受.
/// <summary>
/// Contains extension methods to <see cref="IServiceCollection"/> for configuring identity services.
/// </summary>
public static class IdentityServiceExtensions
{
/// <summary>
/// Adds the default identity system configuration for the specified User and Role types. (Without Authentication Scheme)
/// </summary>
/// <typeparam name="TUser">The type representing a User in the system.</typeparam>
/// <typeparam name="TRole">The type representing a Role in the system.</typeparam>
/// <param name="services">The services available in the application.</param>
/// <returns>An <see cref="IdentityBuilder"/> for creating and configuring the identity system.</returns>
public static IdentityBuilder AddIdentityWithoutAuthenticator<TUser, TRole>(this IServiceCollection services)
where TUser : class
where TRole : class
=> services.AddIdentityWithoutAuthenticator<TUser, TRole>(setupAction: null);
/// <summary>
/// Adds and configures the identity system for the specified User and Role types. (Without Authentication Scheme)
/// </summary>
/// <typeparam name="TUser">The type representing a User in the system.</typeparam>
/// <typeparam name="TRole">The type representing a Role in the system.</typeparam>
/// <param name="services">The services available in the application.</param>
/// <param name="setupAction">An action to configure the <see cref="IdentityOptions"/>.</param>
/// <returns>An <see cref="IdentityBuilder"/> for creating and configuring the identity system.</returns>
public static IdentityBuilder AddIdentityWithoutAuthenticator<TUser, TRole>(this IServiceCollection services, Action<IdentityOptions> setupAction)
where TUser : class
where TRole : class
{
// Hosting doesn't add IHttpContextAccessor by default
services.AddHttpContextAccessor();
// Identity services
services.TryAddScoped<IUserValidator<TUser>, UserValidator<TUser>>();
services.TryAddScoped<IPasswordValidator<TUser>, PasswordValidator<TUser>>();
services.TryAddScoped<IPasswordHasher<TUser>, PasswordHasher<TUser>>();
services.TryAddScoped<ILookupNormalizer, UpperInvariantLookupNormalizer>();
services.TryAddScoped<IRoleValidator<TRole>, RoleValidator<TRole>>();
// No interface for the error describer so we can add errors without rev'ing the interface
services.TryAddScoped<IdentityErrorDescriber>();
services.TryAddScoped<ISecurityStampValidator, SecurityStampValidator<TUser>>();
services.TryAddScoped<ITwoFactorSecurityStampValidator, TwoFactorSecurityStampValidator<TUser>>();
services.TryAddScoped<IUserClaimsPrincipalFactory<TUser>, UserClaimsPrincipalFactory<TUser, TRole>>();
services.TryAddScoped<UserManager<TUser>>();
services.TryAddScoped<SignInManager<TUser>>();
services.TryAddScoped<RoleManager<TRole>>();
if (setupAction != null)
{
services.Configure(setupAction);
}
return new IdentityBuilder(typeof(TUser), typeof(TRole), services);
}
}
现在,您可以从WebAPI项目中使用上面的代码如此
.AddIdentityWithoutAuthenticator<User, IdentityRole>()
以上所述是小编给大家介绍的使用JWT的.Net Core 2.0 Web API-添加身份信息会破坏JWT验证。,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对77isp云服务器技术网的支持!
原文链接:https://77isp.com/post/33756.html
=========================================
https://77isp.com/ 为 “云服务器技术网” 唯一官方服务平台,请勿相信其他任何渠道。
数据库技术 2022-03-28
网站技术 2022-11-26
网站技术 2023-01-07
网站技术 2022-11-17
Windows相关 2022-02-23
网站技术 2023-01-14
Windows相关 2022-02-16
Windows相关 2022-02-16
Linux相关 2022-02-27
数据库技术 2022-02-20
抠敌 2023年10月23日
嚼餐 2023年10月23日
男忌 2023年10月22日
瓮仆 2023年10月22日
簿偌 2023年10月22日
扫码二维码
获取最新动态