JWT 令牌认证 - 以正确的方式做事
Posted
技术标签:
【中文标题】JWT 令牌认证 - 以正确的方式做事【英文标题】:JWT Token authentication - Doing it right way 【发布时间】:2018-11-12 02:04:11 【问题描述】:我的项目结构概览:
我有 2 个项目。
-
Asp.net 核心 Web Api
Asp.net 核心 Web MVC
在 Web Api 项目中
我没有使用 Asp.net 核心身份登录,而是使用我自己的登录机制。LoginAction
方法将对数据库中的用户进行身份验证并生成 JWT Token。
我能够生成 JWT Token 并且到目前为止生活很顺利。
生成令牌
[AllowAnonymous]
[Route("requesttoken")]
[HttpPost]
public async Task<IActionResult> RequestToken([FromBody] TokenRequest request)
var result = await IsValidUser(request);
if(result)
var claims = new[]
new Claim(ClaimTypes.Name, request.Email)
;
var key = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(_myAppSettings.SecurityKey));
var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
var token = new JwtSecurityToken(
issuer: _myAppSettings.WebsiteName.ToLower(),
audience: _myAppSettings.WebsiteName.ToLower(),
claims: claims,
notBefore: Utilities.GetEST_DateTimeNow(),
expires: Utilities.GetEST_DateTimeNow().AddMinutes(5),
signingCredentials: creds);
return Ok(new
token = new JwtSecurityTokenHandler().WriteToken(token)
);
else
return Unauthorized();
Startup 类内部
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
services.Configure<MyAppSettings>(Configuration.GetSection("MyAppSettings"));
#region Validate JWT Token
ConfigureJwtAuthService(services, Configuration);
#endregion
services.AddMvc();
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
if (env.IsDevelopment())
app.UseDeveloperExceptionPage();
app.UseAuthentication();
app.UseMvc();
JWT Validation 部分(作为部分启动类)
public void ConfigureJwtAuthService(IServiceCollection services, IConfiguration configuration)
var symmetricKeyAsBase64 = configuration["MyAppSettings:SecurityKey"];
var keyByteArray = Encoding.ASCII.GetBytes(symmetricKeyAsBase64);
var signingKey = new SymmetricSecurityKey(keyByteArray);
var tokenValidationParameters = new TokenValidationParameters
// The signing key must match!
ValidateIssuerSigningKey = true,
IssuerSigningKey = signingKey,
// Validate the JWT Issuer (iss) claim
ValidateIssuer = true,
ValidIssuer = Configuration["MyAppSettings:WebsiteName"].ToLower(),
// Validate the JWT Audience (aud) claim
ValidateAudience = true,
ValidAudience = Configuration["MyAppSettings:WebsiteName"].ToLower(),
// Validate the token expiry
ValidateLifetime = true,
ClockSkew = TimeSpan.Zero
;
services.AddAuthentication(
options =>
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
)
.AddJwtBearer(o => o.TokenValidationParameters = tokenValidationParameters);
LoginAction 方法的示例响应。
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkrDtGhuIETDs8OoIiwiYWRtaW4iOnRydWV9.469tBeJmYLERjlKi9u6gylb-2NsjHLC_6kZNdtoOGsA"
在 Web MVC 项目中
我正在使用上面的 Web Api 并传递登录参数,并且能够获得 JWT Token 响应。 我将 JWT 令牌响应存储在 cookie [手动 -_httpContextAccessor.HttpContext.Response.Cookies.Append(key, jwtTokenValue, option);
]
根据收到的 JWT 令牌响应,我正在尝试从该 JWT 令牌中提取声明,以便能够在网络上创建用户和登录用户的有效身份。
我正在尝试实现以下目标:
var claims = new List<Claim>
new Claim(ClaimTypes.Name, model.Email)
;
var userIdentity = new ClaimsIdentity(claims, "login");
ClaimsPrincipal principal = new ClaimsPrincipal(userIdentity);
await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, principal);
return RedirectToLocal(returnUrl);
问题
-
我将 JWT 令牌存储在 cookie 中是否正确。我手动存储 cookie 的方法是正确的还是有更好的方法?
如何在 Web Project 中从 JWT 获取声明,以便能够使用 cookie 为用户唱歌?
希望以正确的方式做,任何帮助将不胜感激。
【问题讨论】:
以下帮助了我:blogs.quovantis.com/json-web-token-jwt-with-web-api 【参考方案1】:以下似乎对我有所帮助:http://blogs.quovantis.com/json-web-token-jwt-with-web-api/ 不确定这是否是正确的做法。
/// Using the same key used for signing token, user payload is generated back
public JwtSecurityToken GenerateUserClaimFromJWT(string authToken)
var tokenValidationParameters = new TokenValidationParameters()
ValidAudiences = new string[]
"http://www.example.com",
,
ValidIssuers = new string[]
"self",
,
IssuerSigningKey = signingKey
;
var tokenHandler = new JwtSecurityTokenHandler();
SecurityToken validatedToken;
try
tokenHandler.ValidateToken(authToken,tokenValidationParameters, out validatedToken);
catch (Exception)
return null;
return validatedToken as JwtSecurityToken;
【讨论】:
以上是关于JWT 令牌认证 - 以正确的方式做事的主要内容,如果未能解决你的问题,请参考以下文章