okta-react-native icon indicating copy to clipboard operation
okta-react-native copied to clipboard

Authentication with sessionToken rejects Promise (Android)

Open kennyho-ml opened this issue 4 years ago • 14 comments

I'm submitting a:

  • [x] Bug report
  • [ ] Feature request
  • [ ] Other (Describe below)

Current behavior

I'm using the Js wrapper to login => get a sessionToken => use authenticate with session Token

      const response = await getAuthClient().signInWithCredentials({username, password})

      const {sessionToken } = response

      await authenticate({sessionToken})

On IOS, this works as expected as I see the network requests via Flipper that is calling the authn endpoints. Then after you call authenticate it calls authorize which sets the sid cookie.

❗ However on android, when you call authenticate it seems like it's rejecting a promise (which maybe why it doesn't call authorize

Here are the logs

Possible Unhandled Promise Rejection (id: 5):
TypeError: null is not an object (evaluating '_reactNative.NativeModules.OktaSdkBridge.authenticate')
_callee5$@http://10.0.2.2:8081/index.bundle?platform=android&dev=true&minify=false&app=com.oktaandroidtest&modulesOnly=false&runModule=true:110719:87
tryCatch@http://10.0.2.2:8081/index.bundle?platform=android&dev=true&minify=false&app=com.oktaandroidtest&modulesOnly=false&runModule=true:24264:23
invoke@http://10.0.2.2:8081/index.bundle?platform=android&dev=true&minify=false&app=com.oktaandroidtest&modulesOnly=false&runModule=true:24434:32
tryCatch@http://10.0.2.2:8081/index.bundle?platform=android&dev=true&minify=false&app=com.oktaandroidtest&modulesOnly=false&runModule=true:24264:23
invoke@http://10.0.2.2:8081/index.bundle?platform=android&dev=true&minify=false&app=com.oktaandroidtest&modulesOnly=false&runModule=true:24336:30
http://10.0.2.2:8081/index.bundle?platform=android&dev=true&minify=false&app=com.oktaandroidtest&modulesOnly=false&runModule=true:24366:19
tryCallTwo@http://10.0.2.2:8081/index.bundle?platform=android&dev=true&minify=false&app=com.oktaandroidtest&modulesOnly=false&runModule=true:28950:9
doResolve@http://10.0.2.2:8081/index.bundle?platform=android&dev=true&minify=false&app=com.oktaandroidtest&modulesOnly=false&runModule=true:29114:25
Promise@http://10.0.2.2:8081/index.bundle?platform=android&dev=true&minify=false&app=com.oktaandroidtest&modulesOnly=false&runModule=true:28973:14
callInvokeWithMethodAndArg@http://10.0.2.2:8081/index.bundle?platform=android&dev=true&minify=false&app=com.oktaandroidtest&modulesOnly=false&runModule=true:24365:33
enqueue@http://10.0.2.2:8081/index.bundle?platform=android&dev=true&minify=false&app=com.oktaandroidtest&modulesOnly=false&runModule=true:24370:157
http://10.0.2.2:8081/index.bundle?platform=android&dev=true&minify=false&app=com.oktaandroidtest&modulesOnly=false&runModule=true:24385:69
_callee5@http://10.0.2.2:8081/index.bundle?platform=android&dev=true&minify=false&app=com.oktaandroidtest&modulesOnly=false&runModule=true:110714:38
_callee2$
tryCatch@http://10.0.2.2:8081/index.bundle?platform=android&dev=true&minify=false&app=com.oktaandroidtest&modulesOnly=false&runModule=true:24264:23
invoke@http://10.0.2.2:8081/index.bundle?platform=android&dev=true&minify=false&app=com.oktaandroidtest&modulesOnly=false&runModule=true:24434:32
tryCatch@http://10.0.2.2:8081/index.bundle?platform=android&dev=true&minify=false&app=com.oktaandroidtest&modulesOnly=false&runModule=true:24264:23
invoke@http://10.0.2.2:8081/index.bundle?platform=android&dev=true&minify=false&app=com.oktaandroidtest&modulesOnly=false&runModule=true:24336:30
http://10.0.2.2:8081/index.bundle?platform=android&dev=true&minify=false&app=com.oktaandroidtest&modulesOnly=false&runModule=true:24346:21
tryCallOne@http://10.0.2.2:8081/index.bundle?platform=android&dev=true&minify=false&app=com.oktaandroidtest&modulesOnly=false&runModule=true:28941:16
http://10.0.2.2:8081/index.bundle?platform=android&dev=true&minify=false&app=com.oktaandroidtest&modulesOnly=false&runModule=true:29042:27
http://10.0.2.2:8081/index.bundle?platform=android&dev=true&minify=false&app=com.oktaandroidtest&modulesOnly=false&runModule=true:29633:26
_callTimer@http://10.0.2.2:8081/index.bundle?platform=android&dev=true&minify=false&app=com.oktaandroidtest&modulesOnly=false&runModule=true:29529:17
_callReactNativeMicrotasksPass@http://10.0.2.2:8081/index.bundle?platform=android&dev=true&minify=false&app=com.oktaandroidtest&modulesOnly=false&runModule=true:29568:17
callReactNativeMicrotasks@http://10.0.2.2:8081/index.bundle?platform=android&dev=true&minify=false&app=com.oktaandroidtest&modulesOnly=false&runModule=true:29778:44
__callReactNativeMicrotasks@http://10.0.2.2:8081/index.bundle?platform=android&dev=true&minify=false&app=com.oktaandroidtest&modulesOnly=false&runModule=true:3049:46
http://10.0.2.2:8081/index.bundle?platform=android&dev=true&minify=false&app=com.oktaandroidtest&modulesOnly=false&runModule=true:2827:45
__guard@http://10.0.2.2:8081/index.bundle?platform=android&dev=true&minify=false&app=com.oktaandroidtest&modulesOnly=false&runModule=true:3032:15
flushedQueue@http://10.0.2.2:8081/index.bundle?platform=android&dev=true&minify=false&app=com.oktaandroidtest&modulesOnly=false&runModule=true:2826:21
flushedQueue@[native code]
invokeCallbackAndReturnFlushedQueue@[native code]

