private static SecurityKey GetSecurityKey(string jwksJson, string token) { string[] tokenParts = token.Split('.'); JwtHeader header = JwtHeader.Base64UrlDeserialize(tokenParts[0]); JsonWebKeySet jwks = new JsonWebKeySet(jwksJson); IList <SecurityKey> keyList = jwks.GetSigningKeys(); SecurityKey signedKey = null; for (int index = 0; index < keyList.Count; index++) { SecurityKey key = keyList[index]; if (StringComparer.Ordinal.Equals(key.KeyId, header.Kid)) { signedKey = key; break; } } return(signedKey); }
public IActionResult VerifyToken([FromHeader(Name = HEADER_AUTH)] string token) { IActionResult response = Unauthorized(); var headerKeys = string.Empty; foreach (var key in Request.Headers.Keys) { headerKeys += key.ToString() + ", "; } headerKeys = headerKeys.Substring(0, headerKeys.Length - 2); if (Request.Headers.Keys.Contains(HEADER_AUTH)) { var reqHeader = Request.Headers.FirstOrDefault(h => h.Key == HEADER_AUTH); if (reqHeader.Value != string.Empty && reqHeader.Value != "null") { try { if (ModelState.IsValid) // ModelState อาจจะไม่จำเป็นต้องใช้ หรือใช้ไม่ได้กับ API { try { var handler = new JwtSecurityTokenHandler(); var jwtSecToken = handler.ReadToken(token) as JwtSecurityToken; string[] jwtArray = token.Split('.'); var jwtHeader = JwtHeader.Base64UrlDeserialize(jwtArray[0]); var jwtPayload = JwtPayload.Base64UrlDeserialize(jwtArray[1]); Jwt.Algorithm jwtAlg; if (jwtHeader.Alg == "HS256") { jwtAlg = Jwt.Algorithm.HS256; } else if (jwtHeader.Alg == "RS256") { jwtAlg = Jwt.Algorithm.RS256; } else if (jwtHeader.Alg == "ES256") { jwtAlg = Jwt.Algorithm.ES256; } else { jwtAlg = Jwt.Algorithm.HS256; } var tokenHandler = new JwtSecurityTokenHandler(); try { var claimPrincipal = tokenHandler.ValidateToken(token, new TokenValidationParameters { ValidIssuer = _config["Jwt:Issuer"], ValidAudience = _config["Jwt:Audience"], ValidateIssuer = true, ValidateAudience = true, ValidateLifetime = true, ValidateIssuerSigningKey = true, ClockSkew = TimeSpan.Zero, IssuerSigningKey = Jwt.GetSecurityKey(jwtAlg, _config, _azObj) }, out var parsedToken); var isAuthen = claimPrincipal.Identity.IsAuthenticated; if (isAuthen) { var result = "valid"; return(Ok(new { result, token })); } else { response = CustomHttpResponse.Error(HttpStatusCode.Unauthorized, Errors.Invalid_AccessToken, "Unauthorized, AccessToken (" + token + ") is invalid (Can Not Authenticated)."); } } catch (Exception ex) { response = CustomHttpResponse.Error(HttpStatusCode.Unauthorized, Errors.Invalid_AccessToken, "Unauthorized, AccessToken (" + token + ") is invalid (>> " + ex.Message + ")."); } } catch (Exception ex) { response = CustomHttpResponse.Error(HttpStatusCode.Unauthorized, Errors.Invalid_AccessToken, "Unauthorized, AccessToken (" + token + ") is invalid (> " + ex.Message + ")."); } } else // ModelState อาจจะไม่จำเป็นต้องใช้ หรือใช้ไม่ได้กับ API { response = CustomHttpResponse.Error(HttpStatusCode.Unauthorized, Errors.ExceptionalOccured, "Unauthorized, Input Model ('" + headerKeys + "') is invalid."); } } catch (Exception ex) { response = CustomHttpResponse.Error(HttpStatusCode.Unauthorized, Errors.ExceptionalOccured, "Unauthorized, Exception occurred (" + ex.Message + " - " + ex.Source + " - " + ex.StackTrace + " - " + ex.InnerException + " - " + ex.HelpLink + ")."); } } else { response = CustomHttpResponse.Error(HttpStatusCode.Unauthorized, Errors.Invalid_AccessToken, "Unauthorized, AccessToken is empty"); } } else { response = CustomHttpResponse.Error(HttpStatusCode.Unauthorized, Errors.ExceptionalOccured, "Unauthorized, Input Model is invalid (There is no Auth-Jwt)."); } return(response); }
protected override Task <AuthenticateResult> HandleAuthenticateAsync() { // Get Authorization header value if (!Request.Headers.TryGetValue(HeaderNames.Authorization, out var authorization)) { return(Task.FromResult(AuthenticateResult.Fail("Cannot read authorization header."))); } var jwtString = authorization.First(); jwtString = jwtString.Replace("Bearer ", ""); string[] jwtArray = jwtString.Split('.'); var jwtHeader = JwtHeader.Base64UrlDeserialize(jwtArray[0]); Jwt.Algorithm jwtAlg; if (jwtHeader.Alg == "HS256") { jwtAlg = Jwt.Algorithm.HS256; } else if (jwtHeader.Alg == "RS256") { jwtAlg = Jwt.Algorithm.RS256; } else if (jwtHeader.Alg == "ES256") { jwtAlg = Jwt.Algorithm.ES256; } else { jwtAlg = Jwt.Algorithm.HS256; } var tokenHandler = new JwtSecurityTokenHandler(); try { var claimPrincipal = tokenHandler.ValidateToken(jwtString, new TokenValidationParameters { ValidIssuer = _config["Jwt:Issuer"], ValidAudience = _config["Jwt:Audience"], ValidateIssuer = true, ValidateAudience = true, ValidateLifetime = true, ValidateIssuerSigningKey = true, ClockSkew = TimeSpan.Zero, IssuerSigningKey = Jwt.GetSecurityKey(jwtAlg, _config, _azObj) }, out var parsedToken); var result = claimPrincipal.Identity.IsAuthenticated; if (result) { var identities = new List <ClaimsIdentity> { new ClaimsIdentity("Undone-CustomJwtAuthType") }; var ticket = new AuthenticationTicket(new ClaimsPrincipal(identities), Options.Scheme); return(Task.FromResult(AuthenticateResult.Success(ticket))); } else { return(Task.FromResult(AuthenticateResult.Fail("Cannot read authorization header."))); } } catch (Exception ex) { return(Task.FromResult(AuthenticateResult.Fail(ex.Message))); } }
public string ReadJwtTokenClaims(string bearerToken, JwtSelector extractor = JwtSelector.EMAIL) { string pattern = @"([A-Za-z0-9-_]+)"; Regex rgx = new Regex(pattern, RegexOptions.IgnoreCase); MatchCollection matches = rgx.Matches(bearerToken); string payload; if (matches.Count != 4) { return(null); } payload = matches[2].Value; JwtHeader jwt = JwtHeader.Base64UrlDeserialize(payload); object valueObject; switch (extractor) { case (JwtSelector.EMAIL): jwt.TryGetValue("email", out valueObject); break; case (JwtSelector.ALG): jwt.TryGetValue("alg", out valueObject); break; case (JwtSelector.AUD): jwt.TryGetValue("aud", out valueObject); break; case (JwtSelector.EXP): jwt.TryGetValue("exp", out valueObject); break; case (JwtSelector.GIVEN_NAME): jwt.TryGetValue("given_name", out valueObject); break; case (JwtSelector.ISS): jwt.TryGetValue("iss", out valueObject); break; case (JwtSelector.JTI): jwt.TryGetValue("jti", out valueObject); break; case (JwtSelector.NBF): jwt.TryGetValue("nbf", out valueObject); break; case (JwtSelector.SUB): jwt.TryGetValue("sub", out valueObject); break; case (JwtSelector.TYP): jwt.TryGetValue("typ", out valueObject); break; default: jwt.TryGetValue("email", out valueObject); break; } return((string)valueObject); }