nextcloud / server

☁️ Nextcloud server, a safe home for all your data
https://nextcloud.com
GNU Affero General Public License v3.0
26.89k stars 4.02k forks source link

Passwordless Authentication Fails in clean NC Installation #27662

Closed brueckner closed 3 years ago

brueckner commented 3 years ago

Steps to reproduce

  1. Install a fresh Nextcloud instance
  2. Log in and go to https://example.test/index.php/settings/user/security
  3. Set up a WebAuthn device (can be simulated with Chrome)
  4. Log out
  5. On the log in screen, click "Log in with a device"
  6. Enter your username
  7. Click "Log in"
  8. Authorize request with your WebAuthn device (or with simulated Chrome)

Expected behaviour

You should get logged on.

Actual behaviour

You are not logged in. Nothing visible to the user happens. No error message, nothing.

Server configuration

Operating system: Linux 5.4.0-70-generic x86_64

Web server: Apache 2.4.38

Database: MySQL 8.0.23

PHP version: 8.0.7

Nextcloud version: (see Nextcloud admin page) 21.0.2

Updated from an older Nextcloud/ownCloud or fresh install: fresh install

Where did you install Nextcloud from: ZIP file from the download page

List of activated apps:

App list ``` Enabled: - accessibility: 1.7.0 - activity: 2.14.3 - bruteforcesettings: 2.2.0 - cloud_federation_api: 1.4.0 - comments: 1.11.0 - contactsinteraction: 1.2.0 - dashboard: 7.1.0 - dav: 1.17.1 - federatedfilesharing: 1.11.0 - federation: 1.11.0 - files: 1.16.0 - files_pdfviewer: 2.1.0 - files_rightclick: 1.0.0 - files_sharing: 1.13.1 - files_trashbin: 1.11.0 - files_versions: 1.14.0 - files_videoplayer: 1.10.0 - firstrunwizard: 2.10.0 - logreader: 2.6.0 - lookup_server_connector: 1.9.0 - nextcloud_announcements: 1.10.0 - notifications: 2.9.0 - oauth2: 1.9.0 - password_policy: 1.11.0 - photos: 1.3.0 - privacy: 1.5.0 - provisioning_api: 1.11.0 - recommendations: 1.0.0 - serverinfo: 1.11.0 - settings: 1.3.0 - sharebymail: 1.11.0 - support: 1.4.0 - survey_client: 1.9.0 - systemtags: 1.11.0 - text: 3.2.0 - theming: 1.12.0 - twofactor_backupcodes: 1.10.0 - updatenotification: 1.11.0 - user_status: 1.1.1 - viewer: 1.5.0 - weather_status: 1.1.0 - workflowengine: 2.3.0 Disabled: - admin_audit - encryption - files_external - user_ldap ```

Are you using external storage, if yes which one: no

Are you using encryption: yes

Are you using an external user-backend, if yes which one: no

Client configuration

Browser: Chrome 91

Operating system: MacOS 11.3.1

Logs

Nextcloud log (data/nextcloud.log)

