如何解决当用户 ID 类型从字符串更改为整数时,.net 核心中的 User.Identity.IsAuthenticated 始终为 false
我有一个使用 json web 令牌进行身份验证的 asp.net 核心应用程序,当我的用户 ID 是字符串时,这工作正常,但在更改为 int 后停止工作。
我的 IdentityUser 类型原来是这个
public class AppUser : IdentityUser
{
//other properties...
}
我更新了这个;
public class AppUser : IdentityUser<int>
{
//other properties...
}
我从此更改了启动配置;
services.Configure<JwtIssuerOptions>(options =>
{
options.Issuer = jwtIssuerOptions.Issuer;
options.Audience = jwtIssuerOptions.Audience;
options.SigningCredentials = jwtIssuerOptions.SigningCredentials;
});
var tokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = true,Validissuer = jwtIssuerOptions.Issuer,ValidateAudience = true,ValidAudience = jwtIssuerOptions.Audience,ValidateIssuerSigningKey = true,IssuerSigningKey = _signingKey,RequireExpirationTime = false,ValidateLifetime = true,ClockSkew = TimeSpan.Zero
};
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(configureOptions =>
{
configureOptions.ClaimsIssuer = jwtIssuerOptions.Issuer;
configureOptions.TokenValidationParameters = tokenValidationParameters;
configureOptions.Savetoken = true;
});
// add identity
var builder = services.AddIdentityCore<AppUser>(o =>
{
// configure identity options
o.Password.requiredigit = false;
o.Password.RequireLowercase = false;
o.Password.RequireUppercase = false;
o.Password.RequireNonAlphanumeric = false;
o.Password.requiredLength = 6;
o.SignIn.RequireConfirmedEmail = true;
});
builder = new IdentityBuilder(builder.UserType,typeof(IdentityRole),builder.Services);
builder.AddEntityFrameworkStores<ApplicationDbContext>().AddDefaultTokenProviders();
为此;
services.Configure<JwtIssuerOptions>(options =>
{
options.Issuer = jwtIssuerOptions.Issuer;
options.Audience = jwtIssuerOptions.Audience;
options.SigningCredentials = jwtIssuerOptions.SigningCredentials;
});
var tokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = true,ClockSkew = TimeSpan.Zero
};
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(configureOptions =>
{
configureOptions.ClaimsIssuer = jwtIssuerOptions.Issuer;
configureOptions.TokenValidationParameters = tokenValidationParameters;
configureOptions.Savetoken = true;
});
// add identity
var builder = services.AddIdentity<AppUser,IdentityRole<int>>(o =>
{
// configure identity options
o.Password.requiredigit = false;
o.Password.RequireLowercase = false;
o.Password.RequireUppercase = false;
o.Password.RequireNonAlphanumeric = false;
o.Password.requiredLength = 6;
o.SignIn.RequireConfirmedEmail = true;
});
builder = new IdentityBuilder(builder.UserType,typeof(IdentityRole<int>),builder.Services);
builder.AddEntityFrameworkStores<ApplicationDbContext>().AddDefaultTokenProviders();
public async Task<string> GenerateEncodedToken(string userName,ClaimsIdentity identity)
{
var claims = new[]
{
new Claim(JwtRegisteredClaimNames.Sub,userName),new Claim(JwtRegisteredClaimNames.Jti,await _jwtOptions.JtiGenerator()),new Claim(JwtRegisteredClaimNames.Iat,ToUnixEpochDate(_jwtOptions.IssuedAt).ToString(),ClaimValueTypes.integer64),identity.FindFirst(JwtClaimIdentifiers.Rol),identity.FindFirst(JwtClaimIdentifiers.Id)
};
// Create the JWT security token and encode it.
var jwt = new JwtSecurityToken(
issuer: _jwtOptions.Issuer,audience: _jwtOptions.Audience,claims: claims,notBefore: _jwtOptions.NotBefore,expires: _jwtOptions.Expiration,signingCredentials: _jwtOptions.SigningCredentials);
var encodedJwt = new JwtSecurityTokenHandler().Writetoken(jwt);
return encodedJwt;
}
最后这个方法用于创建声明标识;
public ClaimsIdentity GenerateClaimsIdentity(string userName,int id)
{
return new ClaimsIdentity(new GenericIdentity(userName,"Token"),new[]
{
new Claim(JwtClaimIdentifiers.Id,id.ToString(),ClaimValueTypes.Integer32),});
}
User.Identity.IsAuthenticated 现在在验证时始终为 false,并且 ClaimsIdentity 似乎没有我在将 AppUser 从字符串 ID 类型转换为 int Id 类型之前看到的信息。
到目前为止我所掌握的最好的理论是,问题可能与令牌值的序列化/反序列化有关,但我正抓着稻草,不知道如何调试它。
我错过了什么?
解决方法
您的代码中没有任何内容让我生气(看起来主要区别在于您从 AddIdentity
切换到 AddIdentityCore
?),但我发现 JWT 身份验证问题,它确实有助于运行应用程序在调试模式下并为 JwtBearerEvents
添加处理程序。
将此添加到您的 Startup .AddJwtBearer
调用中:
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
{
// ...
// Add this at the end:
options.Events = new JwtBearerEvents
{
OnAuthenticationFailed = context =>
{
// Put a breakpoint here
System.Console.WriteLine(context.Exception);
return Task.CompletedTask;
},};
})
如果您在调试中运行,将能够检查context.Exception
:
这应该可以让您更好地解释 JWT 身份验证失败的原因。
,利用 Connor Low's advice,我为所有 JwtBearerOptions
事件提供了委托。这些都没有命中,说明我的设置不够完善,根本没有使用我配置的认证方案。
我恢复到addIdentityCore
var builder = services.AddIdentityCore<AppUser>(o =>
虽然我不能再指定我使用的是 IdentityRole<int>
而不是像这样的默认值;
var builder = services.AddIdentity<AppUser,IdentityRole<int>>(o =>
如果我有以下行,这似乎是不必要的;
builder = new IdentityBuilder(builder.UserType,typeof(IdentityRole<int>),builder.Services);
随着这些更改就位,身份验证起作用了,并且我在 Connor Low 的建议中添加的断点也被击中了。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。