Expected behavior

Able to call authenticate on android and have the sid cookie set on the device. (just for reference... I'm using sid cookie to SSO into zendesk).

Minimal reproduction of the problem with instructions

Creating new react-native app and install new okta... via

{
  "name": "oktaandroidtest",
  "version": "0.0.1",
  "private": true,
  "scripts": {
    "android": "react-native run-android",
    "ios": "react-native run-ios",
    "start": "react-native start",
    "test": "jest",
    "lint": "eslint ."
  },
  "dependencies": {
    "@okta/okta-react": "^6.2.0",
    "@okta/okta-react-native": "^2.1.1",
    "react": "17.0.2",
    "react-native": "0.66.0"
  },
  "devDependencies": {
    "@babel/core": "^7.12.9",
    "@babel/runtime": "^7.12.5",
    "@react-native-community/eslint-config": "^2.0.0",
    "babel-jest": "^26.6.3",
    "eslint": "7.14.0",
    "jest": "^26.6.3",
    "metro-react-native-babel-preset": "^0.66.2",
    "react-test-renderer": "17.0.2"
  },
  "jest": {
    "preset": "react-native"
  }
}

Config taken from https://github.com/okta/okta-react-native#createconfig:

await createConfig({
  issuer: "https://{yourOktaDomain}/oauth2/default", // Optional
  clientId: "{clientId}",
  redirectUri: "{redirectUri}",
  endSessionRedirectUri: "{endSessionRedirectUri}",
  discoveryUri: "https://{yourOktaDomain}",
  scopes: ["openid", "profile", "offline_access"],
  requireHardwareBackedKeyStore: true, // Optional
  androidChromeTabColor: "#FF00AA", // Optional
  browserMatchAll: true, // Optional
  httpConnectionTimeout: 15, // Optional
  httpReadTimeout: 10, // Optional
});

Okta calls:

  const onSubmit = async () => {
      const response = await getAuthClient().signInWithCredentials({username, password})

      const {sessionToken } = response

      await authenticate({sessionToken})
  }

Extra information about the use case/user story you are trying to implement

Environment

  • Package Version: 2.1.1
  • React Native Version: 17.0.2
  • OS: Mac
  • Node version (node -v): 14.18.0
  • Other:

kennyho-ml avatar Oct 12 '21 16:10 kennyho-ml

Hi @kennyho-ml can you make sure the response is not null by using a print statement?

JayNewstrom avatar Oct 12 '21 16:10 JayNewstrom

Hi @kennyho-ml can you make sure the response is not null by using a print statement?

@JayNewstrom I'm not able to get print the response ..as it's throwing an error ... I get

{ [TypeError: null is not an object (evaluating '_reactNative.NativeModules.OktaSdkBridge.authenticate')]
  line: 110740,
  column: 87,
  sourceURL: 'http://10.0.2.2:8081/index.bundle?platform=android&dev=true&minify=false&app=com.oktaandroidtest&modulesOnly=false&runModule=true' }

when printing the error.

kennyho-ml avatar Oct 12 '21 21:10 kennyho-ml

What does this print?

const response = await getAuthClient().signInWithCredentials({username, password})
console.log(response)

JayNewstrom avatar Oct 12 '21 21:10 JayNewstrom

What does this print?

const response = await getAuthClient().signInWithCredentials({username, password})
console.log(response)

@JayNewstrom

{"cancel": [Function anonymous], "data": {"_embedded": {"user": [Object]}, "_links": {"cancel": [Object]}, "expiresAt": "2021-10-13T16:11:28.000Z", "sessionToken": "20111bvGnQPruqwMDsYC63FJEKRnwiQ40WPRcWWDiUSvgQ38LIOU3S1", "status": "SUCCESS"}, "expiresAt": "2021-10-13T16:11:28.000Z", "sessionToken": "20111bvGnQPruqwMDsYC63FJEKRnwiQ40WPRcWWDiUSvgQ38LIOU3S1", "status": "SUCCESS", "user": {"id": "00u27hp8vtU9IDa3s5d7", "passwordChanged": "2021-10-13T13:20:23.000Z", "profile": {"firstName": "mary", "lastName": "poppins", "locale": "en", "login": "[email protected]", "timeZone": "America/Los_Angeles"}}}

Also .. I created my own personal okta instance... and I'm getting [Error: Okta Oidc error]

when doing:

  const onSubmit = async () => {
    try {
      const response = await getAuthClient().signInWithCredentials({
        username,
        password,
      });
      console.log('response: ', response);
      const {sessionToken} = response;
      console.log('SESSION TOKEN: ', sessionToken);
      const resp = await authenticate({sessionToken: sessionToken});
      console.log('AUTHENTICATE, ', resp);
    } catch (e) {
      console.log('ERROR : ', e);
    }
  };

Not sure if this might help.

kennyho-ml avatar Oct 13 '21 16:10 kennyho-ml

@kennyho-ml which line is failing with [Error: Okta Oidc error]?

Is it the getAuthClient().signInWithCredentials line?

JayNewstrom avatar Oct 13 '21 16:10 JayNewstrom

@kennyho-ml which line is failing with [Error: Okta Oidc error]?

Is it the getAuthClient().signInWithCredentials line? @JayNewstrom nope..

await authenticate({sessionToken})

kennyho-ml avatar Oct 13 '21 16:10 kennyho-ml

What does your log for this line return?

console.log('SESSION TOKEN: ', sessionToken);

Is it a valid token?

JayNewstrom avatar Oct 13 '21 16:10 JayNewstrom

What does your log for this line return?

console.log('SESSION TOKEN: ', sessionToken);

Is it a valid token?

I assume so .. 'SESSION TOKEN: ', '20111bvGnQPruqwMDsYC63FJEKRnwiQ40WPRcWWDiUSvgQ38LIOU3S1'..

For IOS I get Screen Shot 2021-10-13 at 9 23 19 AM

I'm not sure why android doesn't have parity like so. .. (Getting to the requests past authn)


Here are the configs for android/app/build.gradle as well ... as I thought it might have to do something with the redirect

def nativeArchitectures = project.getProperties().get("reactNativeDebugArchitectures")

android {
    ndkVersion rootProject.ext.ndkVersion

    compileSdkVersion rootProject.ext.compileSdkVersion

    defaultConfig {
        applicationId "com.oktaandroidtest"
        minSdkVersion rootProject.ext.minSdkVersion
        targetSdkVersion rootProject.ext.targetSdkVersion
        versionCode 1
        versionName "1.0"
        manifestPlaceholders = [
                appAuthRedirectScheme: 'com.oktaandroidtest'
        ]
    }
...
    ```

kennyho-ml avatar Oct 13 '21 16:10 kennyho-ml

I've created an internal issue for us to take a look at this. OKTA-437013

Judging by what you've provided, it looks like a bug. If you have a chance, could you show the network logs for the Android version as well.

JayNewstrom avatar Oct 13 '21 18:10 JayNewstrom

I've created an internal issue for us to take a look at this. OKTA-437013

Judging by what you've provided, it looks like a bug. If you have a chance, could you show the network logs for the Android version as well.

Here are the logs:

Device Logs: Screen Shot 2021-10-13 at 4 10 21 PM

Network Logs: Screen Shot 2021-10-13 at 4 10 56 PM

kennyho-ml avatar Oct 13 '21 20:10 kennyho-ml

Hey @kennyho-ml Is there a reason to use await getAuthClient().signInWithCredentials?

I believe you can use a convenience method signIn, it does the same but in one line without needing to exchange session token. I'm not sure if it fixes the issue but still it's the SDK way to authenticate with creds.

oleggnidets-okta avatar Oct 27 '21 11:10 oleggnidets-okta

@oleggnidets-okta hi -- we used signInWithCredentials because it exposed the deviceId which allows you to remember the device and skip MFA... It shouldn't matter though since we get the sessionToken either way to call authenticate ?

-- also it said https://github.com/okta/okta-auth-js#signinoptions was being deprecated.. I think that was also one of our reasons.

kennyho-ml avatar Oct 27 '21 12:10 kennyho-ml

Having the same issue here has there been any movement on this?

JSummerv avatar May 12 '22 19:05 JSummerv

I was able to get a more detailed error back from the module [Hardware Backed KeyStore. Client require hardware backed keystore, but EncryptionManager doesn't support it.]

JSummerv avatar May 13 '22 16:05 JSummerv