Skip to content
This repository has been archived by the owner on Oct 24, 2024. It is now read-only.

Confused? Is Okta auth in Android apps shareable with webviews? #877

Open
3 of 8 tasks
bdruth opened this issue Aug 27, 2020 · 16 comments
Open
3 of 8 tasks

Confused? Is Okta auth in Android apps shareable with webviews? #877

bdruth opened this issue Aug 27, 2020 · 16 comments

Comments

@bdruth
Copy link

bdruth commented Aug 27, 2020

I'm submitting this issue for the package(s):

  • jwt-verifier
  • okta-angular
  • oidc-middleware
  • okta-react
  • okta-react-native

I'm submitting a:

  • Bug report
  • Feature request
  • Other (Describe below)

Current behavior

I'm new to Okta and trying to navigate the best way to incorporate Okta authentication in native apps (iOS/Android) to SSO with webviews opened by these apps to apps protected by the same Okta domain. I've been able to get this working in iOS using the custom-sign-in example in https://github.com/okta/samples-js-react-native and the information to setup usePersistentCookie. On Android, however, I'm not connecting the dots. Is this possible? I've seen an issue reference Chrome Custom Tabs and how cookies can't be shared to a webview from there, but it doesn't look like the custom-sign-in example uses that on Android. The browser-sign-in example is documented as returning a code to the app which is then exchanged for an access token and id token, so it doesn't appear that there's any cookie being set that a webview could inherit in this approach, either?

Expected behavior

Both Android and iOS platforms have an Okta SSO mechanism to embedded webviews from the native application.

Minimal reproduction of the problem with instructions

Run https://github.com/okta/samples-js-react-native apps on Android and use a webview (e.g. https://github.com/react-native-community/react-native-webview) to load an Okta web app protected in the same domain - should work w/o prompting for login again.

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

Implement a hybrid native app with some native functionality and some webview functionality under the same Okta domain without requiring multiple logins on Android.

Environment

  • Package Version: okta-react-native 1.4.0
  • Browser: n/a
  • OS: Android Q (29)
  • Node version (node -v): 12.6.3
  • Other:
@swiftone
Copy link
Contributor

@bdruth - Thanks for the question, I'll forward this to team members that can speak intelligently about react-native and see if we can get you an answer.

@shuowu
Copy link
Contributor

shuowu commented Aug 27, 2020

@bdruth Webview is not the recommended way to implement OIDC flow in the native app.
Quoted from https://www.linkedin.com/pulse/webviews-bad-use-appauth-mike-schwartz/

In a WebView any malicious code in the page has the same rights as your application, so you should make sure you only load trusted content. But there is another risk–a malicious app may also have access to browser content (like cookies) and may snoop passwords or intercept OAuth codes.

For the browser-sign-in, you may need to listen on signInSuccess event to get the tokens after redirect, like https://github.com/okta/samples-js-react-native/blob/82b302de87a1d8d0213bff4899604202aef1d312/browser-sign-in/App.js#L51-L54
If you want to implement customized UI, you can follow the custom-sign-in sample to build your native UI, then call signIn function from @okta/okta-react-native to acquire token.

signIn({ username, password })
      .then(token => {
        // do things with acquired token
      });

@bdruth
Copy link
Author

bdruth commented Aug 27, 2020

OK - that jives with some of the things I've read. What I'm not clear on is what to do with the acquired token so that there's a seamless SSO? I'm not married to using webviews, and I've read that Chrome Custom Tabs on Android might be the better option, though it's bizarre that those are two completely different things in react-native, and the cross-platform behavior is completely different for Chrome Custom Tabs ... ideally there'd be a simple way to use webviews on iOS and Chrome Custom Tabs on Android in an effectively identical way from React Native, but I digress ...

@shuowu
Copy link
Contributor

shuowu commented Aug 27, 2020

@bdruth The @okta/react-native has implemented the browser sign-in flow based on the android custom tab, you can use it by calling signIn function without providing any arguments.

@bdruth
Copy link
Author

bdruth commented Aug 28, 2020

Right ... but I need custom sign-in. So, how do I use custom sign-in and pass what to a Chrome Custom Tab?

@shuowu
Copy link
Contributor

shuowu commented Aug 28, 2020

For custom signin in react native you will need to build your own sign in UI, instead of using custom tabs to open the okta login page.

https://github.com/okta/okta-react-native#custom-sign-in

@bdruth
Copy link
Author

bdruth commented Aug 28, 2020

Right - I'm following all that. I have the custom-sign-in working from the Okta react-native samples. All good with custom-sign-in, but ... how do I SSO that to something, anything that can load a web page ... I don't really care if it's Chrome Custom Tabs or webviews at this point.

