网站首页 网站源码
website
站点相关全部源代码,隐藏了一些关于服务器的信息
using System.Collections.Concurrent;
using System.Reflection;
using System.Security.Claims;

namespace Dpz.Core.Auth;

public static class AuthHelper
{
    private static readonly HashSet<string> AllowedPermissionGroups = new(StringComparer.Ordinal)
    {
        "Endpoints",
        "GrantTypes",
        "ResponseTypes",
        "Scopes",
    };

    public static readonly Lazy<Dictionary<string, List<string>>> OpenIddictPermissionCache = new(
        GetPermissionGroups
    );

    private static Dictionary<string, List<string>> GetPermissionGroups()
    {
        const BindingFlags flags =
            BindingFlags.Public | BindingFlags.Static | BindingFlags.FlattenHierarchy;
        var groups = new Dictionary<string, List<string>>(StringComparer.Ordinal);
        foreach (
            var t in typeof(OpenIddict.Abstractions.OpenIddictConstants.Permissions).GetNestedTypes()
        )
        {
            if (!AllowedPermissionGroups.Contains(t.Name))
            {
                continue;
            }
            var values = t.GetFields(flags)
                .Where(f =>
                    f is { IsLiteral: true, IsInitOnly: false } && f.FieldType == typeof(string)
                )
                .Select(f => (string)f.GetRawConstantValue()!)
                .OrderBy(x => x, StringComparer.Ordinal)
                .ToList();
            if (values.Count > 0)
            {
                groups[t.Name] = values;
            }
        }
        return groups;
    }

    private static readonly ConcurrentDictionary<string, string> AuthorizationDescription = new(
        StringComparer.OrdinalIgnoreCase
    );

    private static readonly ConcurrentDictionary<string, string> TokenStatusDescription = new(
        StringComparer.OrdinalIgnoreCase
    );

    private static readonly ConcurrentDictionary<string, string> TokenTypeDescription = new(
        StringComparer.OrdinalIgnoreCase
    );

    static AuthHelper()
    {
        AuthorizationDescription.TryAdd("valid", "有效");
        AuthorizationDescription.TryAdd("revoked", "已撤销");
        AuthorizationDescription.TryAdd("inactive", "禁用");
        AuthorizationDescription.TryAdd("ad-hoc", "临时授权");
        AuthorizationDescription.TryAdd("permanent", "永久授权");

        TokenStatusDescription.TryAdd("valid", "有效");
        TokenStatusDescription.TryAdd("revoked", "已撤销");
        TokenStatusDescription.TryAdd("expired", "已过期");
        TokenStatusDescription.TryAdd("invalid", "无效");
        TokenStatusDescription.TryAdd("inactive", "未激活");
        TokenStatusDescription.TryAdd("used", "已使用");
        TokenStatusDescription.TryAdd("replaced", "已替换");
        TokenStatusDescription.TryAdd("redeemed", "已兑换");

        TokenTypeDescription.TryAdd("access_token", "访问令牌");
        TokenTypeDescription.TryAdd("refresh_token", "刷新令牌");
        TokenTypeDescription.TryAdd("device_code", "设备码");
        TokenTypeDescription.TryAdd("authorization_code", "授权码");
        TokenTypeDescription.TryAdd("id_token", "身份令牌");
        TokenTypeDescription.TryAdd("oidc_principal", "OIDC 主体令牌");
        TokenTypeDescription.TryAdd("reference_token", "引用令牌");
        TokenTypeDescription.TryAdd("personal_access_token", "个人访问令牌");
    }

    public static string GetAuthorizationDescription(string? key)
    {
        if (string.IsNullOrWhiteSpace(key))
        {
            return "-";
        }

        if (AuthorizationDescription.TryGetValue(key, out var value))
        {
            return value;
        }

        return key;
    }

    public static string GetTokenStatusDescription(string? key)
    {
        if (string.IsNullOrWhiteSpace(key))
        {
            return "-";
        }

        var dictKey = TokenStatusDescription.Keys.FirstOrDefault(x =>
            key.EndsWith(x, StringComparison.OrdinalIgnoreCase)
        );
        if (dictKey == null)
        {
            return "-";
        }
        return TokenStatusDescription[dictKey];
    }

    public static string GetTokenTypeDescription(string? key)
    {
        if (string.IsNullOrWhiteSpace(key))
        {
            return "-";
        }

        var dictKey = TokenTypeDescription.Keys.FirstOrDefault(x =>
            key.EndsWith(x, StringComparison.OrdinalIgnoreCase)
        );
        if (dictKey == null)
        {
            return "-";
        }
        return TokenTypeDescription[dictKey];
    }

    extension(ClaimsPrincipal principal)
    {
        /// <summary>
        /// 账号 用户ID
        /// </summary>
        public string? NameIdentifier => principal.FindFirst(ClaimTypes.NameIdentifier)?.Value;
    }
}
⚠⚠    以下内容为AI分析的结果,请根据实际情况进行判断。

这段代码定义了一个名为 AuthHelper 的静态类,主要用于处理与身份验证和授权相关的功能。以下是代码的主要组成部分和功能的详细解释:

1. AllowedPermissionGroups

这是一个 HashSet<string>,包含了允许的权限组名称。它用于过滤在后续代码中处理的权限组。

2. OpenIddictPermissionCache

这是一个 Lazy<Dictionary<string, List<string>>>,用于缓存 OpenIddict 的权限组。它在第一次访问时会调用 GetPermissionGroups 方法来填充数据。

3. GetPermissionGroups 方法

这个私有方法使用反射来获取 OpenIddict 中的权限组。它会遍历 OpenIddict.Abstractions.OpenIddictConstants.Permissions 类的嵌套类型,并检查这些类型的名称是否在 AllowedPermissionGroups 中。如果是,它会获取该类型中所有的字符串常量字段,并将它们按字母顺序排序,最终将结果存储在一个字典中,字典的键是权限组的名称,值是该组中的权限列表。

4. 描述字典

代码中定义了三个 ConcurrentDictionary<string, string>,分别用于存储授权状态、令牌状态和令牌类型的描述。这些字典在静态构造函数中被初始化,提供了英文状态的中文翻译。

  • AuthorizationDescription: 存储授权状态的描述,如 "valid" 对应 "有效"。
  • TokenStatusDescription: 存储令牌状态的描述,如 "expired" 对应 "已过期"。
  • TokenTypeDescription: 存储令牌类型的描述,如 "access_token" 对应 "访问令牌"。

5. 获取描述的方法

代码提供了三个公共方法,用于根据给定的键获取相应的描述:

  • GetAuthorizationDescription: 根据授权状态的键返回对应的中文描述。如果键为空或未找到,则返回 "-"
  • GetTokenStatusDescription: 根据令牌状态的键返回对应的中文描述。它会检查键是否以字典中的某个键结尾,并返回相应的描述。
  • GetTokenTypeDescription: 类似于 GetTokenStatusDescription,但用于令牌类型。

6. ClaimsPrincipal 扩展方法

代码中定义了一个扩展方法,用于 ClaimsPrincipal 类型。这个扩展方法提供了一个属性 NameIdentifier,用于获取用户的 ID(即 ClaimTypes.NameIdentifier 的值)。如果没有找到该声明,则返回 null

总结

整体而言,这段代码的功能是提供一个帮助类,用于处理与身份验证和授权相关的操作,包括获取权限组、描述授权状态、令牌状态和令牌类型的中文翻译,以及扩展 ClaimsPrincipal 以获取用户 ID。它利用了反射、并发字典和延迟加载等技术来提高性能和可维护性。

loading