okta / okta-oidc-android

OIDC SDK for Android
https://github.com/okta/okta-oidc-android
Other
60 stars 45 forks source link

Refresh token error when app is closed (killed) #267

Closed deajakovl12 closed 2 years ago

deajakovl12 commented 2 years ago

RefreshToken method is returning AuthorizationException: {"type":0,"code":0,"errorDescription":"java.security.cert.CertPathValidatorException: Trust anchor for certification path not found."}

If we close the app and then open it again, and if refreshToken is needed to be called we get error above.

If we stay inside the app (for example 5 mins - token lifetime) and then refreshToken method works properly.

NikitaAvraimov-okta commented 2 years ago

Thanks for reaching out, do you have any additional logs? Have you specified correct redirect uri and discovery uri

deajakovl12 commented 2 years ago

I guess we have set it properly. Because as I said if we stay in-app until the token expires, and then call refreshToken everything works fine.

Only if we close the app, and then reopen it we get this error.

Is there a chance that this happens because of the newly created SessionClient object after the app is open?

NikitaAvraimov-okta commented 2 years ago

It is possible, could you share full stacktrace

deajakovl12 commented 2 years ago

image

image

So the OktaAuthClientProvider is class similar to the OktaManager used in this example https://developer.okta.com/blog/2021/01/06/android-login

image

JayNewstrom commented 2 years ago

Are you able to access the url you have configured in a browser on your computer? Are you able to recreate this on other devices?

deajakovl12 commented 2 years ago

Yeah, as I mentioned, we are able to refresh the token until the app is closed. Is it possible that killing the app and generating these objects in OktaAuthClientProvider somehow messes up the session client, because we don't know where to look at...

This is the interceptor that works properly, it checks the tokens, and if it is expired calls refreshOktaToken method that is already shown above. image

We can reproduce it on more devices yes.

JayNewstrom commented 2 years ago

I see. This is likely due to making parallel requests to refresh token. We've got some in progress work to enhance the SDK to enable parallel requests to refresh token.

That being said, the exception doesn't align with what we've seen in the past for parallel usage of refresh token.

Maybe you could try adding some locking around the interceptor to ensure only one request is made to refresh token at a time, to see if that is indeed the issue.

deajakovl12 commented 2 years ago

I think it is not connected to that issue.

For example, when we get that error on refreshToken, the app logs out (our mechanism because token expired) and we are unable to sign in via Okta, also we get the same error.

image

image

We are able to log in again when we close the app and open it again.

It is really strange behavior

JayNewstrom commented 2 years ago

I'd like to get to the bottom of this. I propose a few next steps:

Another option is to reach out to our support team, and share your code with them, to see if we can find an issue that way.

deajakovl12 commented 2 years ago

Okay. I have installed https://github.com/okta/samples-android/tree/master/browser-sign-in

set everything in okta_oidc_config.json as explained. Also added to app gradle appAuthRedirectScheme.

When pressing sign in button in that app I get the same error as in our application..

image

image

JayNewstrom commented 2 years ago

Are you using a custom url domain? https://developer.okta.com/docs/guides/custom-url-domain/overview/

Could you share your configuration URL? If you don't feel comfortable sharing publicly, you can share with our support team as well.

The url should look something along the lines of https://your_org_here.okta.com/oauth2/default

JayNewstrom commented 2 years ago

Are you using a proxy (such a charles proxy) on the device to inspect HTTPS traffic?

deajakovl12 commented 2 years ago

Yes, we are using a custom URL domain. It would be better to share it with your support team.

The thing I noticed in this sample app is that for example.

"https://oktapreview.company.com/oauth2/default" is, for example, our custom domain and with this, your sample application when pressing on the sign-in button generates the error above.

If I change this to "https://company.oktapreview.com/oauth2/default" that is not the custom domain, it is the domain you generated for us.

then when pressing the Sign-in button in your sample application web client is open and the sign-in screen is shown, after entering username and password in this client and pressing verify, again I am shown the error above.

I think also that we have some problems with discoveryUri and our custom domain.

Just a note, we have also iOS application and everything works fine, that's even stranger..

deajakovl12 commented 2 years ago

Just a note, we have "removed" the custom domain now, and set a default URL "https://company.oktapreview.com/oauth2/default"

We are able to log in normally in to your sample app.

Is there a chance that SDK has some problems with custom domain or maybe we did something that was not correctly configured?

deajakovl12 commented 2 years ago

Hello, we have found where the error was, okta configuration was not set properly on the server, the intermediate certificate was missing... These are the links that helped us solve it if anyone had a similar problem.

https://stackoverflow.com/questions/39264056/android-java-security-cert-certpathvalidatorexception-trust-anchor-for-certific https://developer.android.com/training/articles/security-ssl#MissingCa

But, we now have another problem, we are getting this error now

AuthorizationException: {"type":0,"code":3,"errorDescription":"Network error"}

I have googled it and found out that other people had this issue also. https://githubmemory.com/repo/okta/okta-oidc-android/issues/165?page=1

When the refresh token expires (for the test purposes we have set it to 5 minutes) and the user reopens the app we get that error for the first for example 2 calls, the third call on refresh token passes, but it is too late because we already logged out our user.

**Note we had the network access all the time.

Is there any workaround?

JayNewstrom commented 2 years ago

Could you get the full stack trace for the exception? My first guess is you're doing multiple requests to refreshToken in parallel, which isn't yet supported.

deajakovl12 commented 2 years ago

Hey Jay

Network error was not connected to this issue, an error that is thrown when we call more than once refreshToken method is "thread interrupted" exception.

Today we have I think cleared all errors, thanks for the support.

JayNewstrom commented 2 years ago

Glad everything worked out! Please open another issue if something comes up.