nol*_*int 7 c# jwt firebase firebase-authentication
处理使用Firebase进行某些数据存储的项目,我们的客户端请求使用C#.NET实现服务器.我们在服务器上设置REST端点,以便客户端能够出于某些目的与其进行通信(例如,触发只能在服务器上运行的算法).
Firebase建议我们通过ID令牌识别用户,如下所示:https://firebase.google.com/docs/auth/server/verify-id-tokens#verify_id_tokens_using_a_third-party_jwt_library
由于没有支持令牌身份验证的官方.NET Firebase服务器SDK,因此我们使用第三方JWT库来执行此操作:https://github.com/AzureAD/azure-activedirectory-identitymodel-extensions-for -dotnet
根据Firebase文档中的规定,我们首先生成向服务器发送令牌.在检查令牌中的几个不同字段后,我们使用该kid字段从https://www.googleapis.com/robot/v1/metadata/x509/securetoken@system.gserviceaccount.com获取公钥.
我们一直在浏览文档和StackOverflow很长一段时间,但是根据Firebase文档的规定,我们找不到使用此公钥来执行此操作的方法:
最后,确保ID令牌由与令牌的孩子声明相对应的私钥签名.从https://www.googleapis.com/robot/v1/metadata/x509/securetoken@system.gserviceaccount.com获取公钥,并使用JWT库验证签名.
Firebase文档实际上没有为此提供任何解释,我们正在使用的库的文档也没有.因此,当我们给出的所有内容都是公钥时,我们甚至无法获得关于如何验证令牌是否由私钥签名的基本想法.
验证令牌是否由正确的私钥实际签名的最佳方法是什么?
您应该能够通过执行以下操作来完成令牌验证,该操作利用System.IdentityModel.Tokens.JwtNuget包执行大多数验证:
class Program {
static HttpClient client = new HttpClient();
static void Main() { RunAsync().Wait(); }
static async Task RunAsync() {
string encodedJwt = "[TOKEN_TO_BE_VALIDATED]";
// 1. Get Google signing keys
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; }
var x509Data = await response.Content.ReadAsAsync<Dictionary<string, string>>();
SecurityKey[] keys = x509Data.Values.Select(CreateSecurityKeyFromPublicKey).ToArray();
// 2. Configure validation parameters
const string FirebaseProjectId = "[FIREBASE_PROJECT_ID]";
var parameters = new TokenValidationParameters {
ValidIssuer = "https://securetoken.google.com/" + FirebaseProjectId,
ValidAudience = FirebaseProjectId,
IssuerSigningKeys = keys,
};
// 3. Use JwtSecurityTokenHandler to validate signature, issuer, audience and lifetime
var handler = new JwtSecurityTokenHandler();
SecurityToken token;
ClaimsPrincipal principal = handler.ValidateToken(encodedJwt, parameters, out token);
var jwt = (JwtSecurityToken)token;
// 4.Validate signature algorithm and other applicable valdiations
if (jwt.Header.Alg != SecurityAlgorithms.RsaSha256) {
throw new SecurityTokenInvalidSignatureException(
"The token is not signed with the expected algorithm.");
}
}
static SecurityKey CreateSecurityKeyFromPublicKey(string data) {
return new X509SecurityKey(new X509Certificate2(Encoding.UTF8.GetBytes(data)));
}
}
Run Code Online (Sandbox Code Playgroud)
示例程序的使用声明列表:
using System;
using System.Collections.Generic;
using System.IdentityModel.Tokens.Jwt;
using System.Linq;
using System.Net.Http;
using System.Security.Claims;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Threading.Tasks;
using Microsoft.IdentityModel.Tokens;
Run Code Online (Sandbox Code Playgroud)
现在我们可以使用适用于 .NET 的 Firebase Admin SDK。
https://github.com/Firebase/firebase-admin-dotnet
var decoded = await FirebaseAuth.DefaultInstance.VerifyIdTokenAsync(idToken);
var uid = decoded.Uid;
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3728 次 |
| 最近记录: |