【问题标题】:webauthn authentication javascript formatting assistancewebauthn 身份验证 javascript 格式化帮助
【发布时间】:2020-05-14 13:30:32
【问题描述】:

我一直在试图弄清楚如何使用 webauthn 进行 2fa,并且我的注册部分正在工作。详细信息的文档记录确实很差,尤其是 javascript 中的所有编码有效负载。我可以向用户注册设备,但无法使用该设备进行身份验证。作为参考,我正在使用这些资源:

https://github.com/cedarcode/webauthn-ruby

https://www.passwordless.dev/js/mfa.register.js

具体来说,对于身份验证,我正在尝试模仿这个 js 功能:

https://www.passwordless.dev/js/mfa.register.js

在我的用户模型中,我有一个 webauthn_id 和几个 u2f 设备,每个设备都有一个 public_key 和一个 webauthn_id。

在我的 Rails 应用程序中,我这样做:

options = WebAuthn::Credential.options_for_get(allow: :webauthn_id)
session[:webauthn_options] = options

在我的 javascript 中,我尝试模仿上面的 js 文件,然后我做了(这是嵌入的 ruby​​):

options = <%= raw @options.as_json.to_json %>
options.challenge = WebAuthnHelpers.coerceToArrayBuffer(options.challenge);
options.allowCredentials = options.allowCredentials.map((c) => {
    c.id = WebAuthnHelpers.coerceToArrayBuffer(c.id);
    return c;
});

navigator.credentials.get({ "publicKey": options }).then(function (credentialInfoAssertion) 
{
            // send assertion response back to the server
            // to proceed with the control of the credential
alert('here');
}).catch(function (err) 
{
    debugger
    console.error(err);   /*  THIS IS WHERE THE ERROR IS THROWN */
});

问题是,我无法通过 navigator.credentials.get,我在 javascript 控制台中收到此错误:

TypeError: CredentialsContainer.get: Element of 'allowCredentials' member of PublicKeyCredentialRequestOptions can't be converted to a dictionary

调用 navigator.credentials.get 时的选项如下所示:

我已经尝试了各种方法将我的数据库存储的用户和设备变量转换为正确编码和解析的 javascript 变量,但似乎无法让它工作。有什么明显的我做错了什么吗?

感谢您的帮助, 凯文

更新 -

添加服务器生成的选项json:

"{\"challenge\":\"SSDYi4I7kRWt5wc5KjuAvgJ3dsQhjy7IPOJ0hvR5tMg\",\"timeout\":120000,\"allowCredentials\":[{\"type\":\"public-key\",\"id\":\"OUckfxGNLGGASUfGiX-1_8FzehlXh3fKvJ98tm59mVukJkKb_CGk1avnorL4sQQASVO9aGqmgn01jf629Jt0Z0SmBpDKd9sL1T5Z9loDrkLTTCIzrIRqhwPC6yrkfBFi\"},{\"type\":\"public-key\",\"id\":\"Fj5T-WPmEMTz139mY-Vo0DTfsNmjwy_mUx6jn5rUEPx-LsY51mxNYidprJ39_cHeAOieg-W12X47iJm42K0Tsixj4_Fl6KjdgYoxQtEYsNF-LPhwtoKwYsy1hZgVojp3\"}]}"

【问题讨论】:

    标签: javascript ruby-on-rails webauthn


    【解决方案1】:

    这是我们的实现返回的序列化 JSON 数据的示例:

    {
        "challenge": "MQ1S8MBSU0M2kiJqJD8wnQ",
        "timeout": 60000,
        "rpId": "identity.acme.com",
        "allowCredentials": [
            {
                "type": "public-key",
                "id": "k5Ti8dLdko1GANsBT-_NZ5L_-8j_8TnoNOYe8mUcs4o",
                "transports": [
                    "internal"
                ]
            },
            {
                "type": "public-key",
                "id": "LAqkKEO99XPCQ7fsUa3stz7K76A_mE5dQwX4S3QS6jdbI9ttSn9Hu37BA31JUGXqgyhTtskL5obe6uZxitbIfA",
                "transports": [
                    "usb"
                ]
            },
            {
                "type": "public-key",
                "id": "nbN3S08Wv2GElRsW9AmK70J1INEpwIywQcOl6rp_DWLm4mcQiH96TmAXSrZRHciZBENVB9rJdE94HPHbeVjtZg",
                "transports": [
                    "usb"
                ]
            }
        ],
        "userVerification": "discouraged",
        "extensions": {
            "txAuthSimple": "Sign in to your ACME account",
            "exts": true,
            "uvi": true,
            "loc": true,
            "uvm": true
        }
    }
    

    这被解析为一个对象,用于强制那些 base64url 编码值的代码是:

    credentialRequestOptions.challenge = WebAuthnHelpers.coerceToArrayBuffer(credentialRequestOptions.challenge);
    
    credentialRequestOptions.allowCredentials = credentialRequestOptions.allowCredentials.map((c) => {
        c.id = WebAuthnHelpers.coerceToArrayBuffer(c.id);
        return c;
    });
    

    希望对您有所帮助。 JSON 数据通过 fetch() 调用检索,并且 byte[] 字段在服务器端编码为 base64url。

    【讨论】:

    • 谢谢@mackie,你的payload和我的唯一区别是我没有rpId、userVerificaiton或扩展密钥,并且在allowedCredentials中,我没有传输。我正在取得进展,但现在在控制台中我得到“在当前上下文中,用户代理或平台不允许该请求,可能是因为用户拒绝了许可” - 有什么想法吗?如果有帮助,我会将我的选项添加到我的问题中。感谢您迄今为止的帮助。
    • 这些都是可选的,所以应该不是问题。这与这些 base64url 值如何转换为 ArrayBuffers 有关。该错误是直接从 navigator.credentials.get 返回的吗?
    • 是的,它实际上在 navigator.credentails.get 行的 catch 块中,我实际上更新了我的代码以匹配你的代码,让我用新代码更新我的问题,也许有些事情很明显跨度>
    • 好的,我已经用注释更新了代码,以便在发生错误的 catch 块中向您显示。非常感谢您在这方面的帮助。
    • 在我看来一切正常,很奇怪!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-14
    • 1970-01-01
    • 1970-01-01
    • 2020-08-28
    • 2012-03-18
    • 2020-12-08
    相关资源
    最近更新 更多