fusionauth-issues icon indicating copy to clipboard operation
fusionauth-issues copied to clipboard

Expose the state param to the jwt populate lambda

Open mooreds opened this issue 3 years ago • 5 comments

Expose the state param to lambdas

Problem

I want to get info into my jwt that is neither on the user nor the registration object. I'm using the OAuth authorization code grant.

Solution

Expose the state parameter to lambda code, at least for the jwt populate lambda.

Alternatives/workarounds

Not really any good alternatives. I suppose you could catch the state object and the user in a proxy and then use the API to update the user state, but there'd be race conditions there.

Additional context

Similar in nature to https://github.com/FusionAuth/fusionauth-issues/issues/267 and related issues.

Came up in this slack thread: https://fusionauth.slack.com/archives/CG00HG935/p1603112107071200

How to vote

Please give us a thumbs up or thumbs down as a reaction to help us prioritize this feature. Feel free to comment if you have a particular need or comment on how this feature should work.

mooreds avatar Oct 19 '20 22:10 mooreds

The state should really be an opaque value to all but the OIDC service provider - and the JWT populate is used in a lot of cases where we are not in an OAuth flow and would not have any state.

Is there a real use case that we could outline here to better understand how to solve it?

robotdan avatar Oct 19 '20 22:10 robotdan

From the slack thread linked (paraphrased):

I want to add the device id into the JWT. I want to issue tokens for 10 devices from same user and same application , but i want the token hold unique deviceId. Is this possible?

mooreds avatar Oct 19 '20 22:10 mooreds

If I can extrapolate from this idea... the use case is:

  1. [User Agent] Begin the Authorization Code Grant and pass a state parameter that contains a deviceId parameter.
  2. [User Agent] The user enters credentials in a web based form, and FusionAuth returns an auth code to the caller using a 302 redirect.
  3. [Backend code] The caller consumes the auth code, and then calls the Token endpoint to complete the auth code grant using a backend service.
  4. [Backend code] FusionAuth accepts the code and returns the caller a JWT

The state parameter is echo'd back to the caller during the 302 redirect in step 2 of the User Agent flow. Once the caller then makes the final request to the Token endpoint to exchange the code for a JWT in step 4- we are no longer in a user-agent scoped context.

We do not currently persist the state parameter, so we do not have any knowledge of the state by the time we generate a JWT during the final code exchange in step 4.

I am not sure I understand the use enough yet to suggest an alternative, it sounds like the user wishes to authenticate up to 10 times and allow the authentication workflow to provide some sort of meta data to be returned in the resulting JWT.

The Refresh Token does have the ability to store meta data about the authentication request, name, description, device type, etc. Perhaps this is an option.

As far as I can tell, to satisfy this request, we would have to invent something new on top of OIDC to provide a documented parameter allowing the caller to add something to the request that can be persisted along with the authorization code for use by the lambda.

We can leave this open to explore that option, however without a compelling use case this will be a very low priority feature.

robotdan avatar Oct 20 '20 00:10 robotdan

As an alternative (until this issue is resolved with a better and more general solution), you can pass the information in the "scope" parameter. It is a bit of a mis-use of the scope, but it is currently exposed.

Example use:

On our testing tenant and application, we are using that to allow developers to simulate "roles" by passing in a scope of: role:XYZ in the scope parameter and then the lambda will add the "XYZ" role will to the token that is given back out.

This could be abused for other reasons since the state object is not passed to the lambda currently.

awoodobvio avatar Dec 07 '21 13:12 awoodobvio

This came up again in a different context. The desire is a way to have the lambda know about the specific request in order to do a cookie fingerprint, as advised by OWASP to prevent sidejacking: https://github.com/OWASP/CheatSheetSeries/blob/master/cheatsheets/JSON_Web_Token_for_Java_Cheat_Sheet.md#token-sidejacking

mooreds avatar Sep 01 '22 16:09 mooreds

I also have a use-case as well where I'd want to add in external custom data when I perform a user login or IdP token exchange.

I'd like to be able to feed something like the other users mention above as a param into Authenticate a User and OAuth Endpoints

And have that data be exposed as another param in JWT Populate

When the token is refreshed, it should retain the custom data it had

theogravity avatar Sep 13 '22 22:09 theogravity

@theogravity will Lambda HTTP Connect work for you? If not, can you explain why?

mooreds avatar Sep 14 '22 17:09 mooreds

@theogravity will Lambda HTTP Connect work for you? If not, can you explain why?

It wouldn't because the data to infuse would be session-specific. I would need to know a value to use as a reference to make a call using that to our backend to get the proper value, which is really just additional steps should it be possible.

I can't use user data to store that session specific value because there may be a chance that another process can override the value should the user try to begin a session at the same time in two separate browsers.

Also after some thought, my use-case may have a workaround via the vend JWT API, but vend doesn't allow for token refresh (which should still be ok).

theogravity avatar Sep 14 '22 17:09 theogravity