Nextcloud log ``` {"reqId":"Z9Z3J3n3TeOppz24bAv1","level":3,"time":"2021-06-24T12:57:32+00:00","remoteAddr":"127.0.0.1","user":"--","app":"index","method":"POST","url":"/index.php/login/webauthn/finish","message":{"Exception":"Doctrine\\DBAL\\Exception\\UniqueConstraintViolationException","Message":"An exception occurred while executing a query: SQLSTATE[23000]: Integrity constraint violation: 19 UNIQUE constraint failed: oc_webauthn.id","Code":19,"Trace":[{"file":"/path/to/nextcloud/3rdparty/doctrine/dbal/src/Connection.php","line":1728,"function":"convert","class":"Doctrine\\DBAL\\Driver\\API\\SQLite\\ExceptionConverter","type":"->","args":[{"xdebug_message":null,"__class__":"Doctrine\\DBAL\\Driver\\PDO\\Exception"},{"__class__":"Doctrine\\DBAL\\Query"}]},{"file":"/path/to/nextcloud/3rdparty/doctrine/dbal/src/Connection.php","line":1667,"function":"handleDriverException","class":"Doctrine\\DBAL\\Connection","type":"->","args":[{"xdebug_message":null,"__class__":"Doctrine\\DBAL\\Driver\\PDO\\Exception"},{"__class__":"Doctrine\\DBAL\\Query"}]},{"file":"/path/to/nextcloud/3rdparty/doctrine/dbal/src/Connection.php","line":1146,"function":"convertExceptionDuringQuery","class":"Doctrine\\DBAL\\Connection","type":"->","args":[{"xdebug_message":null,"__class__":"Doctrine\\DBAL\\Driver\\PDO\\Exception"},"INSERT INTO \"oc_webauthn\" (\"name\", \"uid\", \"public_key_credential_id\", \"data\", \"id\") VALUES(?, ?, ?, ?, ?)",["Chrome","***redacted username***","AZB0gw7O4VD7DTcziMcPmRwjwB+PaQOcwxyOVcA3UO1ErA+KhJiEhU45qfS4v4Yx0GF2RUS9mvzaCOzQmMI=","{\"publicKeyCredentialId\":\"AZB0gw7O4VD7DTcziMcPmRwjwB-PaQOcwxyOVcA3UO1ErA-KhJiEhU45qfS4v4Yx0GF2RUS9mvzaCOzQmMI\",\"type\":\"public-key\",\"transports\":[],\"attestationType\":\"none\",\"trustPath\":{\"type\":\"Webauthn\\\\TrustPath\\\\EmptyTrustPath\"},\"aaguid\":\"00000000-0000-0000-0000-000000000000\",\"credentialPublicKey\":\"pQECAyYgASFYIPmtQTJ1lSxl-tB3uaeyl3sSuzppt01UmNtSMlGhMTyvIlgg1JJOVEQpsi0Xy65HEyv8rq4zJhOsyJw9hFfXBpIlF-Y\",\"userHandle\":\"am9oYW5uZXM\",\"counter\":1624539452}",1],[2,2,2,2,1]]},{"file":"/path/to/nextcloud/lib/private/DB/Connection.php","line":257,"function":"executeStatement","class":"Doctrine\\DBAL\\Connection","type":"->","args":["INSERT INTO \"oc_webauthn\" (\"name\", \"uid\", \"public_key_credential_id\", \"data\", \"id\") VALUES(?, ?, ?, ?, ?)",["Chrome","***redacted username***","AZB0gw7O4VD7DTcziMcPmRwjwB+PaQOcwxyOVcA3UO1ErA+KhJiEhU45qfS4v4Yx0GF2RUS9mvzaCOzQmMI=","{\"publicKeyCredentialId\":\"AZB0gw7O4VD7DTcziMcPmRwjwB-PaQOcwxyOVcA3UO1ErA-KhJiEhU45qfS4v4Yx0GF2RUS9mvzaCOzQmMI\",\"type\":\"public-key\",\"transports\":[],\"attestationType\":\"none\",\"trustPath\":{\"type\":\"Webauthn\\\\TrustPath\\\\EmptyTrustPath\"},\"aaguid\":\"00000000-0000-0000-0000-000000000000\",\"credentialPublicKey\":\"pQECAyYgASFYIPmtQTJ1lSxl-tB3uaeyl3sSuzppt01UmNtSMlGhMTyvIlgg1JJOVEQpsi0Xy65HEyv8rq4zJhOsyJw9hFfXBpIlF-Y\",\"userHandle\":\"am9oYW5uZXM\",\"counter\":1624539452}",1],[2,2,2,2,1]]},{"file":"/path/to/nextcloud/3rdparty/doctrine/dbal/src/Query/QueryBuilder.php","line":213,"function":"executeStatement","class":"OC\\DB\\Connection","type":"->","args":["INSERT INTO \"oc_webauthn\" (\"name\", \"uid\", \"public_key_credential_id\", \"data\", \"id\") VALUES(:dcValue1, :dcValue2, :dcValue3, :dcValue4, :dcValue5)",{"dcValue1":"Chrome","dcValue2":"***redacted username***","dcValue3":"AZB0gw7O4VD7DTcziMcPmRwjwB+PaQOcwxyOVcA3UO1ErA+KhJiEhU45qfS4v4Yx0GF2RUS9mvzaCOzQmMI=","dcValue4":"{\"publicKeyCredentialId\":\"AZB0gw7O4VD7DTcziMcPmRwjwB-PaQOcwxyOVcA3UO1ErA-KhJiEhU45qfS4v4Yx0GF2RUS9mvzaCOzQmMI\",\"type\":\"public-key\",\"transports\":[],\"attestationType\":\"none\",\"trustPath\":{\"type\":\"Webauthn\\\\TrustPath\\\\EmptyTrustPath\"},\"aaguid\":\"00000000-0000-0000-0000-000000000000\",\"credentialPublicKey\":\"pQECAyYgASFYIPmtQTJ1lSxl-tB3uaeyl3sSuzppt01UmNtSMlGhMTyvIlgg1JJOVEQpsi0Xy65HEyv8rq4zJhOsyJw9hFfXBpIlF-Y\",\"userHandle\":\"am9oYW5uZXM\",\"counter\":1624539452}","dcValue5":1},{"dcValue1":2,"dcValue2":2,"dcValue3":2,"dcValue4":2,"dcValue5":1}]},{"file":"/path/to/nextcloud/lib/private/DB/QueryBuilder/QueryBuilder.php","line":287,"function":"execute","class":"Doctrine\\DBAL\\Query\\QueryBuilder","type":"->","args":[]},{"file":"/path/to/nextcloud/lib/public/AppFramework/Db/QBMapper.php","line":135,"function":"execute","class":"OC\\DB\\QueryBuilder\\QueryBuilder","type":"->","args":[]},{"file":"/path/to/nextcloud/lib/public/AppFramework/Db/QBMapper.php","line":159,"function":"insert","class":"OCP\\AppFramework\\Db\\QBMapper","type":"->","args":[{"id":1,"__class__":"OC\\Authentication\\WebAuthn\\Db\\PublicKeyCredentialEntity"}]},{"file":"/path/to/nextcloud/lib/private/Authentication/WebAuthn/CredentialRepository.php","line":90,"function":"insertOrUpdate","class":"OCP\\AppFramework\\Db\\QBMapper","type":"->","args":[{"id":1,"__class__":"OC\\Authentication\\WebAuthn\\Db\\PublicKeyCredentialEntity"}]},{"file":"/path/to/nextcloud/lib/private/Authentication/WebAuthn/CredentialRepository.php","line":94,"function":"saveAndReturnCredentialSource","class":"OC\\Authentication\\WebAuthn\\CredentialRepository","type":"->","args":[{"__class__":"Webauthn\\PublicKeyCredentialSource"},"default"]},{"file":"/path/to/nextcloud/3rdparty/web-auth/webauthn-lib/src/AuthenticatorAssertionResponseValidator.php","line":206,"function":"saveCredentialSource","class":"OC\\Authentication\\WebAuthn\\CredentialRepository","type":"->","args":[{"__class__":"Webauthn\\PublicKeyCredentialSource"}]},{"file":"/path/to/nextcloud/lib/private/Authentication/WebAuthn/Manager.php","line":235,"function":"check","class":"Webauthn\\AuthenticatorAssertionResponseValidator","type":"->","args":[null,{"__class__":"Webauthn\\AuthenticatorAssertionResponse"},{"__class__":"Webauthn\\PublicKeyCredentialRequestOptions"},{"__class__":"GuzzleHttp\\Psr7\\ServerRequest"},"***redacted username***"]},{"file":"/path/to/nextcloud/core/Controller/WebAuthnController.php","line":107,"function":"finishAuthentication","class":"OC\\Authentication\\WebAuthn\\Manager","type":"->","args":[{"__class__":"Webauthn\\PublicKeyCredentialRequestOptions"},"{\"id\":\"AZB0gw7O4VD7DTcziMcPmRwjwB-PaQOcwxyOVcA3UO1ErA-KhJiEhU45qfS4v4Yx0GF2RUS9mvzaCOzQmMI\",\"type\":\"public-key\",\"rawId\":\"AZB0gw7O4VD7DTcziMcPmRwjwB+PaQOcwxyOVcA3UO1ErA+KhJiEhU45qfS4v4Yx0GF2RUS9mvzaCOzQmMI=\",\"response\":{\"authenticatorData\":\"PmfOdjbCeXFHXvDwXZyqMk4LvGagoDl6PRhqL89+3MQFYNSBPA==\",\"clientDataJSON\":\"eyJ0eXBlIjoid2ViYXV0aG4uZ2V0IiwiY2hhbGxlbmdlIjoib0ZCZEpsaXdWTFlRNzF1a18tT3BIRTVnRHd2bVlFeEgyZDJqa2EyMXNiWSIsIm9yaWdpbiI6Imh0dHBzOi8vbmN3ZWJhdXRobi50ZXN0IiwiY3Jvc3NPcmlnaW4iOmZhbHNlfQ==\",\"signature\":\"MEUCIQDy6hHniCRGSD7RXghbZI57ghJOWYLLlVuANsAptRN6NwIgH/ksTNEkKP1HB706PJxqyq3N+ofraaxc1kZHiFLFqE4=\",\"userHandle\":\"am9oYW5uZXM=\"}}","***redacted username***"]},{"file":"/path/to/nextcloud/lib/private/AppFramework/Http/Dispatcher.php","line":218,"function":"finishAuthentication","class":"OC\\Core\\Controller\\WebAuthnController","type":"->","args":["{\"id\":\"AZB0gw7O4VD7DTcziMcPmRwjwB-PaQOcwxyOVcA3UO1ErA-KhJiEhU45qfS4v4Yx0GF2RUS9mvzaCOzQmMI\",\"type\":\"public-key\",\"rawId\":\"AZB0gw7O4VD7DTcziMcPmRwjwB+PaQOcwxyOVcA3UO1ErA+KhJiEhU45qfS4v4Yx0GF2RUS9mvzaCOzQmMI=\",\"response\":{\"authenticatorData\":\"PmfOdjbCeXFHXvDwXZyqMk4LvGagoDl6PRhqL89+3MQFYNSBPA==\",\"clientDataJSON\":\"eyJ0eXBlIjoid2ViYXV0aG4uZ2V0IiwiY2hhbGxlbmdlIjoib0ZCZEpsaXdWTFlRNzF1a18tT3BIRTVnRHd2bVlFeEgyZDJqa2EyMXNiWSIsIm9yaWdpbiI6Imh0dHBzOi8vbmN3ZWJhdXRobi50ZXN0IiwiY3Jvc3NPcmlnaW4iOmZhbHNlfQ==\",\"signature\":\"MEUCIQDy6hHniCRGSD7RXghbZI57ghJOWYLLlVuANsAptRN6NwIgH/ksTNEkKP1HB706PJxqyq3N+ofraaxc1kZHiFLFqE4=\",\"userHandle\":\"am9oYW5uZXM=\"}}"]},{"file":"/path/to/nextcloud/lib/private/AppFramework/Http/Dispatcher.php","line":127,"function":"executeController","class":"OC\\AppFramework\\Http\\Dispatcher","type":"->","args":[{"__class__":"OC\\Core\\Controller\\WebAuthnController"},"finishAuthentication"]},{"file":"/path/to/nextcloud/lib/private/AppFramework/App.php","line":157,"function":"dispatch","class":"OC\\AppFramework\\Http\\Dispatcher","type":"->","args":[{"__class__":"OC\\Core\\Controller\\WebAuthnController"},"finishAuthentication"]},{"file":"/path/to/nextcloud/lib/private/Route/Router.php","line":302,"function":"main","class":"OC\\AppFramework\\App","type":"::","args":["OC\\Core\\Controller\\WebAuthnController","finishAuthentication",{"__class__":"OC\\AppFramework\\DependencyInjection\\DIContainer"},{"_route":"core.WebAuthn.finishAuthentication"}]},{"file":"/path/to/nextcloud/lib/base.php","line":993,"function":"match","class":"OC\\Route\\Router","type":"->","args":["/login/webauthn/finish"]},{"file":"/path/to/nextcloud/index.php","line":37,"function":"handleRequest","class":"OC","type":"::","args":[]},{"file":"/Users/brueckner/.composer/vendor/laravel/valet/server.php","line":235,"args":["/path/to/nextcloud/index.php"],"function":"require"}],"File":"/path/to/nextcloud/3rdparty/doctrine/dbal/src/Driver/API/SQLite/ExceptionConverter.php","Line":44,"Previous":{"Exception":"Doctrine\\DBAL\\Driver\\PDO\\Exception","Message":"SQLSTATE[23000]: Integrity constraint violation: 19 UNIQUE constraint failed: oc_webauthn.id","Code":19,"Trace":[{"file":"/path/to/nextcloud/3rdparty/doctrine/dbal/src/Driver/PDO/Statement.php","line":84,"function":"new","class":"Doctrine\\DBAL\\Driver\\PDO\\Exception","type":"::","args":[{"errorInfo":["23000",19,"UNIQUE constraint failed: oc_webauthn.id"],"xdebug_message":null,"__class__":"PDOException"}]},{"file":"/path/to/nextcloud/3rdparty/doctrine/dbal/src/Connection.php","line":1136,"function":"execute","class":"Doctrine\\DBAL\\Driver\\PDO\\Statement","type":"->","args":[]},{"file":"/path/to/nextcloud/lib/private/DB/Connection.php","line":257,"function":"executeStatement","class":"Doctrine\\DBAL\\Connection","type":"->","args":["INSERT INTO \"oc_webauthn\" (\"name\", \"uid\", \"public_key_credential_id\", \"data\", \"id\") VALUES(?, ?, ?, ?, ?)",["Chrome","***redacted username***","AZB0gw7O4VD7DTcziMcPmRwjwB+PaQOcwxyOVcA3UO1ErA+KhJiEhU45qfS4v4Yx0GF2RUS9mvzaCOzQmMI=","{\"publicKeyCredentialId\":\"AZB0gw7O4VD7DTcziMcPmRwjwB-PaQOcwxyOVcA3UO1ErA-KhJiEhU45qfS4v4Yx0GF2RUS9mvzaCOzQmMI\",\"type\":\"public-key\",\"transports\":[],\"attestationType\":\"none\",\"trustPath\":{\"type\":\"Webauthn\\\\TrustPath\\\\EmptyTrustPath\"},\"aaguid\":\"00000000-0000-0000-0000-000000000000\",\"credentialPublicKey\":\"pQECAyYgASFYIPmtQTJ1lSxl-tB3uaeyl3sSuzppt01UmNtSMlGhMTyvIlgg1JJOVEQpsi0Xy65HEyv8rq4zJhOsyJw9hFfXBpIlF-Y\",\"userHandle\":\"am9oYW5uZXM\",\"counter\":1624539452}",1],[2,2,2,2,1]]},{"file":"/path/to/nextcloud/3rdparty/doctrine/dbal/src/Query/QueryBuilder.php","line":213,"function":"executeStatement","class":"OC\\DB\\Connection","type":"->","args":["INSERT INTO \"oc_webauthn\" (\"name\", \"uid\", \"public_key_credential_id\", \"data\", \"id\") VALUES(:dcValue1, :dcValue2, :dcValue3, :dcValue4, :dcValue5)",{"dcValue1":"Chrome","dcValue2":"***redacted username***","dcValue3":"AZB0gw7O4VD7DTcziMcPmRwjwB+PaQOcwxyOVcA3UO1ErA+KhJiEhU45qfS4v4Yx0GF2RUS9mvzaCOzQmMI=","dcValue4":"{\"publicKeyCredentialId\":\"AZB0gw7O4VD7DTcziMcPmRwjwB-PaQOcwxyOVcA3UO1ErA-KhJiEhU45qfS4v4Yx0GF2RUS9mvzaCOzQmMI\",\"type\":\"public-key\",\"transports\":[],\"attestationType\":\"none\",\"trustPath\":{\"type\":\"Webauthn\\\\TrustPath\\\\EmptyTrustPath\"},\"aaguid\":\"00000000-0000-0000-0000-000000000000\",\"credentialPublicKey\":\"pQECAyYgASFYIPmtQTJ1lSxl-tB3uaeyl3sSuzppt01UmNtSMlGhMTyvIlgg1JJOVEQpsi0Xy65HEyv8rq4zJhOsyJw9hFfXBpIlF-Y\",\"userHandle\":\"am9oYW5uZXM\",\"counter\":1624539452}","dcValue5":1},{"dcValue1":2,"dcValue2":2,"dcValue3":2,"dcValue4":2,"dcValue5":1}]},{"file":"/path/to/nextcloud/lib/private/DB/QueryBuilder/QueryBuilder.php","line":287,"function":"execute","class":"Doctrine\\DBAL\\Query\\QueryBuilder","type":"->","args":[]},{"file":"/path/to/nextcloud/lib/public/AppFramework/Db/QBMapper.php","line":135,"function":"execute","class":"OC\\DB\\QueryBuilder\\QueryBuilder","type":"->","args":[]},{"file":"/path/to/nextcloud/lib/public/AppFramework/Db/QBMapper.php","line":159,"function":"insert","class":"OCP\\AppFramework\\Db\\QBMapper","type":"->","args":[{"id":1,"__class__":"OC\\Authentication\\WebAuthn\\Db\\PublicKeyCredentialEntity"}]},{"file":"/path/to/nextcloud/lib/private/Authentication/WebAuthn/CredentialRepository.php","line":90,"function":"insertOrUpdate","class":"OCP\\AppFramework\\Db\\QBMapper","type":"->","args":[{"id":1,"__class__":"OC\\Authentication\\WebAuthn\\Db\\PublicKeyCredentialEntity"}]},{"file":"/path/to/nextcloud/lib/private/Authentication/WebAuthn/CredentialRepository.php","line":94,"function":"saveAndReturnCredentialSource","class":"OC\\Authentication\\WebAuthn\\CredentialRepository","type":"->","args":[{"__class__":"Webauthn\\PublicKeyCredentialSource"},"default"]},{"file":"/path/to/nextcloud/3rdparty/web-auth/webauthn-lib/src/AuthenticatorAssertionResponseValidator.php","line":206,"function":"saveCredentialSource","class":"OC\\Authentication\\WebAuthn\\CredentialRepository","type":"->","args":[{"__class__":"Webauthn\\PublicKeyCredentialSource"}]},{"file":"/path/to/nextcloud/lib/private/Authentication/WebAuthn/Manager.php","line":235,"function":"check","class":"Webauthn\\AuthenticatorAssertionResponseValidator","type":"->","args":[null,{"__class__":"Webauthn\\AuthenticatorAssertionResponse"},{"__class__":"Webauthn\\PublicKeyCredentialRequestOptions"},{"__class__":"GuzzleHttp\\Psr7\\ServerRequest"},"***redacted username***"]},{"file":"/path/to/nextcloud/core/Controller/WebAuthnController.php","line":107,"function":"finishAuthentication","class":"OC\\Authentication\\WebAuthn\\Manager","type":"->","args":[{"__class__":"Webauthn\\PublicKeyCredentialRequestOptions"},"{\"id\":\"AZB0gw7O4VD7DTcziMcPmRwjwB-PaQOcwxyOVcA3UO1ErA-KhJiEhU45qfS4v4Yx0GF2RUS9mvzaCOzQmMI\",\"type\":\"public-key\",\"rawId\":\"AZB0gw7O4VD7DTcziMcPmRwjwB+PaQOcwxyOVcA3UO1ErA+KhJiEhU45qfS4v4Yx0GF2RUS9mvzaCOzQmMI=\",\"response\":{\"authenticatorData\":\"PmfOdjbCeXFHXvDwXZyqMk4LvGagoDl6PRhqL89+3MQFYNSBPA==\",\"clientDataJSON\":\"eyJ0eXBlIjoid2ViYXV0aG4uZ2V0IiwiY2hhbGxlbmdlIjoib0ZCZEpsaXdWTFlRNzF1a18tT3BIRTVnRHd2bVlFeEgyZDJqa2EyMXNiWSIsIm9yaWdpbiI6Imh0dHBzOi8vbmN3ZWJhdXRobi50ZXN0IiwiY3Jvc3NPcmlnaW4iOmZhbHNlfQ==\",\"signature\":\"MEUCIQDy6hHniCRGSD7RXghbZI57ghJOWYLLlVuANsAptRN6NwIgH/ksTNEkKP1HB706PJxqyq3N+ofraaxc1kZHiFLFqE4=\",\"userHandle\":\"am9oYW5uZXM=\"}}","***redacted username***"]},{"file":"/path/to/nextcloud/lib/private/AppFramework/Http/Dispatcher.php","line":218,"function":"finishAuthentication","class":"OC\\Core\\Controller\\WebAuthnController","type":"->","args":["{\"id\":\"AZB0gw7O4VD7DTcziMcPmRwjwB-PaQOcwxyOVcA3UO1ErA-KhJiEhU45qfS4v4Yx0GF2RUS9mvzaCOzQmMI\",\"type\":\"public-key\",\"rawId\":\"AZB0gw7O4VD7DTcziMcPmRwjwB+PaQOcwxyOVcA3UO1ErA+KhJiEhU45qfS4v4Yx0GF2RUS9mvzaCOzQmMI=\",\"response\":{\"authenticatorData\":\"PmfOdjbCeXFHXvDwXZyqMk4LvGagoDl6PRhqL89+3MQFYNSBPA==\",\"clientDataJSON\":\"eyJ0eXBlIjoid2ViYXV0aG4uZ2V0IiwiY2hhbGxlbmdlIjoib0ZCZEpsaXdWTFlRNzF1a18tT3BIRTVnRHd2bVlFeEgyZDJqa2EyMXNiWSIsIm9yaWdpbiI6Imh0dHBzOi8vbmN3ZWJhdXRobi50ZXN0IiwiY3Jvc3NPcmlnaW4iOmZhbHNlfQ==\",\"signature\":\"MEUCIQDy6hHniCRGSD7RXghbZI57ghJOWYLLlVuANsAptRN6NwIgH/ksTNEkKP1HB706PJxqyq3N+ofraaxc1kZHiFLFqE4=\",\"userHandle\":\"am9oYW5uZXM=\"}}"]},{"file":"/path/to/nextcloud/lib/private/AppFramework/Http/Dispatcher.php","line":127,"function":"executeController","class":"OC\\AppFramework\\Http\\Dispatcher","type":"->","args":[{"__class__":"OC\\Core\\Controller\\WebAuthnController"},"finishAuthentication"]},{"file":"/path/to/nextcloud/lib/private/AppFramework/App.php","line":157,"function":"dispatch","class":"OC\\AppFramework\\Http\\Dispatcher","type":"->","args":[{"__class__":"OC\\Core\\Controller\\WebAuthnController"},"finishAuthentication"]},{"file":"/path/to/nextcloud/lib/private/Route/Router.php","line":302,"function":"main","class":"OC\\AppFramework\\App","type":"::","args":["OC\\Core\\Controller\\WebAuthnController","finishAuthentication",{"__class__":"OC\\AppFramework\\DependencyInjection\\DIContainer"},{"_route":"core.WebAuthn.finishAuthentication"}]},{"file":"/path/to/nextcloud/lib/base.php","line":993,"function":"match","class":"OC\\Route\\Router","type":"->","args":["/login/webauthn/finish"]},{"file":"/path/to/nextcloud/index.php","line":37,"function":"handleRequest","class":"OC","type":"::","args":[]},{"file":"/Users/brueckner/.composer/vendor/laravel/valet/server.php","line":235,"args":["/path/to/nextcloud/index.php"],"function":"require"}],"File":"/path/to/nextcloud/3rdparty/doctrine/dbal/src/Driver/PDO/Exception.php","Line":26,"Previous":{"Exception":"PDOException","Message":"SQLSTATE[23000]: Integrity constraint violation: 19 UNIQUE constraint failed: oc_webauthn.id","Code":"23000","Trace":[{"file":"/path/to/nextcloud/3rdparty/doctrine/dbal/src/Driver/PDO/Statement.php","line":82,"function":"execute","class":"PDOStatement","type":"->","args":[null]},{"file":"/path/to/nextcloud/3rdparty/doctrine/dbal/src/Connection.php","line":1136,"function":"execute","class":"Doctrine\\DBAL\\Driver\\PDO\\Statement","type":"->","args":[]},{"file":"/path/to/nextcloud/lib/private/DB/Connection.php","line":257,"function":"executeStatement","class":"Doctrine\\DBAL\\Connection","type":"->","args":["INSERT INTO \"oc_webauthn\" (\"name\", \"uid\", \"public_key_credential_id\", \"data\", \"id\") VALUES(?, ?, ?, ?, ?)",["Chrome","***redacted username***","AZB0gw7O4VD7DTcziMcPmRwjwB+PaQOcwxyOVcA3UO1ErA+KhJiEhU45qfS4v4Yx0GF2RUS9mvzaCOzQmMI=","{\"publicKeyCredentialId\":\"AZB0gw7O4VD7DTcziMcPmRwjwB-PaQOcwxyOVcA3UO1ErA-KhJiEhU45qfS4v4Yx0GF2RUS9mvzaCOzQmMI\",\"type\":\"public-key\",\"transports\":[],\"attestationType\":\"none\",\"trustPath\":{\"type\":\"Webauthn\\\\TrustPath\\\\EmptyTrustPath\"},\"aaguid\":\"00000000-0000-0000-0000-000000000000\",\"credentialPublicKey\":\"pQECAyYgASFYIPmtQTJ1lSxl-tB3uaeyl3sSuzppt01UmNtSMlGhMTyvIlgg1JJOVEQpsi0Xy65HEyv8rq4zJhOsyJw9hFfXBpIlF-Y\",\"userHandle\":\"am9oYW5uZXM\",\"counter\":1624539452}",1],[2,2,2,2,1]]},{"file":"/path/to/nextcloud/3rdparty/doctrine/dbal/src/Query/QueryBuilder.php","line":213,"function":"executeStatement","class":"OC\\DB\\Connection","type":"->","args":["INSERT INTO \"oc_webauthn\" (\"name\", \"uid\", \"public_key_credential_id\", \"data\", \"id\") VALUES(:dcValue1, :dcValue2, :dcValue3, :dcValue4, :dcValue5)",{"dcValue1":"Chrome","dcValue2":"***redacted username***","dcValue3":"AZB0gw7O4VD7DTcziMcPmRwjwB+PaQOcwxyOVcA3UO1ErA+KhJiEhU45qfS4v4Yx0GF2RUS9mvzaCOzQmMI=","dcValue4":"{\"publicKeyCredentialId\":\"AZB0gw7O4VD7DTcziMcPmRwjwB-PaQOcwxyOVcA3UO1ErA-KhJiEhU45qfS4v4Yx0GF2RUS9mvzaCOzQmMI\",\"type\":\"public-key\",\"transports\":[],\"attestationType\":\"none\",\"trustPath\":{\"type\":\"Webauthn\\\\TrustPath\\\\EmptyTrustPath\"},\"aaguid\":\"00000000-0000-0000-0000-000000000000\",\"credentialPublicKey\":\"pQECAyYgASFYIPmtQTJ1lSxl-tB3uaeyl3sSuzppt01UmNtSMlGhMTyvIlgg1JJOVEQpsi0Xy65HEyv8rq4zJhOsyJw9hFfXBpIlF-Y\",\"userHandle\":\"am9oYW5uZXM\",\"counter\":1624539452}","dcValue5":1},{"dcValue1":2,"dcValue2":2,"dcValue3":2,"dcValue4":2,"dcValue5":1}]},{"file":"/path/to/nextcloud/lib/private/DB/QueryBuilder/QueryBuilder.php","line":287,"function":"execute","class":"Doctrine\\DBAL\\Query\\QueryBuilder","type":"->","args":[]},{"file":"/path/to/nextcloud/lib/public/AppFramework/Db/QBMapper.php","line":135,"function":"execute","class":"OC\\DB\\QueryBuilder\\QueryBuilder","type":"->","args":[]},{"file":"/path/to/nextcloud/lib/public/AppFramework/Db/QBMapper.php","line":159,"function":"insert","class":"OCP\\AppFramework\\Db\\QBMapper","type":"->","args":[{"id":1,"__class__":"OC\\Authentication\\WebAuthn\\Db\\PublicKeyCredentialEntity"}]},{"file":"/path/to/nextcloud/lib/private/Authentication/WebAuthn/CredentialRepository.php","line":90,"function":"insertOrUpdate","class":"OCP\\AppFramework\\Db\\QBMapper","type":"->","args":[{"id":1,"__class__":"OC\\Authentication\\WebAuthn\\Db\\PublicKeyCredentialEntity"}]},{"file":"/path/to/nextcloud/lib/private/Authentication/WebAuthn/CredentialRepository.php","line":94,"function":"saveAndReturnCredentialSource","class":"OC\\Authentication\\WebAuthn\\CredentialRepository","type":"->","args":[{"__class__":"Webauthn\\PublicKeyCredentialSource"},"default"]},{"file":"/path/to/nextcloud/3rdparty/web-auth/webauthn-lib/src/AuthenticatorAssertionResponseValidator.php","line":206,"function":"saveCredentialSource","class":"OC\\Authentication\\WebAuthn\\CredentialRepository","type":"->","args":[{"__class__":"Webauthn\\PublicKeyCredentialSource"}]},{"file":"/path/to/nextcloud/lib/private/Authentication/WebAuthn/Manager.php","line":235,"function":"check","class":"Webauthn\\AuthenticatorAssertionResponseValidator","type":"->","args":[null,{"__class__":"Webauthn\\AuthenticatorAssertionResponse"},{"__class__":"Webauthn\\PublicKeyCredentialRequestOptions"},{"__class__":"GuzzleHttp\\Psr7\\ServerRequest"},"***redacted username***"]},{"file":"/path/to/nextcloud/core/Controller/WebAuthnController.php","line":107,"function":"finishAuthentication","class":"OC\\Authentication\\WebAuthn\\Manager","type":"->","args":[{"__class__":"Webauthn\\PublicKeyCredentialRequestOptions"},"{\"id\":\"AZB0gw7O4VD7DTcziMcPmRwjwB-PaQOcwxyOVcA3UO1ErA-KhJiEhU45qfS4v4Yx0GF2RUS9mvzaCOzQmMI\",\"type\":\"public-key\",\"rawId\":\"AZB0gw7O4VD7DTcziMcPmRwjwB+PaQOcwxyOVcA3UO1ErA+KhJiEhU45qfS4v4Yx0GF2RUS9mvzaCOzQmMI=\",\"response\":{\"authenticatorData\":\"PmfOdjbCeXFHXvDwXZyqMk4LvGagoDl6PRhqL89+3MQFYNSBPA==\",\"clientDataJSON\":\"eyJ0eXBlIjoid2ViYXV0aG4uZ2V0IiwiY2hhbGxlbmdlIjoib0ZCZEpsaXdWTFlRNzF1a18tT3BIRTVnRHd2bVlFeEgyZDJqa2EyMXNiWSIsIm9yaWdpbiI6Imh0dHBzOi8vbmN3ZWJhdXRobi50ZXN0IiwiY3Jvc3NPcmlnaW4iOmZhbHNlfQ==\",\"signature\":\"MEUCIQDy6hHniCRGSD7RXghbZI57ghJOWYLLlVuANsAptRN6NwIgH/ksTNEkKP1HB706PJxqyq3N+ofraaxc1kZHiFLFqE4=\",\"userHandle\":\"am9oYW5uZXM=\"}}","***redacted username***"]},{"file":"/path/to/nextcloud/lib/private/AppFramework/Http/Dispatcher.php","line":218,"function":"finishAuthentication","class":"OC\\Core\\Controller\\WebAuthnController","type":"->","args":["{\"id\":\"AZB0gw7O4VD7DTcziMcPmRwjwB-PaQOcwxyOVcA3UO1ErA-KhJiEhU45qfS4v4Yx0GF2RUS9mvzaCOzQmMI\",\"type\":\"public-key\",\"rawId\":\"AZB0gw7O4VD7DTcziMcPmRwjwB+PaQOcwxyOVcA3UO1ErA+KhJiEhU45qfS4v4Yx0GF2RUS9mvzaCOzQmMI=\",\"response\":{\"authenticatorData\":\"PmfOdjbCeXFHXvDwXZyqMk4LvGagoDl6PRhqL89+3MQFYNSBPA==\",\"clientDataJSON\":\"eyJ0eXBlIjoid2ViYXV0aG4uZ2V0IiwiY2hhbGxlbmdlIjoib0ZCZEpsaXdWTFlRNzF1a18tT3BIRTVnRHd2bVlFeEgyZDJqa2EyMXNiWSIsIm9yaWdpbiI6Imh0dHBzOi8vbmN3ZWJhdXRobi50ZXN0IiwiY3Jvc3NPcmlnaW4iOmZhbHNlfQ==\",\"signature\":\"MEUCIQDy6hHniCRGSD7RXghbZI57ghJOWYLLlVuANsAptRN6NwIgH/ksTNEkKP1HB706PJxqyq3N+ofraaxc1kZHiFLFqE4=\",\"userHandle\":\"am9oYW5uZXM=\"}}"]},{"file":"/path/to/nextcloud/lib/private/AppFramework/Http/Dispatcher.php","line":127,"function":"executeController","class":"OC\\AppFramework\\Http\\Dispatcher","type":"->","args":[{"__class__":"OC\\Core\\Controller\\WebAuthnController"},"finishAuthentication"]},{"file":"/path/to/nextcloud/lib/private/AppFramework/App.php","line":157,"function":"dispatch","class":"OC\\AppFramework\\Http\\Dispatcher","type":"->","args":[{"__class__":"OC\\Core\\Controller\\WebAuthnController"},"finishAuthentication"]},{"file":"/path/to/nextcloud/lib/private/Route/Router.php","line":302,"function":"main","class":"OC\\AppFramework\\App","type":"::","args":["OC\\Core\\Controller\\WebAuthnController","finishAuthentication",{"__class__":"OC\\AppFramework\\DependencyInjection\\DIContainer"},{"_route":"core.WebAuthn.finishAuthentication"}]},{"file":"/path/to/nextcloud/lib/base.php","line":993,"function":"match","class":"OC\\Route\\Router","type":"->","args":["/login/webauthn/finish"]},{"file":"/path/to/nextcloud/index.php","line":37,"function":"handleRequest","class":"OC","type":"::","args":[]},{"file":"/Users/brueckner/.composer/vendor/laravel/valet/server.php","line":235,"args":["/path/to/nextcloud/index.php"],"function":"require"}],"File":"/path/to/nextcloud/3rdparty/doctrine/dbal/src/Driver/PDO/Statement.php","Line":82}},"CustomMessage":"--"},"userAgent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.4551.0 Safari/537.36","version":"21.0.2.1"} ```

