【问题标题】:Hot Chocolate Authenticated Connected User热巧克力认证连接用户
【发布时间】:2021-09-09 08:06:37
【问题描述】:

我的 GraphQL 查询类中有一个非常简单的 IQueryable。我想要完成的是获取请求聊天信息的授权用户。将 context.Chats 更改为 context.Chats.Where(i => i.UserId == RequestingId)。所以你不能从我的 API 获取私人聊天。如果您未获得授权,那么您将始终收到一个空列表。我已经看到如何使用 MVC 控制器执行此操作,但这不是预期的结果。

public class Query
{
    [UseDbContext(typeof(AppDbContext))]
    [UseFiltering]
    [UseSorting]
    public IQueryable<Chat> GetChats([ScopedService] AppDbContext context)
    {
        return context.Chats
           .Include(m => m.Messages)
           .Include(r => r.Recipients);
    }
}

【问题讨论】:

    标签: c# graphql .net-5 webapi hotchocolate


    【解决方案1】:

    您可以像下面这样注入用户的ClaimsPrincipal

    public IQueryable<Chat> GetChats([ScopedService] AppDbContext context,
        [GlobalState(nameof(ClaimsPrincipal))] ClaimsPrincipal claimsPrincipal)
    {
        // ...
    }
    

    随着即将发布的 v11.3.1,您还可以简单地编写:

    public IQueryable<Chat> GetChats([ScopedService] AppDbContext context, 
        ClaimsPrincipal claimsPrincipal)
    {
        // ...
    }
    

    您可以像这样访问经过身份验证的用户的 ID:

    var userId = claimsPrincipal.FindFirstValue(ClaimTypes.NameIdentifier);
    

    注意:根据您设置身份验证/授权机制的方式,声明可能会有所不同。

    【讨论】:

      【解决方案2】:
      [UseDbContext(typeof(AppDbContext))]
          [UseFiltering]
          [UseSorting]
          public IQueryable<Chat> GetChats([ScopedService] AppDbContext context, [Service] IHttpContextAccessor httpContextAccessor)
          {
              ClaimsPrincipal authenticatedUser = new ClaimsPrincipal(new ClaimsIdentity(JwtParser.ParseClaimsFromJwt(httpContextAccessor.HttpContext.Request.Headers["Authorization"]), Startup.JWT_AUTH_TYPE));
              int userId;
              int.TryParse(authenticatedUser.Claims.FirstOrDefault(i => i.Type.Equals(ClaimTypes.NameIdentifier))?.Value, out userId);
              return context.Chats
                  .Include(m => m.Messages)
                  .Include(r => r.Recipients)
                  .Where(i => i.Recipients.Any(i => i.UserId == userId));
          }
      

      将此添加到 StartUp.cs

      services.AddHttpContextAccessor();
      

      加上使用 JwtParser

      public static class JwtParser
      {
          public static IEnumerable<Claim> ParseClaimsFromJwt(string jwt)
          {
              List<Claim> claims = new();
              string payload = jwt.Split('.')[1];
              byte[] jsonBytes = ParseBase64WithoutPadding(payload);
              Dictionary<string, object> keyValuePairs = JsonSerializer.Deserialize<Dictionary<string, object>>(jsonBytes);
              ExtractRolesFromJwt(claims, keyValuePairs);
              claims.AddRange(keyValuePairs.Select(kvp => new Claim(kvp.Key, kvp.Value.ToString())));
              return claims;
          }
      
          private static void ExtractRolesFromJwt(List<Claim> claims, Dictionary<string, object> keyValuePairs)
          {
              keyValuePairs.TryGetValue(ClaimTypes.Role, out object roles);
              if (roles is null) return;
              string[] parsedRoles = roles.ToString().Trim().TrimStart('[').TrimEnd(']').Split(',');
              if (parsedRoles.Length > 1)
              {
                  foreach (string parsedRole in parsedRoles)
                  {
                      claims.Add(new Claim(ClaimTypes.Role, parsedRole.Trim('"')));
                  }
              }
              else
              {
                  claims.Add(new Claim(ClaimTypes.Role, parsedRoles[0]));
              }
              keyValuePairs.Remove(ClaimTypes.Role);
          }
      
          private static byte[] ParseBase64WithoutPadding(string base64)
          {
              switch (base64.Length % 4)
              {
                  case 2:
                      base64 += "==";
                      break;
                  case 3:
                      base64 += "=";
                      break;
              }
              return Convert.FromBase64String(base64);
          }
      }
      

      这是我开始做的事情。有没有更好的解决方案或者这是否足够好?

      【讨论】:

        猜你喜欢
        • 2022-10-25
        • 1970-01-01
        • 2020-12-22
        • 2021-11-24
        • 2020-08-21
        • 2022-01-04
        • 2020-11-13
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多