auth0/Auth0.Android

idToken not being provided if not manually added via scope property result in exception thrown

ryandary opened this issue · 9 comments

* This method will use the /oauth/token endpoint with the 'refresh_token' grant, and the response will include an id_token and an access_token if 'openid' scope was requested when the refresh_token was obtained.

The language of the documentation suggests that the scope that are used when performing the initial auth will be applied on the renew, however it seems that this is not always the case. We found that when calling renew without specifically adding the scope parameter, the result of the call is an exception because the payload returned by the server did not contain the idToken.

Hi @ryandary

the response will include an id_token and an access_token if 'openid' scope was requested when the refresh_token was obtained

The documentation does say "if" openid scope is present. Have any suggestions to make this better?

That's clear. In my case, it is being provided in auth, so my expectation is that it will be provided in refresh.

@ryandary the renewAuth method will work only based on the parameters provided. It doesn't know of any previous state. You can consider it as a pure function that isn't influenced by previous states.

However what you can do is use our SecureCredentialsManager to manage your token and it will renew the token depending on the scope and does the management internally and securely. Hope this answers your questions. Feel free to let me know if you have more doubts and I'd be happy to help.

Perhaps the phrase that is confusing is "if 'openid' scope was requested when the refresh_token was obtained" as this suggests some prior state that is being considered. The "was requested... when.. was obtained" implies that some state is being remembered either internally on device, in the cloud or possibly in the token itself.

It is unclear to the caller (me in this case) that scope needed to be passed explicitly and that it needed to match what was passed at initial auth. The sentence that I started this thread with implies that as long as the initial auth included that scope that this function would also return the tokens.

The fact that the exception is thrown seems to suggest that the internal implementation also makes expectations that are based on state rather than on simply passed-in values.

Can you share the exception that you are referring to here?

Here is a snippet. This is caused by calling renewAuth on AuthenticationAPIClient without using the addParameter and passing the scope and the initial auth was called by passing the scope "openid email offline_access".

Caused by: com.auth0.android.Auth0Exception: Something went wrong
at com.auth0.android.authentication.AuthenticationAPIClient$Companion$createErrorAdapter$1.fromException(AuthenticationAPIClient.kt:816)
... 23 more
Caused by: java.lang.NullPointerException: idToken must not be null
at com.auth0.android.request.internal.CredentialsDeserializer.deserialize(CredentialsDeserializer.kt:38)

The point of interest is the idToken must not be null portion.

@ryandary Thanks for your patient response. I can understand the confusion now and the documentation is misleading. Let me explain the cause.

We usually return AuthenticationRequest when we return Credentials object and always use newAuthenticationBuilder in ParameterBuilder when we return Credentials. This will ensure the scope contains default required values one of which is openid

The renewAuth and token request in AuthenticationAPIClient don't seem to use this builder and thus doesn't have the required scope to build the credentials and object. Hence we are not able to build the Credentials object which requires a non null idToken

This error and documentation error might have happened because we use both these methods internally and we ensure default scopes are added internally.

I am looking into possible solution without affecting backward compatibilty. Will provide an update soon.

@ryandary we have added a fix to this. Thanks a lot for raising this to us :) This should be released soon.