wso2 / product-is

Welcome to the WSO2 Identity Server source code! For info on working with the WSO2 Identity Server repository and contributing code, click the link below.
http://wso2.github.io/
Apache License 2.0
746 stars 724 forks source link

Passkey authentication fails for a user who logs in with email OTP #19110

Closed malithie closed 8 months ago

malithie commented 8 months ago

Describe the issue: $subject

How to reproduce:

  1. Have an app that has emailOTP and passkeys configured as the authentication options
  2. Have a user with a valid email
  3. Have the same options configured in my account
  4. Login to the app with email otp and access my account to entroll the passkey
  5. Logout and login using passkeys again
  6. App recieves an error as below http://127.0.0.1:5173/?error_description=Authentication+required&state=request_2&error=login_required

Following error logs were visible in the carbon log. [1] TID: [-1234] [oauth2] [2024-01-22 12:12:04,275] [a2d6674a-29d4-43f7-8940-7a14be7d8af6] ERROR {org.wso2.carbon.identity.core.persistence.JDBCPersistenceManager} - An error occurred while commit transactions. java.sql.SQLException: Can't call commit when autocommit=true at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:67) at com.mysql.cj.jdbc.ConnectionImpl.commit(ConnectionImpl.java:786) at jdk.internal.reflect.GeneratedMethodAccessor56.invoke(Unknown Source) at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.base/java.lang.reflect.Method.invoke(Method.java:566) at org.apache.tomcat.jdbc.pool.ProxyConnection.invoke(ProxyConnection.java:131) at org.apache.tomcat.jdbc.pool.JdbcInterceptor.invoke(JdbcInterceptor.java:109) at

[2] TID: [-1234] [] [2024-01-22 12:14:05,264] [f2d0daba-1312-484e-a5a5-936783a55fbb] ERROR {org.wso2.carbon.identity.application.authentication.framework.handler.request.impl.DefaultRequestCoordinator} - Exception in Authentication Framework java.lang.NullPointerException at org.wso2.carbon.identity.application.authentication.framework.util.FrameworkUtils.preprocessUsername(FrameworkUtils.java:3280) at org.wso2.carbon.identity.application.authenticator.fido.FIDOAuthenticator.resolveUserFromUsername(FIDOAuthenticator.java:1025) at org.wso2.carbon.identity.application.authenticator.fido.FIDOAuthenticator.initiateAuthenticationRequest(FIDOAuthenticator.java:628) at org.wso2.carbon.identity.application.authenticator.fido.FIDOAuthenticator.process(FIDOAuthenticator.java:174) at org.wso2.carbon.identity.application.authentication.framework.handler.step.impl.DefaultStepHandler.doAuthentication(DefaultStepHandler.java:724) at org.wso2.carbon.identity.application.authentication.framework.handler.step.impl.DefaultStepHandler.handleRequestFromLoginPage(DefaultStepHandler.java:636) at org.wso2.carbon.identity.application.authentication.framework.handler.step.impl.DefaultStepHandler.handle(DefaultStepHandler.java:240) at org.wso2.carbon.identity.application.authentication.framework.handler.sequence.impl.GraphBasedSequenceHandler.handleAuthenticationStep(GraphBasedSequenceHandler.java:547) at org.wso2.carbon.identity.application.authentication.framework.handler.sequence.impl.GraphBasedSequenceHandler.handleNode(GraphBasedSequenceHandler.java:212) at org.wso2.carbon.identity.application.authentication.framework.handler.sequence.impl.GraphBasedSequenceHandler.handle(GraphBasedSequenceHandler.java:162) at org.wso2.carbon.identity.application.authentication.framework.handler.request.impl.DefaultAuthenticationRequestHandler.handle(DefaultAuthenticationRequestHandler.java:205) at org.wso2.carbon.identity.application.authentication.framework.handler.request.impl.DefaultRequestCoordinator.handle(DefaultRequestCoordinator.java:382) at org.wso2.carbon.identity.application.authentication.framework.CommonAuthenticationHandler.doPost(CommonAuthenticationHandler.java:57) at org.wso2.carbon.identity.application.authentication.framework.CommonAuthenticationHandler.doGet(CommonAuthenticationHandler.java:46) at org.wso2.carbon.identity.application.authentication.framework.servlet.CommonAuthenticationServlet.doGet(CommonAuthenticationServlet.java:48) at javax.servlet.http.HttpServlet.service(HttpServlet.java:529) at javax.servlet.http.HttpServlet.service(HttpServlet.java:623)

[3] TID: [-1234] [] [2024-01-22 12:29:34,186] [7ad8cb28-4205-44a9-9b62-da00a2510cb5] WARN {com.yubico.webauthn.RelyingParty} - Allowed origin is not a valid URL, it will match only by exact string equality: android:apk-key-hash:mJQKzmN3toRDHYWPA8-KFIec3t_qeiVVzVNaz8NTpVc TID: [-1234] [] [2024-01-22 12:29:34,186] [7ad8cb28-4205-44a9-9b62-da00a2510cb5] WARN {com.yubico.webauthn.RelyingParty} - Allowed origin is not a valid URL, it will match only by exact string equality: android:apk-key-hash:lAUVW7PYEUHgx90c3TrnExyJ52uYCLquJ0V7lv3R9S0 TID: [-1234] [] [2024-01-22 12:29:43,121] [a5befc3f-c1b2-4920-8c83-4034beff06d3] WARN {com.yubico.webauthn.RelyingParty} - Allowed origin is not a valid URL, it will match only by exact string equality: android:apk-key-hash:mJQKzmN3toRDHYWPA8-KFIec3t_qeiVVzVNaz8NTpVc TID: [-1234] [] [2024-01-22 12:29:43,122] [a5befc3f-c1b2-4920-8c83-4034beff06d3] WARN {com.yubico.webauthn.RelyingParty} - Allowed origin is not a valid URL, it will match only by exact string equality: android:apk-key-hash:lAUVW7PYEUHgx90c3TrnExyJ52uYCLquJ0V7lv3R9S0 TID: [-1234] [] [2024-01-22 12:29:43,150] [a5befc3f-c1b2-4920-8c83-4034beff06d3] ERROR {org.wso2.carbon.identity.application.authentication.framework.handler.step.impl.DefaultStepHandler} - Authentication failed exception! Assertion failed while finishing the assertion to retrieve the assertion result.

Expected behavior: Passkey authentication should be successful

Environment information (Please complete the following information; remove any unnecessary fields) :


Optional Fields

Related issues:

Suggested labels:

ashanthamara commented 8 months ago

Flow is working fine for H2 DB.

https://github.com/wso2/product-is/assets/75057725/de057a2f-093f-46f6-abcc-f05cc9abf34e

ashanthamara commented 8 months ago

Issue is not reproducing in MYSQL DB as well.

Tested IS pack: https://wso2.org/jenkins/job/products/job/product-is/5033/ with applying this manually https://github.com/wso2/identity-apps/pull/5335

https://github.com/wso2/product-is/assets/75057725/ed1c3fe0-72d1-4c33-afa5-917385177c09

➜  ~ mysql -V      
mysql  Ver 14.14 Distrib 5.7.43, for osx10.17 (x86_64) using  EditLine wrapper
DMHP commented 8 months ago

[1] https://github.com/wso2/product-is/issues/18655

Thumimku commented 8 months ago

Root cause

As explained in above comment, isIdfInitiatedFromAuthenticator is set to true even after clicking the choose different option is the root casue.

Possible fix no 1

Adding logic to remove isIdfInitiatedFromAuthenticator from context in DefaultRequestHandler

This is not possible because this particular if block will be run before going to IDF Initiated page and after entering the username. Hence usernameLess authentication procedure won't work.

Possible fix no 2

Adding an additional request param when clicking Choose different option. The redirection URI is Multioption URI which preserved over whole authentication process. Adding a param in Multioption URI will complicate the soluciton where not only we need to check for this param, but also we need to remove from multiOptionURI after processing it.

Possible fix no 3

Fixing at authenticator by handling NPE. This is a NPE issue. Hence we need to handle it NPE path also. Fixing NPE will fix this Issue. Proposed Fix :https://github.com/wso2-extensions/identity-local-auth-fido/pull/129

Thumimku commented 8 months ago

@DMHP I fixed the issue for the above comment you mentioned. hence I remove my assignment. Since the original issue is different I am not going to close this issue but assigning yourself.

Thumimku commented 8 months ago

Regarding in error log 3

I tried with chrome profile passkey and mobile device passkey login but both works as expected. So I had to do some analysis on the error logs.

TID: [-1234] [] [2024-01-22 12:29:43,150] [a5befc3f-c1b2-4920-8c83-4034beff06d3] ERROR {org.wso2.carbon.identity.application.authentication.framework.handler.step.impl.DefaultStepHandler} - Authentication failed exception! Assertion failed while finishing the assertion to retrieve the assertion result.

Above error is an assertion error which happens as last step of the passkey authentication process. This is a generic error, we can reproduce by clicking another user chrome profile key. But here we need to look above warn logs too.

TID: [-1234] [] [2024-01-22 12:29:43,121] [a5befc3f-c1b2-4920-8c83-4034beff06d3]  WARN {com.yubico.webauthn.RelyingParty} - Allowed origin is not a valid URL, it will match only by exact string equality: android:apk-key-hash:mJQKzmN3toRDHYWPA8-KFIec3t_qeiVVzVNaz8NTpVc 

Origin in webauthn contect explained here.

Upon further research for relying party Identifier rpiD I found that

The origin's scheme must be https.

Here the origin is android:apk-key-hash:mJQKzmN3toRDHYWPA8-KFIec3t_qeiVVzVNaz8NTpVc not is https format.

For further analysis we need to reproduce the flow with the involvement of specific andorid app, cause the issue description doesn't specify about any android applicaiton.

CC: @DMHP @malithie

Thumimku commented 8 months ago

Since the third error log is not reproduceable, I am closing the issue.