openid / AppAuth-Android

Android client SDK for communicating with OAuth 2.0 and OpenID Connect providers.
https://openid.github.io/AppAuth-Android
Apache License 2.0
2.87k stars 887 forks source link

Redirect URI is not been handled by the app and therefore getting page not found #764

Open waldjdida opened 2 years ago

waldjdida commented 2 years ago

Configuration

Description

Android app is unable to catch the redirect Uri and therefore unable to complete authentication.

I don't seem to see where the issue is

I am running the app in Android Simulator

This is my configuration

AndroidManifest.xml

Added this in the application tag

<activity
    android:name="net.openid.appauth.RedirectUriReceiverActivity"
    android:theme="@style/Theme.AppCompat.NoActionBar">
        <intent-filter>
            <action android:name="android.intent.action.VIEW"/>

            <category android:name="android.intent.category.DEFAULT"/>
            <category android:name="android.intent.category.BROWSABLE"/>
      <data android:scheme="https"
              android:host="sub.company.com"
              android:path="/oauthredirect"/>
        </intent-filter>
</activity>

The config used in the react native app:

const configs = {
  identityserver: {
    issuer: 'https://sub.company.com',
    clientId: 'company_react_mobile',
    redirectUrl: 'https://sub.company.com/oauthredirect',
    scopes: ['openid', 'profile', 'email', 'offline_access'],
  }
};

add this in build.gradle

android {
   ....
    defaultConfig {
        ....
        manifestPlaceholders = [
            appAuthRedirectScheme: 'https://sub.company.com' // I have used sub.company.com by itself here but no luck
            ]

    }

image

agologan commented 2 years ago

Couple of different things:

waldjdida commented 2 years ago

@agologan I made a progress in this.

After a thorough investigation, I realised and using that command that the redirect actually work.

So let me elaborate...

When the user first logs in, the app opens an in-app browser page to the auth server login page. Once the login is validated, the user is redirected to the app using the redirect URI and everything works as expected.

The issue lays when the user logs out the app or when revoke function is called. Apparently,the user is still logged in the browser used in the initial authentication.

But when I manually logs the user out in the browser and try log in through the app, I'm able to log in and the redirect works just fine.

It looks like I only get (see the screenshot in my previous post) the not found error page, when the user is already logged-in in the browser.

agologan commented 2 years ago

Token revocation in react-native-app-auth is not the same as logout done by calling EndSession with this lib which will open a browser window and invalidate your cookies also.

Due to the session being active per my last comment:

remember you need user interaction during the flow (the user needs to tap something in the browser) or the flow will most likely end up never redirecting back to the app

I fully expect your described behavior and encourage you to add an account confirmation step for the user to tap (something like, you're logged in as X tap here to continue) which would alleviate the problem since this is an SSO scenario and not logging out is not the only way to end up in this situation.

With everything said some developers have opted into using prompt=login during authentication which would ask the user to always relogin in case the flow is initiated in the app.

Maushundb commented 2 years ago

I'm experiencing a similar issue now.

main/AndroidManifest.xml:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
          xmlns:tools="http://schemas.android.com/tools"
          package="com.monarchmoney.mobile">
        ...
        <application
            android:name=".MainApplication"
            android:label="@string/app_name"
            android:icon="@mipmap/ic_launcher"
            android:roundIcon="@mipmap/ic_launcher_round"
            android:allowBackup="false"
            android:usesCleartextTraffic="true"
            android:theme="@style/AppTheme">
            ...

            <activity
                android:name="net.openid.appauth.RedirectUriReceiverActivity"
                tools:node="replace">
                 <intent-filter>
                    <action android:name="android.intent.action.VIEW"/>
                    <category android:name="android.intent.category.DEFAULT"/>
                    <category android:name="android.intent.category.BROWSABLE"/>
                    <data android:scheme="https"/>
                    <data android:scheme="http"/>
                    <data android:host="app.monarchmoney.com"/>
                    <data android:pathPrefix="/oauth"/>                
                </intent-filter>
            </activity>
        </application>
        ...
</manifest>

and config:

const COINBASE_OAUTH_CONFIG = {
  clientId: COINBASE_CLIENT_ID,
  redirectUrl: https://app.monarchmoney.com/oauth,
  scopes: COINBASE_SCOPES,
  serviceConfiguration: {
    authorizationEndpoint: COINBASE_AUTH_URL,
    tokenEndpoint: '',
  },
  skipCodeExchange: true,
  additionalParameters: { account: 'all' },
};

we're NOT setting appAuthRedirectScheme since it's my understanding that using the RedirectUriReceiverActivity is what you do instead of that if you want to use https app-links.

We go through the authorization flow, the user hits "Authorize" on the Coinbase site, then it just redirects to the app.monarchmoney.com website. BUT doing the same thing via adb adb shell am start -a android.intent.action.VIEW -d "https://app.monarchmoney.com/oauth?code=597&state=foo" appears to successfully redirect to the app for some reason.

If it helps, we also have a prod AndriodManifest override for our other app-links:

prod/AndriodManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
          package="com.monarchmoney.mobile">
    <application
            android:name=".MainApplication"
            android:label="@string/app_name"
            android:icon="@mipmap/ic_launcher"
            android:roundIcon="@mipmap/ic_launcher_round"
            android:allowBackup="false"
            android:theme="@style/AppTheme">
        <activity
                android:name=".MainActivity"
                android:label="@string/app_name"
                android:configChanges="keyboard|keyboardHidden|orientation|screenSize|uiMode"
                android:launchMode="singleTask"
                android:windowSoftInputMode="adjustResize">

            <intent-filter android:autoVerify="true">
                <action android:name="android.intent.action.VIEW"/>
                <category android:name="android.intent.category.DEFAULT"/>
                <category android:name="android.intent.category.BROWSABLE"/>

                <data android:scheme="https"/>
                <data android:scheme="http"/>
                <data android:host="app.monarchmoney.com"/>
                <data android:pathPrefix="/links"/>
            </intent-filter>
        </activity>
    </application>
</manifest>

Any guidance here would be appreciated @agologan

Maushundb commented 2 years ago

Opened my own issue over at https://github.com/openid/AppAuth-Android/issues/766 since they may be different.