ASP.NET Core Identity:支持 JWT 令牌进行用户身份验证






4.81/5 (9投票s)
在 ASP.NET Core Identity 中支持 JWT 令牌
引言
这是关于 ASP.NET Core Identity 的一系列文章中的第三篇文章
- ASP.NET Core Identity:入门
- ASP.NET Core Identity:设置 Web 项目和 Identity 数据库
- ASP.NET Core Identity:使用 ASP.NET Core MVC 实现用户注册、登录和注销功能
- ASP.NET Core Identity:支持用于用户身份验证的 JWT Token
- Angular 4:使用 JWT Token 进行用户身份验证
- ASP.NET Core Identity:支持来自外部提供程序的 OAuth 2.0 凭据
- Angular 4:使用外部提供程序进行用户身份验证
在之前的步骤中,我们使用 ASP.NET Core Identity 创建了一个带有登录/注销功能的 ASP.NET Core MVC 网站。我们构建的 MVC 网站使用了基于 Cookie 的身份验证,这对于该场景来说很好。但是对于许多其他场景(例如从移动应用程序消费安全的 API),基于 Cookie 的方法不是一个好的选择。一种流行的解决方案是基于令牌的身份验证。 在这一步中,我们将为身份验证添加 jwt 令牌生成能力到我们的项目中。
我不会解释 JWT 令牌是什么以及它与基于 Cookie 的方法有何不同,因为关于这个主题有很多非常好的文章。 如果您感兴趣,可以查看这些文章
- https://auth0.com/blog/angularjs-authentication-with-cookies-vs-token/
- https://auth0.com/blog/ten-things-you-should-know-about-tokens-and-cookies/
- https://medium.com/vandium-software/5-easy-steps-to-understanding-json-web-tokens-jwt-1164c0adfcec
本文的完整代码可在该仓库的 Demo 3 文件夹中找到 https://github.com/ra1han/aspnet-core-identity。
在 Startup 中准备服务
为了启用 JWT 令牌生成,我们必须配置身份验证中间件的服务。 但是,如果我们查看 Startup
类中 ConfigureServices
方法的当前实现,我们会看到没有关于 Cookie 的配置。
那么基于 Cookie 的身份验证是如何工作的? 这是因为如果我们不手动配置它,默认行为就是基于 Cookie 的身份验证。
我们将使用 ConfigureServices
方法中的 services.AddAuthentication
添加额外的身份验证方案。
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<applicationdbcontext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
services.AddIdentity<applicationuser, identityrole="">()
.AddEntityFrameworkStores<applicationdbcontext>()
.AddDefaultTokenProviders();
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddCookie()
.AddJwtBearer(jwtBearerOptions =>
{
jwtBearerOptions.TokenValidationParameters = new TokenValidationParameters()
{
ValidateActor = false,
ValidateAudience = false,
ValidateLifetime = true,
ValidateIssuerSigningKey = true,
ValidIssuer = Configuration["Token:Issuer"],
ValidAudience = Configuration["Token:Audience"],
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes
(Configuration["Token:Key"]))
};
});
services.AddMvc();
}
准备控制器
现在,我们将添加两个新的 Web API 控制器
TokenController
- 可以匿名访问,用户使用它来检索 JWT 令牌GreetingController
- 受保护,只能使用 JWT 令牌身份验证方案访问
TokenController
中的令牌生成代码
[HttpPost]
public async Task<iactionresult> Get(LoginViewModel model)
{
if (ModelState.IsValid)
{
var user = await _userManager.FindByEmailAsync(model.Email);
if (user != null)
{
var result = await _signInManager.CheckPasswordSignInAsync
(user, model.Password, lockoutOnFailure: false);
if (!result.Succeeded)
{
return Unauthorized();
}
var claims = new[]
{
new Claim(JwtRegisteredClaimNames.Sub, model.Email),
new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString())
};
var token = new JwtSecurityToken
(
issuer: _configuration["Token:Issuer"],
audience: _configuration["Token:Audience"],
claims: claims,
expires: DateTime.UtcNow.AddDays(60),
notBefore: DateTime.UtcNow,
signingCredentials: new SigningCredentials(new SymmetricSecurityKey
(Encoding.UTF8.GetBytes(_configuration["Token:Key"])),
SecurityAlgorithms.HmacSha256)
);
return Ok(new { token = new JwtSecurityTokenHandler().WriteToken(token) });
}
}
return BadRequest();
}
使用 API
现在为了测试我们的实现,我们将使用 Postman。
首先,我们将尝试从 postman 访问 Greeting
API (https://:36946/api/greeting)。 我们会看到我们收到 Unauthorized 错误。
现在让我们从 Token
API (https://:36946/api/token) 创建一个令牌。 我们将提供 username
和 password
,API 将返回 bearer 令牌。
现在让我们再次使用 bearer 令牌调用 Greeting
API。
成功了! 在下一篇文章中,我们将创建一个带有用户身份验证功能的 Angular 4 项目,该功能在本步骤中开发完成。