using System.ComponentModel.DataAnnotations;
using OpenIddict.Abstractions;

namespace Dpz.Core.Auth.Models.AdminApi;

/// <summary>
/// 创建 OAuth 2.0 / OpenID Connect 应用请求
/// </summary>
public class CreateAuthApplicationRequest : AdminMfaRequest, IValidatableObject
{
    /// <summary>
    /// 客户端唯一标识符
    /// </summary>
    [Required(ErrorMessage = "请填写 ClientId")]
    public string ClientId { get; set; } = string.Empty;

    /// <summary>
    /// 客户端密钥(机密客户端必填)
    /// </summary>
    public string? ClientSecret { get; set; }

    /// <summary>
    /// 应用显示名称
    /// </summary>
    [Required(ErrorMessage = "请填写显示名称")]
    public string DisplayName { get; set; } = string.Empty;

    /// <summary>
    /// 应用 Logo URL
    /// </summary>
    public string? Logo { get; set; }

    /// <summary>
    /// 应用类型(如 "web"、"native"、"spa")
    /// </summary>
    public string? ApplicationType { get; set; }

    /// <summary>
    /// 客户端类型(公开 / 机密)
    /// </summary>
    [Required(ErrorMessage = "请选择客户端类型")]
    public string ClientType { get; set; } = string.Empty;

    /// <summary>
    /// 允许的回调地址列表
    /// </summary>
    public List<string> RedirectUris { get; set; } = [];

    /// <summary>
    /// 登出后的回调地址
    /// </summary>
    public string? PostLogoutRedirectUri { get; set; }

    /// <summary>
    /// 授权许可列表(如 "openid"、"profile"、"email")
    /// </summary>
    public List<string> Permissions { get; set; } = [];

    /// <summary>
    /// 验证机密客户端必须提供 ClientSecret
    /// </summary>
    public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
    {
        if (
            string.Equals(
                ClientType,
                OpenIddictConstants.ClientTypes.Confidential,
                StringComparison.OrdinalIgnoreCase
            ) && string.IsNullOrWhiteSpace(ClientSecret)
        )
        {
            yield return new ValidationResult(
                "机密客户端需填写 ClientSecret",
                [nameof(ClientSecret)]
            );
        }
    }
}
⚠⚠    以下内容为AI分析的结果,请根据实际情况进行判断。

代码解释

这是一个 C# 数据模型类,用于创建 OAuth 2.0 / OpenID Connect 应用程序的请求。

主要组成部分

1. 命名空间和引用

using System.ComponentModel.DataAnnotations;
using OpenIddict.Abstractions;
  • 引入数据注解验证功能
  • 引入 OpenIddict 库(OpenID Connect 和 OAuth 2.0 的实现框架)

2. 类定义

public class CreateAuthApplicationRequest : AdminMfaRequest, IValidatableObject
  • 继承自 AdminMfaRequest(管理员多因素认证请求基类)
  • 实现 IValidatableObject 接口,支持自定义验证逻辑

3. 属性说明

属性类型必填说明
ClientIdstring客户端唯一标识符
ClientSecretstring?条件必填客户端密钥(机密客户端时必填)
DisplayNamestring应用显示名称
Logostring?应用 Logo URL
ApplicationTypestring?应用类型(web/native/spa)
ClientTypestring客户端类型(公开/机密)
RedirectUrisList<string>OAuth 回调地址列表
PostLogoutRedirectUristring?登出后重定向地址
PermissionsList<string>权限范围列表(如 openid, profile)

4. 自定义验证逻辑

public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)

验证规则

  • ClientType机密客户端(Confidential)时
  • 必须提供 ClientSecret
  • 否则返回验证错误:"机密客户端需填写 ClientSecret"

设计特点

  1. 数据注解验证:使用 [Required] 特性进行基础验证
  2. 自定义验证:通过 IValidatableObject 实现复杂的业务规则验证
  3. OAuth 2.0 标准:遵循标准的客户端注册流程
  4. 安全性考虑:区分公开客户端和机密客户端,强制机密客户端提供密钥
  5. 现代 C# 语法:使用集合表达式 [] 和可空引用类型 ?

使用场景

这个模型通常用于管理后台,允许管理员创建新的 OAuth 2.0 客户端应用程序,例如注册第三方应用、内部微服务等。

评论加载中...