65.9K
CodeProject 正在变化。 阅读更多。
Home

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

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.81/5 (9投票s)

2017 年 11 月 28 日

CPOL

2分钟阅读

viewsIcon

43379

在 ASP.NET Core Identity 中支持 JWT 令牌

引言

这是关于 ASP.NET Core Identity 的一系列文章中的第三篇文章

在之前的步骤中,我们使用 ASP.NET Core Identity 创建了一个带有登录/注销功能的 ASP.NET Core MVC 网站。我们构建的 MVC 网站使用了基于 Cookie 的身份验证,这对于该场景来说很好。但是对于许多其他场景(例如从移动应用程序消费安全的 API),基于 Cookie 的方法不是一个好的选择。一种流行的解决方案是基于令牌的身份验证。 在这一步中,我们将为身份验证添加 jwt 令牌生成能力到我们的项目中。

我不会解释 JWT 令牌是什么以及它与基于 Cookie 的方法有何不同,因为关于这个主题有很多非常好的文章。 如果您感兴趣,可以查看这些文章

  1. https://auth0.com/blog/angularjs-authentication-with-cookies-vs-token/
  2. https://auth0.com/blog/ten-things-you-should-know-about-tokens-and-cookies/
  3. 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) 创建一个令牌。 我们将提供 usernamepassword,API 将返回 bearer 令牌。

现在让我们再次使用 bearer 令牌调用 Greeting API。

成功了! 在下一篇文章中,我们将创建一个带有用户身份验证功能的 Angular 4 项目,该功能在本步骤中开发完成。

© . All rights reserved.