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

Modify configuration from react #1323

Open
meesvandongen opened this issue Mar 14, 2024 · 9 comments
Open

Modify configuration from react #1323

meesvandongen opened this issue Mar 14, 2024 · 9 comments

Comments

@meesvandongen
Copy link
Contributor

meesvandongen commented Mar 14, 2024

Issue and Steps to Reproduce

Currently, the configuration of react-oidc cannot be changed after the initial render. This related to the fact that oidc-client has a global variable called oidcDatabase which is an object containing all previously created oidc configurations based on name. If a name already exists, it is reused.

My use case is as follows: a user can belong to one or more organizations. I want to adjust the organization the user is currently acting on by using the token_request_extras field.

I tried to solve it by using a dynamic configurationName but that will not work with the service worker since it requires a predefined list of configurationNames.

I am not sure what is the best way to solve this; I was thinking of adding a way to adjust the configuration from outside. Currently a big part of the configuration is done in the constructor

this.configuration = {
  ...configuration,
  silent_login_uri,
  monitor_session: configuration.monitor_session ?? false,
  refresh_time_before_tokens_expiration_in_second,
  silent_login_timeout: configuration.silent_login_timeout ?? 12000,
  token_renew_mode:
    configuration.token_renew_mode ??
    TokenRenewMode.access_token_or_id_token_invalid,
  demonstrating_proof_of_possession:
    configuration.demonstrating_proof_of_possession ?? false,
  authority_timeout_wellknowurl_in_millisecond:
    configuration.authority_timeout_wellknowurl_in_millisecond ?? 10000,
  logout_tokens_to_invalidate:
    configuration.logout_tokens_to_invalidate ?? [
      'access_token',
      'refresh_token',
    ],
  service_worker_update_require_callback,
  service_worker_activate:
    configuration.service_worker_activate ?? activateServiceWorker,
  demonstrating_proof_of_possession_configuration:
    configuration.demonstrating_proof_of_possession_configuration ??
    defaultDemonstratingProofOfPossessionConfiguration,
};

So we cannot simply do a Object.assign(configuration, newConfiguration), since some fields are calculated (e.g. silent_login_url). A logical next step is then to abstract this away into a function and call that from the constructor.

Another thing to think about is how to expose it via the react-oidc package. Optimally it would not change the current API: adjusting the config via the current prop would be enough.

Do you think this is a use case you would want to support? And do you have some other ideas for a direction for a solution?

Versions

7.10.7

@guillaume-chervet
Copy link
Contributor

hi @meesvandongen ,

Thank you for your issue.
ConfigurationName is the way to use multiple configuration.

Do you have a domain list somewhere (in a database) ?
Your trustedDomain.js may can be generated dynamically from your server side so it will work properly.

@meesvandongen
Copy link
Contributor Author

@guillaume-chervet I suppose it could work; but I am very hesitant to solve it in that way. There are potentially hundreds of configurations that would end up in such a js file. I don't want to introduce such a coupling either.

The domains they call are a static list though, so I think it would be possible to introduce some global trusted domains and inherit from there.

But even that would be less desirable from my perspective than solving the root problem which is that the library does not adhere to the rules of react, in that it is not composable in ways the user may expect (dynamically change the config).

FYI, the workaround I currently have is to use the oidc-client package for certain things:

import { OidcClient } from '@axa-fr/oidc-client';

const oidc = OidcClient.get();

oidc.configuration.token_request_extras = {
  key: dynamicValue,
};

@guillaume-chervet
Copy link
Contributor

Hi @meesvandongen ,

The trusteddomain list is a security to garanty that access_tokens are not send to an untrusted url. You can set * to access_token domains list. It will still protection you from stealing refresh_token but not for access_token.

@meesvandongen
Copy link
Contributor Author

I was suggesting to do it the other way around; not "a configuration can be used for any domain", but rather "a domain can be used for any configuration".

@guillaume-chervet
Copy link
Contributor

Hi @meesvandongen , do you have some sample with api domains and oidc server domain in order to help me to understand your need.

@meesvandongen
Copy link
Contributor Author

@guillaume-chervet the oidc and api domains are the same for each configuration. The only thing that is different is what is passed to token_request_extras

so for example

configurationName: 1
token_request_extras: {
  organization: 1
}
configurationName: 2
token_request_extras: {
  organization: 2
}

@guillaume-chervet
Copy link
Contributor

guillaume-chervet commented Mar 15, 2024

I think i am starting to understand your need @meesvandongen

Does this way to inject extra resolve your need?

{isAuthenticatedDefault && <button type="button" className="btn btn-primary" onClick={() => login(undefined, { 'test:token_request': 'test', youhou: 'youhou', grant_type: 'tenant', tenantId: '1234' }, true)}>Silent Login</button>}

Each function offer an extras properties to override default extras.

@meesvandongen
Copy link
Contributor Author

@guillaume-chervet Thank you; I looked at that, but I initially disregarded it because it would not work for subsequent token refreshes. But that might not be true if the IDP would handle keeping the state the same for subsequent tokens. I think for my specific use case I am ok at this point.

However I still think the @axa-fr/react-oidc should support adjusting the configuration on subsequent renders. Maybe I could create a merge request to explore the possibility.

@guillaume-chervet
Copy link
Contributor

Hi @meesvandongen ,
If initial extrasTokens are not injected inside tokens refresh it is a bug because it should be the case. I will make some tests. It have been build for that lind of scénario and it is event possible to updates it by using à silentsigin.

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

No branches or pull requests

2 participants