@shuowu
Copy link
Contributor

shuowu commented Aug 28, 2020

@bdruth If I understand your question correctly. You want to implement the SSO as the app redirects the user to a webpage (OKTA domain) to start the sign in process, then it redirects user back to the app after success sign in.
If that's the case, it is the browser sign in flow that provides from the sdk. It is implemented by using custom tabs in android.

Or you want to customize any step in the browser sign in flow?

@bdruth
Copy link
Author

bdruth commented Aug 28, 2020

No, that's not correct. We're looking at how we would have a native app, with native (custom sign-in flow), that will have native functionality in hybrid with loading web pages from existing / legacy secured systems. Both are setup in Okta using OIDC (there may be future need for SAML, too, but right now our test bed is using OIDC). Current behavior is:

  • user launches app for the first time, signs in using custom sign-in flow, accesses a view that loads a secured web-page and is redirected to the Okta sign-in screen.

desired behavior is:

  • user launches app for the first time, signs in using custom sign-in flow, accesses a view that loads a secured web-page and when redirecting for authentication, Okta recognizes the user is signed in and redirects back to the secured web-page with the necessary auth headers/cookies/whatever set

This is working in iOS using the usePersistentCookie and sharedCookiesEnabled on the react-native-webview. So, the question is, how do we accomplish this in the Android ecosystem.

@FeiChen-okta
Copy link
Contributor

FeiChen-okta commented Aug 29, 2020

Hi @bdruth,

The android native sdk needs to have webview support. I have an experimental branch with this webview but this is not something we are planning to support. If you like I can share the patch with you.

@bdruth
Copy link
Author

bdruth commented Aug 31, 2020

@FeiChen-okta - feel free to share patch. So, if I'm understanding correctly, the only way to have SSO between native & web content on Android is to use the browser-sign-in flow? Custom sign-in (without your experimental, unsupported patch) is not possible, irrespective of Chrome Custom Tabs or Webview?

@FeiChen-okta
Copy link
Contributor

Hi @bdruth We have a couple of different configurations

  1. custom-sign-in: To make SSO work for your legacy web pages you'll have to get the response headers from the custom signIn call and set those headers in react-native-webview

  2. browser-sign-in-chrome-tabs: This will not work for your legacy web pages if using react-native-webview since the sessions are stored in chrome and not webview. If you open your legacy web pages with chrome custom tabs then it will work but I'm not sure if react-native-webview supports it.

  3. browser-sign-in-webview: This will require the following patch. This will make oidc sdk use webview instead of chrome custom tabs. This way the session is already in webview so react-native-webview should work.

You can apply the following patch to the master branch in https://github.com/okta/okta-oidc-android
Once you've compiled the aar you'll have to add it to the android bridge.
0001-Webview-support.patch.txt

@bdruth
Copy link
Author

bdruth commented Sep 1, 2020

@FeiChen-okta thank you! So, I'm assuming I need to actually call signIn from @okta/okta-auth-js as is being done by the signIn call in okta-react-native, since the signIn exposed by okta-react-native is only returning the access token as far as I can tell? Or is there a way to make the call through okta-react-native?
@okta/okta-react-native#index.js

export const signIn = async(options) => {
  // Custom sign in
  if (options && typeof options === 'object') {
    return authClient.signIn(options)
      .then((transaction) => {
        const { status, sessionToken } = transaction;
        if (status !== 'SUCCESS') {
          throw new Error('Transaction status other than "SUCCESS" has been return, please handle it properly by calling "authClient.tx.resume()"');
        } 
        return authenticate({ sessionToken });
      })
      .then(token => {
        if (!token) {
          throw new Error('Failed to get accessToken');
        }

        return token;
      })
      .catch(error => {
        throw new OktaAuthError('-1000', 'Sign in was not authorized', error);
      });
  }

@FeiChen-okta
Copy link
Contributor

Hi @bdruth Currently the react-native SDK does not support a way to get the headers from the Android bridge. So you'll need a way to get the response header from HttpClientImpl.java to react-native layer and set the cookies in react-native-webview

Or the other way around where react-native set a boolean flag similar to iOS sharedCookiesEnabled. This is then propagated to HttpClientImpl and it will use CookieManager to set the cookies for WebView

After these changes signIn should set the correct cookies in WebView depending on which path you implement.
Unfortunately both methods require some changes to the SDK. I believe the react-native to Android way is the simplest since that seems to be the way react-native-webview is enabling cookies in iOS.

@bdruth
Copy link
Author

bdruth commented Sep 1, 2020

K, I'll take a look and see what I can come up with. Thanks much for your assistance thus far!

@gabrielmirandat
Copy link

@bdruth I am facing the same issue now. Have you workaround this? Tks

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants