据我所知,使用 C# Firebase Admin SDK 是无法做到的。
我遇到了同样的问题,起初,我使用令牌来获取用户 ID,从数据库中检索用户 ID 的角色,设置一个 Claims 数组,并使用添加的声明创建一个自定义令牌。然后我通过他们的 REST API 将其发送到 Firebase,以获取常规的 Firebase ID 和刷新令牌,如 reference guide 中所述。最后我把令牌给了客户。
但是,我遇到了问题(主要是 404 错误),它没有很好地记录您需要对验证中间件进行哪些更改以接受新的重新发布的令牌,而且我永远无法获得刷新令牌,因为它从未在 REST 中API 响应。我什至按照 here 和 here 中的步骤,根据 Firebase 说明铸造了我自己的自定义令牌,但始终无法让这该死的东西发挥作用。
所以我最终做了一些不同的事情。我从 firebase IdToken 中检索了用户声明,并使用 System.IdentityModel.Tokens.Jwt 创建了我自己的令牌。在那里,我添加了自己的声明和角色并将其发送给客户。现在客户端使用 FireBase 登录,但我可以完全控制令牌以使用我的 API
这就是我修改启动的方式。请记住,我还没有玩过所有选项
var key = System.Text.Encoding.UTF8.GetBytes(Configuration["MyToken:Key"]);
services.AddAuthentication(
auth => {
auth.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
auth.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;})
.AddJwtBearer(options => {
options.RequireHttpsMetadata = false;
options.IncludeErrorDetails = true;
options.TokenValidationParameters = new TokenValidationParameters {
ValidateIssuerSigningKey = true,
IssuerSigningKey = new SymmetricSecurityKey(key),
ValidateIssuer = false,
ValidateAudience = false,
ValidateLifetime = true
};
});
这是简化的编码函数:
public string EncodeTokenMS(string uid, Claim[] claims)
{
var signingKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(<Secret key here>));
var signingCredentials = new SigningCredentials(signingKey, SecurityAlgorithms.HmacSha256Signature);
var now = DateTimeOffset.UtcNow;
var _claims = new[] {
new Claim(JwtRegisteredClaimNames.Iss, "https://auth.xxx.com"),
new Claim(JwtRegisteredClaimNames.Aud, "https://auth.xxx.com"),
new Claim(JwtRegisteredClaimNames.Sub, uid),
new Claim(JwtRegisteredClaimNames.AuthTime, now.ToUnixTimeSeconds().ToString(), ClaimValueTypes.Integer64),
new Claim(JwtRegisteredClaimNames.Iat, now.ToUnixTimeSeconds().ToString(), ClaimValueTypes.Integer64),
new Claim(JwtRegisteredClaimNames.Exp, now.AddMinutes(60).ToUnixTimeSeconds().ToString(), ClaimValueTypes.Integer64),
// TODO Actually write the code to get tenancy, roles, and user info
new Claim("tenantId", "PippoBaudo" ),
new Claim(ClaimTypes.Role, "User")
};
//Create and sign the JWT, and write it to a string
var jwt = new JwtSecurityToken(
claims: _claims,
signingCredentials: signingCredentials);
return new JwtSecurityTokenHandler().WriteToken(jwt);
}
这种方法的缺点是在用户注册时增加了往返,但是只有在用户需要令牌时才会增加延迟,而且我可以增加令牌超过 60 分钟。
欢迎对这种方法提出建议和(建设性的)cmets!
希望这会有所帮助!