在 c# .net 中验证 Firebase JWT

Posted

技术标签:

【中文标题】在 c# .net 中验证 Firebase JWT【英文标题】:Verify Firebase JWT in c# .net 【发布时间】:2017-04-05 14:45:49 【问题描述】:

我正在尝试验证由 firebase android 客户端获取并传递给运行 .net 的服务器的 json Web 令牌

根据here 的回答,我创建了这些方法来验证令牌并提取 uid:

public static async Task<string> GetUserNameFromTokenIfValid(string jsonWebToken)
    
        const string FirebaseProjectId = "testapp-16ecd";
        try
        
            // 1. Get Google signing keys
            HttpClient client = new HttpClient();
            client.BaseAddress = new Uri("https://www.googleapis.com/robot/v1/metadata/");
            HttpResponseMessage response = await client.GetAsync("x509/securetoken@system.gserviceaccount.com");
            if (!response.IsSuccessStatusCode)  return null; 
            var x509Data = await response.Content.ReadAsAsync<Dictionary<string, string>>();
            SecurityKey[] keys = x509Data.Values.Select(CreateSecurityKeyFromPublicKey).ToArray();

            // Use JwtSecurityTokenHandler to validate the JWT token
            JwtSecurityTokenHandler tokenHandler = new JwtSecurityTokenHandler();

            // Set the expected properties of the JWT token in the TokenValidationParameters
            TokenValidationParameters validationParameters = new TokenValidationParameters()
            
                ValidAudience = FirebaseProjectId,
                ValidIssuer = "https://securetoken.google.com/" + FirebaseProjectId,
                ValidateIssuerSigningKey = true,
                IssuerSigningKeys = keys
            ;
            SecurityToken validatedToken;
            ClaimsPrincipal principal = tokenHandler.ValidateToken(jsonWebToken, validationParameters, out validatedToken);
            var jwt = (JwtSecurityToken)validatedToken;
            return jwt.Subject;

        
        catch (Exception e)
        
            return null;
        
    

    static SecurityKey CreateSecurityKeyFromPublicKey(string data)
    
        return new X509SecurityKey(new X509Certificate2(Encoding.UTF8.GetBytes(data)));
    

当我运行代码时,我得到了响应:

"IDX10501: Signature validation failed. Unable to match 'kid': 'c2154b0435d58fc96a4480bd7655188fd4370b07', \ntoken: '"alg":"RS256","typ":"JWT","kid":"c2154b0435d58fc96a4480bd7655188fd4370b07"......

调用 https://www.googleapis.com/robot/v1/metadata/x509/securetoken@system.gserviceaccount.com 会返回一个具有匹配 ID 的证书:


 "c2154b0435d58fc96a4480bd7655188fd4370b07": "-----BEGIN CERTIFICATE-----\nMIIDHDCCAgSgAwIBAgIIRZGQCmoKoNQwDQYJKoZIhvcNAQEFBQAwMTEvMC0GA1UE\nAxMmc2VjdXJldG9rZW4uc3lzdGVtLmdzZXJ2aWNlYWNjb3VudC5jb20wHhcNMTYx\nMTIxMDA0NTI2WhcNMTYxMTI0MDExNTI2WjAxMS8wLQYDVQQDEyZzZWN1cmV0b2tl\nbi5zeXN0ZW0uZ3NlcnZpY2VhY2NvdW50LmNvbTCCASIwDQYJKoZIhvcNAQEBBQAD\nggEPADCCAQoCggEBAKHbxqFaNQyrrrv8gocpQjES+HCum8XRQYYLRqstJ12FGtDN\np32qagCbc0x94TaBZF7tCPMgyFU8pBQP7CvCxWxoy+Xdv+52lcR0sG/kskr23E3N\nJmWVHT3YwiMwdgsbWDIpWEbvJdn3DPFaapvD9BJPwNoXuFCO2vA2rhi1LuNWsaHt\nBj5jTicGCnt2PGKUTXJ9q1hOFi90wxTVUVMfFqDa4g9iKqRoaNaLOo0w3VgsFPlr\nMBca1fw1ArZpEGm3XHaDOiCi+EZ2+GRvdF/aPNy1+RdnUPMEEuHErULSxXpYGIdt\n/Mo7QvtFXkIl6ZHvEp5pWkS8mlAJyfPrOs8RzXMCAwEAAaM4MDYwDAYDVR0TAQH/\nBAIwADAOBgNVHQ8BAf8EBAMCB4AwFgYDVR0lAQH/BAwwCgYIKwYBBQUHAwIwDQYJ\nKoZIhvcNAQEFBQADggEBAJYXDQFIOC0W0ZwLO/5afSlqtMZ+lSiFJJnGx/IXI5Mi\n0sBI3QA7QXmiNH4tVyEiK+HsFPKAYovsbh7HDypEnBGsz9UmEU6Wn6Qu9/v38+bo\nLant6Ds9ME7QHhKJKtYkso0F2RVwu220xZQl1yrl4bjq+2ZDncYthILjw5t+8Z4c\nQW5UCr2wlVtkflGtIPR1UrvyU13eiI5SPkwOWPZvG2iTabnLfcRIkhQgIalkznMe\niz8Pzpk9eT8HFeZYiB61GpIWHG4oEb1/Z4Q//os+vWDQ+X0ARTYhTEbwLLQ0dcjW\nfg/tm7J+MGH5NH5MwjO+CI4fA3NoGOuEzF1vb7/hNdU=\n-----END CERTIFICATE-----\n"

我已使用 Java 调用(在 kotlin 中制作)成功验证了此令牌

FirebaseAuth.getInstance().verifyIdToken(idToken).addOnSuccessListener  decodedToken ->
    val uid = decodedToken.uid

【问题讨论】:

见here。这可能会帮助你。否则,作为一种解决方法,您可以指定自己的密钥解析器,like this 【参考方案1】:

我相信您现在已经找到了解决方案,但对于以后遇到这个问题的人来说。

为 X509SecurityKey 设置 KeyId

x509Data.Select(cert => new X509SecurityKey(new X509Certificate2(Encoding.UTF8.GetBytes(cert.Value)))
            
                KeyId = cert.Key
            )
            .ToArray()

这将允许 TokenValidationParameters 查找要针对哪个 issuerKey 进行验证。

【讨论】:

以上是关于在 c# .net 中验证 Firebase JWT的主要内容,如果未能解决你的问题,请参考以下文章

Firebase .NET 令牌验证

SPA - Firebase 和 .Net WebApi 2 身份验证

使用 .NET Core 的 Firebase 身份验证 (JWT)

Asp net core 和 Firebase 身份验证

Firebase Unity 密码验证失败

将用户从 Firebase 迁移到 ASP.NET