using UserManagement.Data; using Microsoft.AspNetCore.Http; using Microsoft.IdentityModel.Tokens; using System; using System.IdentityModel.Tokens.Jwt; using System.Linq; using System.Text; using System.Threading.Tasks; namespace UserManagement.API.Helpers { public class JwtMiddleware { private readonly RequestDelegate _next; private JwtSettings _settings = null; public JwtMiddleware( RequestDelegate next, JwtSettings settings) { _next = next; _settings = settings; } public async Task Invoke(HttpContext context) { var token = context.Request.Headers["Authorization"].FirstOrDefault()?.Split(" ").Last(); if (token != null) attachUserToContext(context, token); await _next(context); } private void attachUserToContext(HttpContext context, string token) { try { var tokenHandler = new JwtSecurityTokenHandler(); var key = Encoding.ASCII.GetBytes(_settings.Key); tokenHandler.ValidateToken(token, new TokenValidationParameters { ValidateIssuerSigningKey = true, IssuerSigningKey = new SymmetricSecurityKey(key), ValidateIssuer = false, ValidateAudience = false, // set clockskew to zero so tokens expire exactly at token expiration time (instead of 5 minutes later) ClockSkew = TimeSpan.Zero }, out SecurityToken validatedToken); var jwtToken = (JwtSecurityToken)validatedToken; var userId = jwtToken.Claims.First(x => x.Type == "sub").Value; // attach user to context on successful jwt validation //context.Items["User"] = userId; } catch { // do nothing if jwt validation fails // user is not attached to context so request won't have access to secure routes } } } }