/// <summary> /// Validate IDToken and Check if IAP is trusted. /// </summary> /// <param name="request"></param> /// <returns></returns> private async Task ValidateIDTokenAndSignature(HttpRequest request) { if (request == null) { throw new UnauthorizedAccessException("Unauthenticated."); } if (request.Headers == null) { throw new UnauthorizedAccessException("Authorization Header not found."); } var headers = request.Headers.ToList(); #region Get and validate inputs var token = GetHeaderWithKey(headers, "Authorization").Replace("Bearer ", ""); if (string.IsNullOrEmpty(token)) { throw new UnauthorizedAccessException("IDToken not found."); } #endregion //Parse the IDToken var jwtToken = new JwtSecurityToken(token); if (jwtToken == null && jwtToken.Claims == null) { throw new UnauthorizedAccessException("Mailformed IDToken."); } var iss = jwtToken.Claims.FirstOrDefault(i => i.Type == "iss")?.Value; var at_hash = jwtToken.Claims.FirstOrDefault(i => i.Type == "at_hash")?.Value; if (string.IsNullOrWhiteSpace(iss)) { throw new UnauthorizedAccessException("Unable to find the token issuer."); } var client = new HttpClient(); var disco = await client.GetDiscoveryDocumentAsync(iss); if (disco.IsError) { throw new UnauthorizedAccessException("Unable to load information from the token issuer URL."); } var is4Client = new UraClient.OIDCUtil(disco.JwksUri); jwtToken = ValidateIDToken(token, is4Client.RSAParameters); var ski = is4Client.SKI; if (string.IsNullOrEmpty(ski)) { throw new UnauthorizedAccessException("Unsupported algorithm: The valid algorithm is SHA256RSA."); } ValidateIAP(ski); }
/// <summary> /// Validate signaute with id token /// </summary> /// <param name="request"></param> /// <returns></returns> private async Task <(string, X509Certificate2, int)> ValidateSignatureAsync(HttpRequest request) { if (request == null) { return("Request headers not found", null, 0); } if (request.Headers == null) { return("Request headers not found", null, 0); } var headers = request.Headers.ToList(); #region Get and validate inputs var accessToken = GetHeaderWithKey(headers, "Authorization").Replace("Bearer ", ""); if (string.IsNullOrEmpty(accessToken)) { return("Token not found", null, 0); } #endregion #region GetIss string iss = string.Empty; string at_hash = string.Empty; var jwtToken = new JwtSecurityToken(accessToken); if (jwtToken == null && jwtToken.Claims == null) { return("Token is invalid", null, 0); } iss = jwtToken.Claims.FirstOrDefault(i => i.Type == "iss")?.Value; at_hash = jwtToken.Claims.FirstOrDefault(i => i.Type == "at_hash")?.Value; if (string.IsNullOrWhiteSpace(iss)) { return("iss uri is empty", null, 0); } #endregion #region Get ski var client = new HttpClient(); var disco = await client.GetDiscoveryDocumentAsync(iss); if (disco.IsError) { return("iss uri is invalid", null, 0); } var is4Client = new UraClient.OIDCUtil(disco.JwksUri); var ski = is4Client.SKI; if (string.IsNullOrEmpty(ski)) { //return ("Can not get ski: " + error, null, 0); } #endregion #region Get signing certificate from ura or in local storage var cmsClient = new UraClient.CMSConnect(); var cmdCert = GetConfigString("Cert:SingedCert"); var cmdCertPass = GetConfigString("Cert:SingedCertPass"); var cert = cmsClient.GetCert(disco.JwksUri, out string cmsError, cmdCert, cmdCertPass); if (cert == null) { return("Signature not match", null, 0); } #endregion Get signing certificate return(string.Empty, cert, 1); }