Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Is Duende.AccessTokenManagement Suitable for Local Machine Service Workers ? #1410

Closed
camillebourgetATL opened this issue Sep 19, 2024 · 9 comments
Assignees

Comments

@camillebourgetATL
Copy link

camillebourgetATL commented Sep 19, 2024

Hello Duende team,

I’m considering using the Duende.AccessTokenManagement library to manage tokens in machine-to-machine flows for .NET workers and ASP.NET Core worker services. My specific use case involves developing plugins for Autodesk solutions, but I’ve encountered DLL conflicts between the IdentityModel.OidcClient library and Autodesk products. Could Duende.AccessTokenManagement be a suitable replacement, particularly for service workers running locally on a user’s machine, or is it mainly designed for cloud-based environments? I’m particularly concerned about the security implications and how client credentials should be securely stored in a local context.

Thank you for your insights!

Best regards,
Camille

@RolandGuijt
Copy link

Yes, Duende.AccessTokenManagement has support for this. You can find the documentation here.

The tokens are cached using ASP.NET Core's IDistributedCache which can be configured to store the tokens in Redis, SQL Server etc.
If that doesn't suffice you can also consider creating your own implementation of IClientCredentialsTokenCache and implement caching the way you want without IDistributedCache.

@camillebourgetATL
Copy link
Author

Thank you for the information. Just to clarify, with IdentityModel, I currently only use the client ID to retrieve a token, and then I securely store the refresh token on the client machine. With Duende.AccessTokenManagement, am I required to use a client secret, or can I continue using only the client ID?

@RolandGuijt
Copy link

Since you mention a refresh token: What flow are you currently using?
When using Client Credentials flow using a client secret is a must to make the flow secure. Using it the refresh token isn't needed: the application can simply request a new token using Client Credentials when the current one expires.

The original idea of Client Credentials is that the client runs on a server/cloud somewhere, outside the reach of a user. In that case the client secret can easily be kept. In your case however the workers run locally.
Is there a way to run the service workers on a server and expose the result of the work securely to the user application?

@camillebourgetATL
Copy link
Author

camillebourgetATL commented Sep 23, 2024

Currently, I am using the interactive public flow with PKCE and offline access. From what I understand, I cannot move the worker to cloud servers because I need to make secure API calls directly from my application, which is installed locally on the client machine.

My goal is to create a worker that centralizes the logic, allowing me to reuse code and ensure that there is a single source of truth for making these API calls.

@RolandGuijt
Copy link

I'm getting a bit confused here. Is the following correct?

  • You have a "front-end" application that is a Autodesk plugin (that uses code flow + PKCE)
  • There's an API installed locally on the same machine (requiring an access token)
  • You want a separate worker process that gets an access token and does requests to the API

If the above is correct then the worker process should use client credentials (machine to machine) flow since there is no user involved in that process.
Am I understanding this correctly?

@camillebourgetATL
Copy link
Author

My plugin is actually a class library project in C# using both .NET 8 and .NET Framework. Currently, for the authentication and identification of my clients (so they can input their username and password on my Duende IdentityServer), I’ve created another .NET Standard class library. This library uses IdentityModel to authenticate the client and retrieve an access token, which is then used to make API requests.

However, I’ve been running into issues with version conflicts, especially since the latest versions of Autodesk's software, specifically Revit, which enforces strict versioning of libraries. Revit doesn't allow the use of any library versions other than the ones it specifies, which causes problems with my plugin.

Because of this, I’m exploring the option of moving the authentication and identification process into a Windows service (worker) that runs in the background on the client’s machine. This worker would handle API calls and allow me to use the latest versions of libraries without the versioning constraints imposed by Autodesk.

I’m also considering whether your open-source package, Duende.AccessTokenManagement, could be used in this configuration, where the Windows service (worker) would manage authentication and token handling.

However, based on our recent discussion, I don't think this approach is viable because the flow you use requires not exposing the client’s credentials, which makes it unsuitable for my current setup.

@RolandGuijt
Copy link

Clear. So to summarize:

  • The worker process has to get a token using Client Credentials. That flow sends the client credentials to the identity provider and must include the secret.
  • Duende.AccessTokenManagement can be used for that. See the link above.

Since the worker has to run on the user's machine you should store the secret in a secure manner. A way to do that is using Data Protection.

@camillebourgetATL
Copy link
Author

Thank you for the clear summary! I appreciate the details on the process for obtaining a token using Client Credentials. Using Duende.AccessTokenManagement sounds like a solid approach for handling this. I’ll ensure that the secret is stored securely on the user’s machine, utilizing Data Protection as you recommended. If I have any further questions during implementation, I'll reach out. Thanks again for your guidance!

@RolandGuijt
Copy link

You're welcome!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants