Error after updating the password
-
Thanks! This is helpful and including the stack trace is great.
Can you provide more details about your setup to aid in reproducing the bug?
- Can you see this locally or only in prod?
- How many servers are you running for this instance (1, 2, etc)?
- What database and version are you using?
- Any info in the event log?
- Does this happen for all users or only users in a certain state (with MFA on, newly registered, etc)?
Thanks!
-
Sorry for missing these in my previous post.
The issue occurs in both environments: local is a single docker instance and the server environment uses two FA nodes.
Database is PostgreSQL (9.6 in docker and 11 on the server - managed Postgres on DigitalOcean) + Elasticsearch.
No MFA is in use. Users were created long time ago. As I said previously, it doesn't happen all the time, even for the same users. For example, I tried to change the password to 'password123' and it was impossible but when I tried another password like 'someotherpass.123' it worked. Then, trying to change the password again to password123 fails. In the same time, I was able to use 'password123' to reset password for some other user. (note: sample password provided above are not real ones I've used).
-
@maciej-wisniowski said in Error after updating the password:
No MFA is in use. Users were created a long time ago.
In the past, we have seen issues where imported users with improperly imported password hashes had trouble resetting their passwords. Are these users imported? Are they using a standard password encryptor/hash (
Salted PBKDF2 with SHA-256
for instance)?It sounds like you are using the Themed pages to change the password. If you repeat the same actions that caused your previous failure, but this time with the API, do you get the same result?
Thanks,
Josh -
@joshua I think that yes, these users were imported and they're using salted-pbkdf2-hmac-sha256, but their imported passwords are useable so I don't think these are hashed incorrectly.
We have themed pages but I've also tried with the "Default" theme and the issue occurred as well. It is worth noting that even though I get an error from FA, the password is changed and the user is logged in automatically after the password change form is submitted. Seems that the password change procedure works but the problem is a bit later.
Using the API it works properly:
In [42]: res = client.forgot_password({"loginId": 'someuser@somedomain.com'}) In [43]: change_password_id = res.success_response["changePasswordId"] In [44]: res2 = client.change_password(change_password_id, {'password': 'somepass2'}) In [45]: res2.was_successful() Out[45]: True
-
This post is deleted! -
Hmmm. As I read our conversation, there are no simple reproduction steps that you are able to determine? This is happening to just random users?
Still reviewing, but let me know if you have any other thoughts on this.Thanks,
Josh -
@joshua I think I've found the pattern to reproduce this issue.
Basically, it fails if the user I want to reset the password for is not registered in the application whose client_id is used during password reset flow. It works for the application where the user has a valid registration.To reproduce:
- Create new tenant: Tenant1
- Create two Applications for Tenant1: application1 and application2 using https://example.com as redirect_uri
- Create user: user1 for Tenant1
- Create registration for user1 in application1
- Open the authorize URL for application2 like:
https://<FUSIONAUTH_URL>/oauth2/authorize?client_id=<CLIENT_ID_OF_APPLICATION2>&scope=openid%20offline_access&response_type=code&redirect_uri=https%3A%2F%2Fexample.com&tenantId=<TENANT_ID> - Click Forgot your password
- Check you e-mail and click the password reset link
- Try to change the password
It should fail at this point.
You can now check the same for application1 (with the user registration) to see if it works.
I'm very curious if you can reproduce this too.
-
@joshua any chance you had some time to look at this? Is this reproducible on your end?
-
Thanks for the reminder - this is on my list to review this week and log a bug report if needed.
Thanks
Josh -
This was not immediately reproducible on my machine. I am going to try and few more things and will let you know.
Thanks,
Josh -
@joshua Unfortunately, I have similar issue while updating the password through Self Service Portal. It displays 500 Internal Server Error only if new password is not as per application specific password validation rules/constraints. It works fine if updated as per validation rules. As per correct flow , it should display field errors for validations instead redirecting to 500 Internal Server Error.
For reference, logs are
-
@developers in your case the error message is pretty self-explanatory. The problem is just a lack of [[singleCase]user.password] message in your theme. Just add this message to your theme and it should work
-
@maciej-wisniowski thanks for replying. I checked and seems [singleCase]user.password already there in my custom theme.
-
@developers Is this still an open issue for you?
Thanks,
Josh -
@joshua yes, I still have this issue on a few instances of FA while trying to change password for the user that is not registered in the specific application. If you're not able to reproduce this I can try to create a kickstart script to recreate the problem
-
Yes, if you had this that might be helpful. I tried again, and still worked for me.
Also, you can log a bug report if you feel this is appropriate
Thanks,
Josh -
@joshua I've tried with the FA 1.32.1 and I think I've found the source of the problem.
Turns out I had my Forgot Password Email template a bit old (AFAIR based on the template from 1.27.2).Because of this, the URL to reset the password (in the email template) was generated like:
https://#{FA_DOMAIN}/password/change/${changePasswordId}?tenantId=${user.tenantId}
In the newer versions of FA it was changed to:
[#assign url = "https://#{FA_DOMAIN}/password/change/${changePasswordId}?client_id=${(application.oauthConfiguration.clientId)!''}&tenantId=${user.tenantId}" /] [#list state!{} as key, value][#if key != "tenantId" && key != "client_id" && value??][#assign url = url + "&" + key?url + "=" + value?url/][/#if][/#list] ${url}
The point is that with the new version we have extra parameters in the URL like client_id, redirect_uri and a few others. Everything works properly with the new syntax. If these new parameters are missing (I suppose the main issue is lack of the client_id) FA triggers error 500 after password reset (for the users that are not registered in the application that generated the password reset e-mail).
The most recent version of FA triggers a more detailed error message in the log than the previous one and this helped me a bit to track the problem:
2022-01-11 4:19:10.373 PM ERROR io.fusionauth.app.primeframework.error.ExceptionExceptionHandler - An unhandled exception was thrown java.lang.NullPointerException: Cannot read field "oauthConfiguration" because "this.application" is null at io.fusionauth.app.action.oauth2.BaseOAuthAction.handleInteractiveLoginResponse(BaseOAuthAction.java:548) at io.fusionauth.app.action.oauth2.BaseOAuthAction.callLogin(BaseOAuthAction.java:447) at io.fusionauth.app.action.password.ChangeAction.post(ChangeAction.java:121) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.base/java.lang.reflect.Method.invoke(Method.java:568) at org.primeframework.mvc.util.ReflectionUtils.invoke(ReflectionUtils.java:414) at org.primeframework.mvc.action.DefaultActionInvocationWorkflow.execute(DefaultActionInvocationWorkflow.java:79) at org.primeframework.mvc.action.DefaultActionInvocationWorkflow.perform(DefaultActionInvocationWorkflow.java:62) at org.primeframework.mvc.workflow.SubWorkflowChain.continueWorkflow(SubWorkflowChain.java:51) at org.primeframework.mvc.validation.DefaultValidationWorkflow.perform(DefaultValidationWorkflow.java:47) at org.primeframework.mvc.workflow.SubWorkflowChain.continueWorkflow(SubWorkflowChain.java:51) at org.primeframework.mvc.security.DefaultSecurityWorkflow.perform(DefaultSecurityWorkflow.java:60) at org.primeframework.mvc.workflow.SubWorkflowChain.continueWorkflow(SubWorkflowChain.java:51) at org.primeframework.mvc.parameter.DefaultPostParameterWorkflow.perform(DefaultPostParameterWorkflow.java:50) at org.primeframework.mvc.workflow.SubWorkflowChain.continueWorkflow(SubWorkflowChain.java:51) at org.primeframework.mvc.content.DefaultContentWorkflow.perform(DefaultContentWorkflow.java:52) at org.primeframework.mvc.workflow.SubWorkflowChain.continueWorkflow(SubWorkflowChain.java:51) at org.primeframework.mvc.parameter.DefaultParameterWorkflow.perform(DefaultParameterWorkflow.java:57) at org.primeframework.mvc.workflow.SubWorkflowChain.continueWorkflow(SubWorkflowChain.java:51) at org.primeframework.mvc.parameter.DefaultURIParameterWorkflow.perform(DefaultURIParameterWorkflow.java:102) at org.primeframework.mvc.workflow.SubWorkflowChain.continueWorkflow(SubWorkflowChain.java:51) at org.primeframework.mvc.scope.DefaultScopeRetrievalWorkflow.perform(DefaultScopeRetrievalWorkflow.java:58) at org.primeframework.mvc.workflow.SubWorkflowChain.continueWorkflow(SubWorkflowChain.java:51) at org.primeframework.mvc.message.DefaultMessageWorkflow.perform(DefaultMessageWorkflow.java:44) at org.primeframework.mvc.workflow.SubWorkflowChain.continueWorkflow(SubWorkflowChain.java:51) at org.primeframework.mvc.action.DefaultActionMappingWorkflow.perform(DefaultActionMappingWorkflow.java:126) at org.primeframework.mvc.workflow.SubWorkflowChain.continueWorkflow(SubWorkflowChain.java:51) at org.primeframework.mvc.workflow.StaticResourceWorkflow.perform(StaticResourceWorkflow.java:97) at org.primeframework.mvc.workflow.SubWorkflowChain.continueWorkflow(SubWorkflowChain.java:51) at org.primeframework.mvc.parameter.RequestBodyWorkflow.perform(RequestBodyWorkflow.java:91) at org.primeframework.mvc.workflow.SubWorkflowChain.continueWorkflow(SubWorkflowChain.java:51) at org.primeframework.mvc.security.DefaultSavedRequestWorkflow.perform(DefaultSavedRequestWorkflow.java:64) at org.primeframework.mvc.workflow.SubWorkflowChain.continueWorkflow(SubWorkflowChain.java:51) at io.fusionauth.app.primeframework.CORSRequestWorkflow.perform(CORSRequestWorkflow.java:51) at org.primeframework.mvc.workflow.SubWorkflowChain.continueWorkflow(SubWorkflowChain.java:51) at io.fusionauth.app.primeframework.FusionAuthMVCWorkflow.perform(FusionAuthMVCWorkflow.java:86) at org.primeframework.mvc.workflow.DefaultWorkflowChain.continueWorkflow(DefaultWorkflowChain.java:44) at org.primeframework.mvc.servlet.FilterWorkflowChain.continueWorkflow(FilterWorkflowChain.java:50) at org.primeframework.mvc.servlet.PrimeFilter.doFilter(PrimeFilter.java:78) at com.inversoft.maintenance.servlet.MaintenanceModePrimeFilter.doFilter(MaintenanceModePrimeFilter.java:63) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) at com.inversoft.servlet.UTF8Filter.doFilter(UTF8Filter.java:27) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:196) at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97) at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:542) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:135) at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:81) at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78) at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:364) at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:624) at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65) at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:831) at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1650) at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191) at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659) at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) at java.base/java.lang.Thread.run(Thread.java:833)
I'm not sure if this can be considered a bug in FA? What do you think?
BTW. Is this normal that if the kickstart file is used then no default email templates are generated at all?
-
Glad that you are able to figure it out. I am not sure if that qualifies as a bug, but definitely something to be aware of and might be worth calling out in our documentation.
I believe that you should have email templates after a kickstart (at least the default ones). I can do some more testing to see if that same thing happens to me when I kickstart.
Thanks,
Josh