How to store authentication token?

Hi all,

I’m trying to use Keycloak in my application. After having configured the server, I added a custom class (an extension of AuthenticationProvider) to the camunda-engine-rest-core where I retrieved the token from the request and used it for the authentication.

Everything seems to work but now I have to save the access token in order to use it later on in the process; e.g. for calling a Rest API from a Service Task.

Could you please tell me how do that?

Thanks,
Dario

Hi Dario,

not precisely an answer, but this [1] may give you some confidence or inspiration…

regards

Rob

[1] https://blog.camunda.org/post/2015/05/long-running-processes-and-service/

Thank you Rob,

I’ve read the article and “The last user credentials” option is exactly what I would like to do.
I don’t understand how to retrieve the last token for example when a user completes a task.
The article talks about ExecutionListener where I can access just the DelegateExecution object while I need the HTTP request (available in AuthenticationProvider) to retrieve the token.

For now, my solution is to receive the token as process variable when the front-end calls the engine (for Start and Complete operations) and use it in my tasks.

Is there a better way to solve this?

BR,
Dario

Hi Dario,

I think thats a viable way, however a challenge is secure storage of the token. If its compromised a malicious user could impersonate the real user. Hence storage as a process variable in the clear could be considered inappropriate. Another option for secure storage could be use of something like Hashicorp Vault…

Perhaps @BerndRuecker or another Camunda Representative may comment re this use case…

regards

Rob

Happy to do so :slight_smile:

Hi Dario, it depends if you know that you will have synchronous calls going on, then you could store the token in some ThreadLocal or the like. But I guess you also want to have it available in the asynchronous case. As far as I recall we saved the token as process variable in the project which inspired the blog post back then. It is true, that due to security restrictions that might not be possible for you. It was no problem in this customers scenario though. You could also rely on an external storage where you link process instance id and token - but I have no out-of-my-mind recommendation. Sorry!

Thank you anyway, Bernd.

Hi @dar88rm,

You wrote “calling a Rest API from a Service Task”. I assume you are trying to call a 3rd party ReST API secured by Keycloak from a Service Task.

IMHO you shouldn’t use user tokens as a means of trust between engine and 3rd party ReST API. The few downsides are: (1) tokens may expire at the moment you make the api call, (2) if stored in process instance, they are readable in cleartext.

Instead, I would setup a more direct trust between engine and API, e.g. create a client for engine in Keycloak, and use that to make calls from engine to API with engine credentials. To keep track of the user at API side, just convey that as extra context info in API calls.

Thank you tair for your reply.

We also think this is the best way.

BR,
Dario

Hi all,

I know this topic was discussed a long time ago.

But for me it is not clear, how to implement this direct trust between the engine and an external REST API what @tair has mentioned?

Is there an existing example which I can adapt to my needs?

Best regards,
Marvin

Hi Marvin,

just retrieve the token before every call like a normal client in the OAuth 2 protocol.
Even better if you create a Singleton to handle these calls properly (caching/refreshing).

Thank you for the answer, @dar88rm :+1:

Hi @Marvin_Kehr

Here https://www.keycloak.org/docs/latest/server_admin/#_service_accounts you can find the proper way to do a service intergration with keycloak.

In nutshell, you have to understand that Keycloak is itself a set of services:

  1. a service, that gives you tokens in exchange for some (usually, static) id and secret.
  2. various services, that you can call with that token, e.g. to manage users, or even create new clients dynamically.
  3. Third party services, that also delegate step 1 to Keycloak and then authorize http requests with temporary tokens

So, e.g. Keycloak User Management API is not different from a 3rd party API that is secured by Keycloak.

If you want your Camunda be able to manage Keycloak users or call some other 3rd party APIs secured with Keycloak without human assistance, you will have to have some secret in Camunda app config that your app uses at runtime to obtain a temporary access token.

Yes, this became a very convoluted explanation, but OpenID Connect is a complex beast ))

Feel free to ask further questions.

PS: a good example of how to integrate Camunda properly with Keycloak is this plugin https://github.com/camunda/camunda-bpm-identity-keycloak. It has 2 parts: (1) authenticate users with JWT token, (2) present users info in camunda admin webapp. The second part accesses Keycloak user-management api with a privileged service account.