idToken not being provided if not manually added via scope property result in exception thrown
ryandary opened this issue · 9 comments
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.