【问题标题】:Add user claims to firebase auth from asp.net core api从 asp.net core api 向 firebase auth 添加用户声明
【发布时间】:2018-12-16 08:04:25
【问题描述】:

给定一个仅使用 [Authorize] 属性的 asp.net 核心 api 和有效的 firebase 身份验证,我如何向令牌添加自定义声明以使用 [Authorize(Policy = "admin")]?管理 SDK 仅适用于 node.js、Java、python 或 go,我找不到任何有关如何直接使用 Firebase 管理 API 的文档。据我了解,用户声明必须存储在 Firebase Auth 后端。

【问题讨论】:

标签: firebase firebase-authentication asp.net-core-webapi


【解决方案1】:

据我所知,使用 C# Firebase Admin SDK 是无法做到的。 我遇到了同样的问题,起初,我使用令牌来获取用户 ID,从数据库中检索用户 ID 的角色,设置一个 Claims 数组,并使用添加的声明创建一个自定义令牌。然后我通过他们的 REST API 将其发送到 Firebase,以获取常规的 Firebase ID 和刷新令牌,如 reference guide 中所述。最后我把令牌给了客户。 但是,我遇到了问题(主要是 404 错误),它没有很好地记录您需要对验证中间件进行哪些更改以接受新的重新发布的令牌,而且我永远无法获得刷新令牌,因为它从未在 REST 中API 响应。我什至按照 herehere 中的步骤,根据 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!

希望这会有所帮助!

【讨论】:

    【解决方案2】:

    自 Firebase Admin .NET SDK 1.1 发布以来,支持使用自定义声明控制访问功能。

    您可以在此处找到存储库:https://github.com/firebase/firebase-admin-dotnet

    设置指南和文档:https://firebase.google.com/docs/admin/setup

    解决方案:

    // Initialize the admin SDK with your service account keys
    FirebaseApp.Create(new AppOptions()
    {
        Credential = GoogleCredential.FromFile("path/to/serviceAccountKey.json"),
    });
    
    // Create the custom user claim that has the role key
    var claims = new Dictionary<string, object>
    {
        { ClaimTypes.Role, "Administrator" }
    };
    
    // This will call the Firebase Auth server and set the custom claim for the user
    await FirebaseAuth.DefaultInstance.SetCustomUserClaimsAsync(uid, claims);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-01-24
      • 2020-06-19
      • 2021-10-31
      • 2018-08-14
      • 2019-03-12
      • 2015-02-14
      • 2019-08-17
      相关资源
      最近更新 更多