WebAuthn Credentials.Create 异常
WebAuthn Credentials.Create Exception
我为此苦苦挣扎的时间比我愿意承认的要长。我只是想使用 WebAutn 注册一个新设备。我已经尝试了至少两个不同的示例并检查了许多不同的代码。我似乎做的一切都是对的......但无论我做什么,我总是得到同样无益的异常。我在网上搜索了一下,似乎没有其他人收到此异常,所以我真的不知道出了什么问题?
简而言之,在线 newCredential = await navigator.credentials.create({publicKey: options});我收到此错误:“异常:TypeError:无法在 'CredentialsContainer' 上执行 'create':提供的值‘2’不是 AttestationConveyancePreference 类型的有效枚举值。”
这是返回的 PublicKeyCredentialCreationOptions,我正在提交:注意: 质询和 user.id 都已填充,但由于它们是 ArrayBuffer() 的,所以它们不打印。
{
"rp": {
"id": "someserver",
"name": "IB-Fido2",
"icon": null
},
"user": {
"name": "fred@someserver.com",
"id": {},
"displayName": "Fred Sampson"
},
"challenge": {},
"pubKeyCredParams": [
{
"type": 0,
"alg": -7
},
{
"type": 0,
"alg": -257
},
{
"type": 0,
"alg": -37
},
{
"type": 0,
"alg": -35
},
{
"type": 0,
"alg": -258
},
{
"type": 0,
"alg": -38
},
{
"type": 0,
"alg": -36
},
{
"type": 0,
"alg": -259
},
{
"type": 0,
"alg": -39
}
],
"timeout": 60000,
"attestation": 0,
"authenticatorSelection": {
"requireResidentKey": false,
"userVerification": 1
},
"excludeCredentials": [],
"extensions": null,
"status": "ok",
"errorMessage": ""
}
如有任何帮助或建议,我们将不胜感激!
更新: 序列化/反序列化对象已经有一段时间了……但几乎总是针对 C# 而不是 JavaScript……因此我不知道JavaScripts String Enum 直到我遇到这个问题。我看到这是一个转换错误,但错误地认为 Fido2NetLib 必须返回所需的对象,因为没有其他人用它报告错误。
谢天谢地 Newtonsoft.Json 已经有了扩展,可以很容易地完成这个覆盖,这是我从 here 中发现的。
因此最后我不得不使用 StringEnumConverter() 序列化对象,然后将其反序列化回自定义 class 我从 json 创建的自定义 class 这是完全相同的东西,但使用 String Enum值。我需要那样做,因为将 Json 传递给 Blazor.Interop 是行不通的……它需要一个实际的对象。最后,我确信有一种更简洁的方法可以使用 String Enum 进行转换,但想要继续前进,我现在正在使用它。参见:
string url = string.Format("{0}{1}", Endpoints.UsersFidoOptions, userId);
var options = await userRepository.FidoOptions(url);
if (options != null)
{
if (options.Status != "ok")
{
//Error Message
}
else
{
try
{
// Serialize returned options: NOTE: String Enum Converter necessary as this object has JavaScript String Enum's
string json = JsonConvert.SerializeObject(options, new Newtonsoft.Json.Converters.StringEnumConverter());
// Next Deserialize into Custom Object to Compensate for String Enum's
var pubKey = Newtonsoft.Json.JsonConvert.DeserializeObject<PublicKey>(json);
// Now Serialize the Public Key for Session Storage
string pkJson = JsonConvert.SerializeObject(pubKey, new Newtonsoft.Json.Converters.StringEnumConverter());
await sessionStorage.SetItemAsync<string>("fido2.attestationOptions", pkJson);
await jsRuntime.InvokeVoidAsync("blazorInterop.registerOptions", pubKey);
}
catch (JSException e)
{
string err = e.Message;
}
}
}
构建此 JSON 时,它插入的是枚举数值而不是字符串值。例如,在 pubKeyCredParams 中,所有类型值都应该是“public-key”,而不是 0,证明应该是“none”而不是 0,userVerification 应该是“preferred”,而不是 1 . 在规范 https://www.w3.org/TR/webauthn/.
中都被定义为 DOMString
我为此苦苦挣扎的时间比我愿意承认的要长。我只是想使用 WebAutn 注册一个新设备。我已经尝试了至少两个不同的示例并检查了许多不同的代码。我似乎做的一切都是对的......但无论我做什么,我总是得到同样无益的异常。我在网上搜索了一下,似乎没有其他人收到此异常,所以我真的不知道出了什么问题?
简而言之,在线 newCredential = await navigator.credentials.create({publicKey: options});我收到此错误:“异常:TypeError:无法在 'CredentialsContainer' 上执行 'create':提供的值‘2’不是 AttestationConveyancePreference 类型的有效枚举值。”
这是返回的 PublicKeyCredentialCreationOptions,我正在提交:注意: 质询和 user.id 都已填充,但由于它们是 ArrayBuffer() 的,所以它们不打印。
{
"rp": {
"id": "someserver",
"name": "IB-Fido2",
"icon": null
},
"user": {
"name": "fred@someserver.com",
"id": {},
"displayName": "Fred Sampson"
},
"challenge": {},
"pubKeyCredParams": [
{
"type": 0,
"alg": -7
},
{
"type": 0,
"alg": -257
},
{
"type": 0,
"alg": -37
},
{
"type": 0,
"alg": -35
},
{
"type": 0,
"alg": -258
},
{
"type": 0,
"alg": -38
},
{
"type": 0,
"alg": -36
},
{
"type": 0,
"alg": -259
},
{
"type": 0,
"alg": -39
}
],
"timeout": 60000,
"attestation": 0,
"authenticatorSelection": {
"requireResidentKey": false,
"userVerification": 1
},
"excludeCredentials": [],
"extensions": null,
"status": "ok",
"errorMessage": ""
}
如有任何帮助或建议,我们将不胜感激!
更新: 序列化/反序列化对象已经有一段时间了……但几乎总是针对 C# 而不是 JavaScript……因此我不知道JavaScripts String Enum 直到我遇到这个问题。我看到这是一个转换错误,但错误地认为 Fido2NetLib 必须返回所需的对象,因为没有其他人用它报告错误。
谢天谢地 Newtonsoft.Json 已经有了扩展,可以很容易地完成这个覆盖,这是我从 here 中发现的。
因此最后我不得不使用 StringEnumConverter() 序列化对象,然后将其反序列化回自定义 class 我从 json 创建的自定义 class 这是完全相同的东西,但使用 String Enum值。我需要那样做,因为将 Json 传递给 Blazor.Interop 是行不通的……它需要一个实际的对象。最后,我确信有一种更简洁的方法可以使用 String Enum 进行转换,但想要继续前进,我现在正在使用它。参见:
string url = string.Format("{0}{1}", Endpoints.UsersFidoOptions, userId);
var options = await userRepository.FidoOptions(url);
if (options != null)
{
if (options.Status != "ok")
{
//Error Message
}
else
{
try
{
// Serialize returned options: NOTE: String Enum Converter necessary as this object has JavaScript String Enum's
string json = JsonConvert.SerializeObject(options, new Newtonsoft.Json.Converters.StringEnumConverter());
// Next Deserialize into Custom Object to Compensate for String Enum's
var pubKey = Newtonsoft.Json.JsonConvert.DeserializeObject<PublicKey>(json);
// Now Serialize the Public Key for Session Storage
string pkJson = JsonConvert.SerializeObject(pubKey, new Newtonsoft.Json.Converters.StringEnumConverter());
await sessionStorage.SetItemAsync<string>("fido2.attestationOptions", pkJson);
await jsRuntime.InvokeVoidAsync("blazorInterop.registerOptions", pubKey);
}
catch (JSException e)
{
string err = e.Message;
}
}
}
构建此 JSON 时,它插入的是枚举数值而不是字符串值。例如,在 pubKeyCredParams 中,所有类型值都应该是“public-key”,而不是 0,证明应该是“none”而不是 0,userVerification 应该是“preferred”,而不是 1 . 在规范 https://www.w3.org/TR/webauthn/.
中都被定义为 DOMString