The part that matters is this one:

"Exception":"Doctrine\\DBAL\\Exception\\UniqueConstraintViolationException","Message":"An exception occurred while executing a query: SQLSTATE[23000]: Integrity constraint violation: 19 UNIQUE constraint failed: oc_webauthn.id","Code":19,

I tracked down the problem and it seems to come from the insertOrUpdate() function in QBMapper.php: https://github.com/nextcloud/server/blob/bdfd2d92090f5b80254232aecab523f0aaf5e0fc/lib/public/AppFramework/Db/QBMapper.php#L162-L171

It tries to catch the exception:

} catch (Exception $ex) {
    if ($ex->getReason() === Exception::REASON_UNIQUE_CONSTRAINT_VIOLATION) {
        ...

but seems to fail to do so. Tracking it down further, we can see that

Exception::REASON_UNIQUE_CONSTRAINT_VIOLATION

... has been added in version 21.0.0: https://github.com/nextcloud/server/blob/bdfd2d92090f5b80254232aecab523f0aaf5e0fc/lib/public/DB/Exception.php#L134-L139

So I guess that code 14 mit not be correct?!

brueckner commented 3 years ago

Intermediate fix if you absolutely need this to work right now:

In lib/private/Authentication/WebAuthn/CredentialRepository.php

    public function saveAndReturnCredentialSource(PublicKeyCredentialSource $publicKeyCredentialSource, string $name = null): PublicKeyCredentialEntity {
        $oldEntity = null;

        try {
            $oldEntity = $this->credentialMapper->findOneByCredentialId($publicKeyCredentialSource->getPublicKeyCredentialId());
        } catch (IMapperException $e) {
        }

        $defaultName = false;
        if ($name === null) {
            $defaultName = true;
            $name = 'default';
        }

        $entity = PublicKeyCredentialEntity::fromPublicKeyCrendentialSource($name, $publicKeyCredentialSource);

        if ($oldEntity) {
            $entity->setId($oldEntity->getId());
            if ($defaultName) {
                $entity->setName($oldEntity->getName());
            }
+           return $this->credentialMapper->update($entity);
        }

-       return $this->credentialMapper->insertOrUpdate($entity);
+       return $this->credentialMapper->insert($entity);
    }

Sorry for the poor-man's diff ;-)

zimmersi commented 3 years ago

thks, great analysis + workaround fixed it for me!

simao-silva commented 3 years ago

@brueckner worked for me as well. However, I notice that the syncing clients (Linux and Windows) started to log out and unable to keep a login for more than a few minutes.

zimmersi commented 3 years ago

@simao-silva yes, same here

zimmersi commented 3 years ago

@brueckner I have reverted your proposed changes from here

AND

reverted the changes from here #26581

-> webauthn is still working but I have also still the issue that the sync client is logged out after a few minutes....

ChristophWurst commented 3 years ago

For 22 the code looks fine, I think only 21 is a problem.

21: https://github.com/nextcloud/server/blame/e76b83393cf95c0ac97850f9487ab3ddc7bf604b/lib/public/AppFramework/Db/QBMapper.php#L139 22: https://github.com/nextcloud/server/blame/e74f5aeec27d943ba7ba276190bf2846bf49ee71/lib/public/AppFramework/Db/QBMapper.php#L139

executeStatement in 22 will throw the expected exception and the try-catch in the QBMapper::insertOrUpdate can work. In 22 the expected exception isn't thrown.

This also has to do with https://github.com/nextcloud/server/pull/26182

ChristophWurst commented 3 years ago

Ugh. There is a lot that doesn't seem right with documented vs actually thrown exceptions in Nextcloud 21. If you start to fix one place then it has influence on so many other code snippets. I think I'll open a PR that just addresses this specific bug and then we hope for the best :crossed_fingers:

zimmersi commented 3 years ago

@simao-silva regarding the sync client issue....if I authenticate my users with passwords in the browser before allowing the access to the sync client, it keeps the connection..... So, only if a user is authenticated by webauthn before allowing the access to the sync client, the sync client looses the connection after a few minutes.

@ChristophWurst: any idea how to track this down?

ChristophWurst commented 3 years ago

No, I don't see how those two bugs are related.

szaimen commented 3 years ago

Can anyone try again with NC22 if it works there? (idea is based on https://github.com/nextcloud/server/issues/27721#issuecomment-871342626)

zimmersi commented 3 years ago

hi @szaimen , NC 22.0.0.11 the login is working BUT the users and sync clients gets constantly logged out after a short period of time. In fact, it is unusable. issue is already discribed here #26806 after reverting #25460 it is working again.

szaimen commented 3 years ago

Lets track this in https://github.com/nextcloud/server/issues/26806 then