protected override Task <HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) { // if this is not a bearer header, we do not know how to process it, so just return var authorizationHeader = request.Headers.Authorization; if (string.IsNullOrWhiteSpace(authorizationHeader?.Scheme) || !authorizationHeader.Scheme.Equals(authenticationType, StringComparison.InvariantCultureIgnoreCase)) { return(base.SendAsync(request, cancellationToken)); } try { // get the actual token var jwtToken = request.Headers.Authorization.Parameter; // parse the header to find out what algorithm to use var parts = jwtToken.Split('.'); var headerBase64 = parts[0]; var headerJson = Encoding.UTF8.GetString(JwtUtil.Base64UrlDecode(headerBase64)); var headerData = JObject.Parse(headerJson); var principal = JwtManager.GetPrincipal(jwtToken); // setup context principal request.GetRequestContext().Principal = principal; return(base.SendAsync(request, cancellationToken)); } catch (Exception ex) { return(Task.Run(() => request.CreateResponse(HttpStatusCode.Unauthorized, new { message = ex.Message }))); } }
public static TokenInfo ParseToken(string token, bool validateHmac = true) { TokenInfo ti = new TokenInfo(); var parts = token.Split('.'); var headerBase64 = parts[0]; var bodyBase64 = parts[1]; var signature = parts[2]; // parse the header and body into objects var headerJson = Encoding.UTF8.GetString(JwtUtil.Base64UrlDecode(headerBase64)); var headerData = JObject.Parse(headerJson); var bodyJson = Encoding.UTF8.GetString(JwtUtil.Base64UrlDecode(bodyBase64)); var bodyData = JObject.Parse(bodyJson); // verify algorithm var algorithm = (string)headerData["alg"]; if (algorithm != "HS256") { throw new NotSupportedException("Only HS256 is supported for this algorithm."); } if (validateHmac) { // verify signature byte[] bytesToSign = GetBytes(string.Join(".", headerBase64, bodyBase64)); var alg = new HMACSHA256(Convert.FromBase64String(HmacSecret)); var hash = alg.ComputeHash(bytesToSign); var computedSig = JwtUtil.Base64UrlEncode(hash); if (computedSig != signature) { throw new AuthenticationException("Invalid JWT signature"); } } // verify expiration var expirationUtc = JwtUtil.ConvertFromUnixTimestamp((long)bodyData["exp"]); if (DateTime.UtcNow > expirationUtc) { throw new AuthenticationException("Token has expired"); } // verify audience var jwtAudience = (string)bodyData["aud"]; if (jwtAudience != JwtManager.AceAudience) { throw new AuthenticationException($"Invalid audience '{jwtAudience}'. Expected '{JwtManager.AceAudience}'."); } ti.Name = (string)bodyData[ClaimTypes.Name] ?? (string)bodyData["unique_name"]; var roles = bodyData[ClaimTypes.Role] ?? bodyData["role"]; if (roles != null) { if (roles.HasValues) { ti.Roles = roles.Select(r => (string)r).ToList(); } else { ti.Roles = new List <string>() { (string)roles } }; } string accountGuid = (string)bodyData[ClaimTypes.NameIdentifier] ?? (string)bodyData["nameid"]; ti.AccountGuid = Guid.Parse(accountGuid); ti.AccountId = uint.Parse((string)bodyData["account_id"]); ti.IssuingServer = (string)bodyData["issuing_server"]; return(ti); }
public static TokenInfo ParseToken(string token, bool validateHmac = true) { TokenInfo ti = new TokenInfo(); var parts = token.Split('.'); var headerBase64 = parts[0]; var bodyBase64 = parts[1]; var signature = parts[2]; // parse the header and body into objects var headerJson = Encoding.UTF8.GetString(JwtUtil.Base64UrlDecode(headerBase64)); var headerData = JObject.Parse(headerJson); var bodyJson = Encoding.UTF8.GetString(JwtUtil.Base64UrlDecode(bodyBase64)); var bodyData = JObject.Parse(bodyJson); // verify algorithm var algorithm = (string)headerData["alg"]; if (algorithm != "HS256") { throw new NotSupportedException("Only HS256 is supported for this algorithm."); } if (validateHmac) { // verify signature byte[] bytesToSign = GetBytes(string.Join(".", headerBase64, bodyBase64)); var alg = new HMACSHA256(Convert.FromBase64String(HmacSecret)); var hash = alg.ComputeHash(bytesToSign); var computedSig = JwtUtil.Base64UrlEncode(hash); if (computedSig != signature) { throw new AuthenticationException("Invalid JWT signature"); } } // verify expiration var expirationUtc = JwtUtil.ConvertFromUnixTimestamp((long)bodyData["exp"]); if (DateTime.UtcNow > expirationUtc) { throw new AuthenticationException("Token has expired"); } // verify audience var jwtAudience = (string)bodyData["aud"]; if (jwtAudience != JwtManager.AceAudience) { throw new AuthenticationException($"Invalid audience '{jwtAudience}'. Expected '{JwtManager.AceAudience}'."); } ti.Name = (string)bodyData["account_name"]; /// TODO: Convert to SecurityLevel instead of AccessLevel AccessLevel thisGuy = AccessLevel.Player; List <string> roles = new List <string>(); if (Enum.TryParse((string)bodyData["role"], out thisGuy)) { foreach (AccessLevel level in Enum.GetValues(typeof(AccessLevel))) { if (thisGuy >= level) { roles.Add(level.ToString()); } } } ti.AccountGuid = Guid.Parse((string)bodyData["account_guid"]); ti.IssuingServer = (string)bodyData["issuing_server"]; return(ti); }