using Fido2NetLib; using Fido2NetLib.Objects; using System.Text.Json; using System.Text.Json.Serialization; namespace CloudBuilder.Security.Service { /// /// 登录阶段,下发给前端的断言选项模型,对应 CredentialGetOptions /// public sealed class AssertionOptionsModel { [JsonPropertyName("challenge")] public string Challenge { get; init; } /// /// 依赖方ID,域名,例如 localhost / example.com /// [JsonPropertyName("rpId")] public string RpId { get; init; } /// /// 允许使用的凭证列表,告诉浏览器该用户有哪些已绑定凭证 /// [JsonPropertyName("allowCredentials")] public PublicKeyCredentialDescriptor[] AllowCredentials { get; init; } /// /// 用户验证策略:preferred|required|discouraged /// [JsonPropertyName("userVerification")] public UserVerificationRequirement UserVerification { get; init; } /// /// 超时毫秒 /// [JsonPropertyName("timeout")] public ulong Timeout { get; init; } // 可选扩展字段,如果业务用到可以加上 //[JsonPropertyName("extensions")] //public AuthenticationExtensionsClientInputs? Extensions { get; init; } /// /// 和Fido2NetLib原生风格对齐,从JSON字符串反序列化对象 /// /// 后端输出给前端的原始json /// public static AssertionOptionsModel FromJson(string json) { var opt = new JsonSerializerOptions { Converters = { new Base64UrlConverter() }, PropertyNameCaseInsensitive = false }; return JsonSerializer.Deserialize(json, opt)!; } /// /// 序列化为给前端消费的JSON(challenge/id自动Base64Url编码) /// public string ToJson() { var opt = new JsonSerializerOptions { Converters = { new Base64UrlConverter() }, WriteIndented = false }; return JsonSerializer.Serialize(this, opt); } } }