public static string BuildIdToken(string Subject) { string issuer = jwt.Issuer; string audience = jwt.Audience; IList<System.Security.Claims.Claim> claims = new List<System.Security.Claims.Claim>(); claims.Add(new System.Security.Claims.Claim("ver", jwt.Version, System.Security.Claims.ClaimValueTypes.String, issuer)); claims.Add(new System.Security.Claims.Claim("sub", Subject, System.Security.Claims.ClaimValueTypes.String, issuer)); claims.Add(new System.Security.Claims.Claim("iat", jwt.iat, System.Security.Claims.ClaimValueTypes.String, issuer)); claims.Add(new System.Security.Claims.Claim("name", jwt.name, System.Security.Claims.ClaimValueTypes.String, issuer)); claims.Add(new System.Security.Claims.Claim("preferred_username", jwt.preferred_username, System.Security.Claims.ClaimValueTypes.String, issuer)); claims.Add(new System.Security.Claims.Claim("oid", jwt.oid, System.Security.Claims.ClaimValueTypes.String, issuer)); claims.Add(new System.Security.Claims.Claim("tid", jwt.tid, System.Security.Claims.ClaimValueTypes.String, issuer)); claims.Add(new System.Security.Claims.Claim("nonce", jwt.nonce, System.Security.Claims.ClaimValueTypes.String, issuer)); claims.Add(new System.Security.Claims.Claim("aio", jwt.aio, System.Security.Claims.ClaimValueTypes.String, issuer)); // Create the token JwtSecurityToken token = new JwtSecurityToken( issuer, audience, claims, DateTime.Parse(jwt.IssuedAt), DateTime.Parse(jwt.Expiration), SigningCredentials.Value); //AAD v2 tokens doesn't use the x5t claim token.Header.Remove("x5t"); //AAD doesn't use kid/thumbprint, but the hash so a "hack" is required token.Header.Remove("kid"); token.Header.Add("kid", SigningCertHash); // Get the representation of the signed token JwtSecurityTokenHandler jwtHandler = new JwtSecurityTokenHandler(); return jwtHandler.WriteToken(token); }