REST API authentication fails with hashed passwords

When I make a REST API call, only users with plain-text passwords pass authentication. I’m referring to how the passwords are stored in the database, plain text vs hashed. In my flowable setup, I have things configured to hash the passwords by default using the security.rememberme.key and security.passwordencoder settings in the flowable-ui-app.properties file, and so I’d like to avoid using plain text passwords.

How can I get the hashed passwords to work?

Good point. We could add an option to check against hashed passwords, instead of plain text passwords. Could you create a Github issue?

Best regards,

Tijs

I don’t think we should do this, that defeats the point of password hashing if we pass it over http.
The proper way is to have basic auth + https.

1 Like

I am using https. Is there something I need to be doing differently?

If you are using https, then the password is not transferred in plain text when you do a REST request with basic auth.

The point with password hashing is that:

  • The hash is never transferred over the wire and is only known server-side
  • Even if the database is compromised, the attacker only has the hash and still doesn’t have the real password

Unless this is about system-to-system communication, then it would make sense to have an encrypted password in the properties. But not with the same hashing as the regular passwords.

What use case are you looking at?

Hi Joram,
Use case #1: in-network API requests from a php app to flowable, each in separate docker containers. API user/pw is stored in config files for the php app.
Use case #2: user logins to flowable, where flowable is located on a public server.

From what I gather you’re saying, if I want to use https then I can’t use password hashing. Is that correct? I’d like to have the additional security benefits of hashed passwords that you mentioned, but I’ll remove the hashing and keep the https if that’s the case.

For use case #1 : for this use case it would make sense to hash/encrypt the password in the config file. (note: this is different from the hashing of the regular password)

For use case #2 : https is enough here. All passwords will be encrypted by https.

The password hashing has nothing to do with https:

  • https takes care of encrypting the data going over the wire (user forms etc)
  • there is hashing of the password on the server side, as storing plain text is not a good idea.
  • the only we don’t have is storing the password in an encrypted/hashed in a configuration file (use case #1) which would make sense to add support for

Thanks, that was helpful.

However, I’m still not clear on what to do regarding my original question. Right now, if I store passwords in a hashed form on the server, users can login, but an API authentication will fail. I have to manually set the API user’s password to store as plain text in the database, and then it will authenticate.

So, what do you recommend for the best course of action?

  1. I keep the API user’s pw in plain text form in the database, and all other user’s pw in hashed form.
  2. I remove hashing and store all user passwords as plain text in the database. Https is enough security.
  3. There is some other solution where all user passwords are hashed when stored in the database, and the API user can authenticate when sending API requests.

Not 1 and 2, don’t store passwords plain text in the db. Option 3 is not possible our of the box right now.

Isn’t it an option to put the API user password in a configuration file on the local system and use that when doing the call?
However, if you need the encryption of properties right now, you could add it to the code of the UI applications. It would need something like a shared encryption key on both the sending and receiving side … we always welcome pull requests :wink:

Isn’t it an option to put the API user password in a configuration file on the local system and use that when doing the call?

That’s how I have it setup now. The API user password is stored in plain text in the app’s config file, but flowable authentication will fail if the password is stored in hashed form in the database. If I go in and manually change the database to store the password in plain text, it authenticates. This is the challenge. Options 1 and 2 above are the only ideas I’ve thought of for going around this, and so I don’t know what to do since you recommend against those.

How can I use the API without storing passwords in plain text in the database? I can store them plain text in my php app’s config files, I can work with that and I’m already doing that.

You should not store passwords in plain text in the database.
In your php config file, you should put the password, in plain text and do the calls with that.
If you use https, the passwords are not transferred plain text over the wire.

What I’m not getting is that you are saying that you

  1. have the password in plain text in your config file
  2. need to also make this plain text in the database?

This doesn’t sound right. How are you passing the password? Using default basic auth?

The future improvement we can make (which i’m hinting at above) is to allow for hashed passwords in config files, such that there is an extra layer, but this is only for the communication between the servers (not end users)

I’m facing the same issue here.

Everything was working fine until I enabled the password security in the IDM config file (security.passwordencoder=spring_bcrypt). After enabling the passwordencoder, the REST APIs (flowable-rest) started to fail with the following response: “… HTTP Status 401 - Authentication failed for this username and password …”.

Note that I’m still able to access the flowable-modeler, flowable-task, flowable-idm, and flowable-admin using my username and password. I’m only facing this issue with flowable-rest.

To replicated the issue:

  1. enable (security.passwordencoder=spring_bcrypt) in the IDM config file.
  2. change the user’s password using IDM (flowable-idm will overwrite the plain text password with a hashed one).
  3. Now try invoking any REST API (flowable-rest).

Hi,

Note : This answer is according to my understanding of the app. I might be wrong!

All your apps are working because, all the ui apps are authenticated using the flowable-idm app(which provided cookies to the ui-app) and they use the cookie provided to access their apis. But same is not true for the flowable-rest app. Its authentication is different from flowable-idm authentication. It used basic authentication token instead of cookies. Now, in idm you have enabled “security.passwordencoder=spring_bcrypt” so now idm’s authentication class knows how to hash the password to match the one stored in database but in case of flowable-rest, i couldn’t find any property (security.passwordencoder=spring_bcrypt) to edit. So maybe thats why flowable-rest authentication doesn’t know how to hash the password to match with the one stored in the database and so authentication fails.

One thing you can do is(Strictly experimental, dont know if it will work or not), get the value of password ie hashed password from the database table for a user and directly put that value(hashed password) into the password field when using flowable rest. In my opinion, it should get authenticated.

Thank You,
Arpit

Yes, this is correct. I have it plain text in the config file, and auth will only succeed if the password is also plain text in the database. It will fail if the password is hashed in the database.

I am passing the password via curl. The error will show when I run a php curl command or running a simple curl from the command line like this:
curl --user api-user:password https://flowable.mydomain.com:8443/flowable-rest/service/management/engine

Thanks, but I’ve tried this and I still get the same error.

Hi,
I’m using Postman to test REST calls, and when I enter the hashed password (copied from DB table ACT_ID_USER), the authentication works again.

That shouldn’t be the case, the hashes are compared in the backend, not the values itself. Which setup are you using? There a few ways to configure the application to use hashing or different hashing algorithms.