25'ten fazla konu seçemezsiniz Konular bir harf veya rakamla başlamalı, kısa çizgiler ('-') içerebilir ve en fazla 35 karakter uzunluğunda olabilir.

124 satır
3.7KB

  1. using System.Security.Claims;
  2. using System.Text.Json;
  3. namespace Campaign_Tracker.Server.Authorization;
  4. public static class ApplicationRole
  5. {
  6. public const string ClientServices = "ClientServices";
  7. public const string Production = "Production";
  8. public const string Transportation = "Transportation";
  9. public const string Support = "Support";
  10. public const string Admin = "Admin";
  11. private static readonly IReadOnlyDictionary<string, string> Aliases =
  12. new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase)
  13. {
  14. ["client-services"] = ClientServices,
  15. ["clientservices"] = ClientServices,
  16. ["production-lead"] = Production,
  17. ["production"] = Production,
  18. ["transportation"] = Transportation,
  19. ["support-analyst"] = Support,
  20. ["support"] = Support,
  21. ["operations-admin"] = Admin,
  22. ["admin"] = Admin,
  23. };
  24. public static string? Normalize(string role)
  25. {
  26. return Aliases.TryGetValue(role, out var normalized) ? normalized : null;
  27. }
  28. public static string[] NormalizeMany(IEnumerable<string> roles)
  29. {
  30. return roles
  31. .Select(Normalize)
  32. .OfType<string>()
  33. .Distinct(StringComparer.OrdinalIgnoreCase)
  34. .ToArray();
  35. }
  36. public static bool HasAny(IEnumerable<string> roles, params string[] requiredRoles)
  37. {
  38. var normalizedRoles = NormalizeMany(roles);
  39. return normalizedRoles.Contains(Admin, StringComparer.OrdinalIgnoreCase) ||
  40. normalizedRoles.Intersect(requiredRoles, StringComparer.OrdinalIgnoreCase).Any();
  41. }
  42. public static IEnumerable<string> ExtractKeycloakRoles(IEnumerable<Claim> claims, string clientId)
  43. {
  44. foreach (var claim in claims)
  45. {
  46. if (claim.Type == ClaimTypes.Role || claim.Type == "roles")
  47. {
  48. yield return claim.Value;
  49. continue;
  50. }
  51. if (claim.Type == "realm_access")
  52. {
  53. foreach (var role in ExtractRolesFromJson(claim.Value))
  54. {
  55. yield return role;
  56. }
  57. continue;
  58. }
  59. if (claim.Type == "resource_access")
  60. {
  61. foreach (var role in ExtractResourceRolesFromJson(claim.Value, clientId))
  62. {
  63. yield return role;
  64. }
  65. }
  66. }
  67. }
  68. private static IEnumerable<string> ExtractRolesFromJson(string json)
  69. {
  70. using var document = ParseJsonOrDefault(json);
  71. if (document is null ||
  72. !document.RootElement.TryGetProperty("roles", out var roles) ||
  73. roles.ValueKind != JsonValueKind.Array)
  74. {
  75. yield break;
  76. }
  77. foreach (var role in roles.EnumerateArray())
  78. {
  79. if (role.ValueKind == JsonValueKind.String)
  80. {
  81. yield return role.GetString()!;
  82. }
  83. }
  84. }
  85. private static IEnumerable<string> ExtractResourceRolesFromJson(string json, string clientId)
  86. {
  87. using var document = ParseJsonOrDefault(json);
  88. if (document is null ||
  89. !document.RootElement.TryGetProperty(clientId, out var clientAccess))
  90. {
  91. yield break;
  92. }
  93. foreach (var role in ExtractRolesFromJson(clientAccess.GetRawText()))
  94. {
  95. yield return role;
  96. }
  97. }
  98. private static JsonDocument? ParseJsonOrDefault(string json)
  99. {
  100. try
  101. {
  102. return JsonDocument.Parse(json);
  103. }
  104. catch (JsonException)
  105. {
  106. return null;
  107. }
  108. }
  109. }

Powered by TurnKey Linux.