[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);
}
}
这是我开始做的事情。有没有更好的解决方案或者这是否足够好?