使用基于令牌的身份验证和基于 Cookie 的身份验证,无需电子邮件



我正在使用Identity进行.NET Core MVC项目。我目前有一个使用基于 cookie 的正常身份验证的工作项目,摘自身份配置:

public class IdentityHostingStartup : IHostingStartup
{
public void Configure(IWebHostBuilder builder)
{
builder.ConfigureServices((context, services) => {
services.AddDbContext<TauManagerIdentityDbContext>(options =>
options.UseNpgsql(
context.Configuration.GetConnectionString("TauManagerIdentityDbContextConnection")));
services.AddIdentity<ApplicationUser, IdentityRole>()
.AddRoles<IdentityRole>()
.AddRoleManager<ApplicationRoleManager>()
.AddEntityFrameworkStores<TauManagerIdentityDbContext>()
.AddUserManager<ApplicationIdentityUserManager>()
.AddDefaultUI()
.AddDefaultTokenProviders();
});
}
}

我正在使用AuthorizeAttribute来控制不同角色对 Web 应用程序中不同操作的访问。

现在,我现在面临一种情况,即我必须仅对一个特定操作使用某种基于令牌的身份验证。我已经在SO上阅读了几篇关于使用.NET Core Identity设置JWT的文章和问题,我发现最接近我的情况的是使用带有令牌和cookie身份验证的标识。

但是,我有两个问题:

  • 对于这种情况,这确实是生成身份验证令牌的最简单方法吗?
  • 到目前为止,我看到的所有 JWT 示例都包含对用户电子邮件的引用,例如在生成令牌时将new Claim(JwtRegisteredClaimNames.Sub, user.Email)添加到声明列表中。我根本不收集用户的电子邮件,这是我想保留的深思熟虑的决定。有没有办法使用例如用户名?

提前感谢!

这确实是在这种情况下生成身份验证令牌的最简单方法吗?

我假设这是参考问题中的代码 使用身份与令牌和cookie身份验证:

var claims = new[]
{
new Claim(JwtRegisteredClaimNames.Sub, user.Email),
new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()),
};
var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_config["Tokens:Key"]));
var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
var token = new JwtSecurityToken(_config["Tokens:Issuer"],
_config["Tokens:Issuer"],
claims,
expires: DateTime.Now.AddMinutes(30),
signingCredentials: creds);

创建 JWT 时,作为程序员必须提供的两条信息是声明和签名的创建方式。 在前面的代码中,claims作为所需的声明以及创建签名所需的keycreds。 若要创建完整令牌,请使用JwtSecurityToken类创建令牌。 我不知道这怎么能更简单。

有没有办法使用例如用户名?

声明是您想要的任何东西。 System.IdentityModel.Tokens.Jwt 命名空间有几个内置的声明名称,您可以从 JwtRegisterClaimNames 结构中使用。

因此,您可以使用以下方法之一:

JwtRegisteredClaimNames.NameId
JwtRegisteredClaimNames.Sid
JwtRegisteredClaimNames.UniqueName

或者您可以创建自己的。

我认为根本问题是,如何确保我的 JWT 自动授权 ASP.Net身份。 如果您使用的是 Cookie,您应该能够查看ClaimsPrinciple并确定 Identity 正在使用哪些声明来验证请求,并将这些相同的声明放入您的 JWT 中。

更新 1

我目前只将 JWT 与 Angular 用于项目。 我的代码不完整,因为其中一些代码将特定于仅使用 JWT/Bearer,但它应该会有所帮助。 我相信最重要的部分是AddJwtBearer如果我没记错的话,它将查找一个有效/解码的bearer标头,并使用所有相关声明的ClaimsPrincipal填充httpcontext.user。 这些声明可以与执行授权(声明和/或策略(AuthorizeAttribute一起使用。

启动.cs

public void ConfigureServices(IServiceCollection services)
{
services
.Configure<JwtIssuerOptions>(jwtIssuerOptionsConfig)
.Configure<JwtIssuerOptions>(options =>
{
options.SigningCredentials = new SigningCredentials(symmetricSecurityKey, SecurityAlgorithms.HmacSha512);
});
services
.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
{
options.IncludeErrorDetails = true;
options.TokenValidationParameters = new TokenValidationParameters
{
ClockSkew = TimeSpan.FromMinutes(5),
IssuerSigningKey = symmetricSecurityKey,
RequireSignedTokens = true,
RequireExpirationTime = true,
ValidateLifetime = true,
ValidAudience = jwtIssuerOptions.Audience,
ValidateIssuer = true,
ValidIssuer = jwtIssuerOptions.Issuer
};
if (_isDevelopment)
{
options.Events = new JwtBearerEvents
{
OnAuthenticationFailed = c =>
{
Debug.WriteLine(c.Exception.Message);
return Task.CompletedTask;
},
};
}
});

所以,最后我走了不同的路。就我而言,我觉得 JWT 会矫枉过正,因为我打算将生成的令牌存储在浏览器的本地存储中(安全性低(——因此我决定根本不使用 JWT。如果有人可以拦截 JWT 令牌,他们在技术上至少获得了用户的一些访问权限,我需要很好地微调 JWT 内部的权限以使其安全。

因此,我刚刚实现了一个操作,该操作将生成一个随机字节串(使用System.Security.Cryptography.RandomNumberGenerator(并将其存储为IdentityUser对象的属性。

我还用[AllowAnonymous]装饰了我想向基于令牌的访问公开的操作,并在那里添加了我自己的验证例程(基本上检查当前ControllerBase.User是否具有适当的权限,或者传递的令牌参数的值属于有权调用相应操作的用户之一(。我意识到这为一些额外的安全风险打开了大门(例如此端点上的潜在DDOS,如果我不打开它,它将部分缓解(,但这是我愿意采取的权衡。

相关内容

  • 没有找到相关文章

最新更新