okta / okta-idx-android

okta-idx-android
https://github.com/okta/okta-idx-android
Apache License 2.0
10 stars 14 forks source link

SDK token refresh support #156

Closed kevincmojo closed 2 years ago

kevincmojo commented 2 years ago

Describe the feature request?

The iOS sdk supports refreshing the access token with the call of a function. Would be nice to have similar functionality in the Android sdk.

New or Affected Resource(s)

Android Okta Idx SDK.

Provide a documentation link

https://developer.okta.com/docs/guides/oie-embedded-common-refresh-tokens/android/main/#overview

Additional Information?

No response

JayNewstrom commented 2 years ago

Hi @kevincmojo we just released idx-kotlin 2.0 this week! Which depends on our Credential Management SDK (Auth Foundation) in this repo.

Auth Foundation provides mechanisms to do refresh and similar.

If you have further questions, I'd be happy to help. Thanks!

kevincmojo commented 2 years ago

Hey @JayNewstrom, thanks for speedy response! Am I able to use this in conjunction with the idx sdk? For example, I use the idx client to authenticate the user and receive an access token, id token and refresh token, which I plan to use to make a post request for a new access token. Is there a way to take those and use the foundation library to do this for me?

JayNewstrom commented 2 years ago

Are you using the java SDK?

If so, you can still use auth-foundation. There are a few options:

There are plenty of other finer details, so if you need help going down one of these paths, I'd be happy to help.

kevincmojo commented 2 years ago

I'm using okta-idx-android, would I still be able to instantiate an oidcClient and call refreshToken with the refresh token I get from that sdk?

JayNewstrom commented 2 years ago

This repo is a little confusing:

The maven coordinates for the SDKs are as follows:

That being said, the tokens returned from all SDK are just OIDC Tokens which are generally compatible with any OIDC based SDK, including auth-foundation OidcClient

kevincmojo commented 2 years ago

Ah got it. I'm using the idx-kotlin repo. I setup an oidc client in my repo but when I attempt to call the refresh method I'm getting the following error:

com.okta.authfoundation.client.OidcClientResult$Error$HttpResponseException: The grant was issued for another authorization server.

Is it likely that my account is not setup to support this? This is how I setup the idx client config

        IdxClientConfiguration(
            issuer = "{environment_url}/oauth2/default".toHttpUrl(),
            clientId = "{client_id}",
            scopes = setOf("openid", "profile", "offline_access"),
            redirectUri = "{okta_environment}:/callback",
        )

and this is how I setup the oidc client

    val oidcConfiguration = OidcConfiguration(
        clientId = "{client_id}",
        defaultScope = "openid"
    )
    val oidcClient = OidcClient.createFromDiscoveryUrl(oidcConfiguration, "{environment_url}/.well-known/openid-configuration".toHttpUrl())
kevincmojo commented 2 years ago

I found this answer in the forum https://devforum.okta.com/t/the-grant-was-issued-for-another-authorization-server/7306 Does this mean I need to modify my idx config in order for this to work?

JayNewstrom commented 2 years ago

It looks like you’re super close! I think your org is configured correctly, but you need to make sure both configurations are using the same issuer. Once you upgrade to idk-kotlin version 2, this will all happen automatically. But for you now you can specify it manually by doing this:


val oidcConfiguration = OidcConfiguration(
        clientId = "{client_id}",
        defaultScope = "openid"
    )
    val oidcClient = OidcClient.createFromDiscoveryUrl(oidcConfiguration, "{environment_url}/oauth2/default/.well-known/openid-configuration".toHttpUrl())

It’s almost exactly the same as what you have now, just notice the oauth2/default/.

kevincmojo commented 2 years ago

Great, thank you! That got me past that error but I'm now seeing this

com.okta.authfoundation.client.IdTokenValidator$Error: Issued at time is not within the allowed threshold of now.

It looks like the issued at grace period is 600 seconds (5 minutes) and I'm making this request within a few minutes of receiving the refresh token so I'm not sure what the issue might be here.

As for idx-kotlin version 2, is this included in the Auth Foundation repo or is that another library within https://github.com/okta/okta-mobile-kotlin ?

JayNewstrom commented 2 years ago

Idx-kotlin remains in this repo, in the idx-kotlin directory. But it has a transitive dependency on auth foundation.

As for the error. My guess is that your device doesn’t have it’s time synced via NTP or similar (I think it’s the default on Android devices). There’s a few ways to fix this:

Version 1 of IDX Kotlin didn’t validate id tokens according to OIDC specs, but now Auth Foundation does as part of IDX Kotlin V2. Auth Foundation also does this validation as part of refreshes.

The easy fix is to just update the device to use the correct time, but this isn’t always an option for devices in the wild.

Your best bet would be to customize the EventCoordinator https://okta.github.io/okta-mobile-kotlin/auth-foundation/com.okta.authfoundation/-auth-foundation-defaults/index.html#925714337%2FProperties%2F1152495213

And listening for the https://okta.github.io/okta-mobile-kotlin/auth-foundation/com.okta.authfoundation.client.events/-validate-id-token-event/index.html event in the EventHandler you pass to your EventCoordinator.

From there you can set the issuedAtGracePeriodInSeconds to a much larger value.

JayNewstrom commented 2 years ago

Going to close this now. Feel free to open a new issue with any other questions.