Use Android App Link as an OAuth2 Redirect URI
Asked Answered
P

3

5

Is it possible to use Android App Links, starting with https:// such as: https://my-app.com/callback to redirect back to my application from an Android WebView in the end of an OAuth2 flow? I know how normal deep links work, such as com.my-app:// or my-app:// can be used to redirect back to my app. According to my understanding, the WebView doesn't know how to handle such protocols, passes the request up to the OS, and the OS than passes the request to my application which handles this url if an adequate IntentFilter is provided in AndroidManifest.xml.

Can this be done by a https:// scheme or the redirect will always be caught by the WebView and there's no way to redirect back to my app?

To specify what I want to achieve with steps:

  1. An IntentFilter is provided in AndroidManifest.xml to handle the app link, like:
<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="http" android:host="my-app.com/callback" />
 <data android:scheme="https" />
</intent-filter>
  1. A valid assetlinks.json is provided at https://my-app.com/.well-known/assetlinks.json (at this point, the IntentFilterIntent logs reveal that the validation of the JSON succeeds and I am able to open the app from the terminal with a command like npx uri-scheme open https://my-app.com/callback)
  2. My app starts an OAuth2 flow by launching CustomTabsIntent.launchUrl with an url like:
https://accounts.google.com/o/oauth2/v2/auth?
 scope=email%20profile&
 response_type=code&
 state=state&
 redirect_uri=https://my-app.com/callback&
 client_id=client_id

After these steps, I expect my app to open after a successful login because it is a valid handler of the url and don't want to be stuck in the browser. Is this possible, or the request will never be forwarded from the browser to the OS, because the browser is a valid handler of the https:// scheme?

If above is impossible, is there a way to navigate back from the WebView to the App, providing the auth_code or the only way to do this is to use custom schemes?

Psychosomatics answered 27/4, 2021 at 16:43 Comment(5)
what is the redirect_uri in Mobile App flow when it wants to send the credentials (i.e. access token and refresh token) toward the backend side? is it a backend endpoint or not?Leveret
I am not sure I understand your question correctly, but I try to help. Redirect_uri should be an url that your application claims through an IntentFilter so the OS knows to redirect that uri to your app, whenever that uri is called. This is not a backend endpoint. This redirect_uri is needed for the Authorization Request not the Token Request. Authorization Request gives back a code to your app that that can be later used in the Token Request to get back the access_token and refresh_token you are talking about.Psychosomatics
thank you for your response, maybe this post could represent my question betterLeveret
Actually, I thought redirect_uri should be my backend /callback endpoint because I want google calls my /callback endpoint in the backend to have access token here in the backend and store it into db.Leveret
I'll respond on your question.Psychosomatics
N
5

Specifically for Android 12 and up

  • In Android 12 Google has changed the way that web intents get resolved. If you are targeting Android 12 or above you need to implement specific features. Read more about it HERE

Anti practices

  • Please note that you should not be logging in your users via a WebView in your application. This is considered a Embedded User-Agents and as the official Internet Engineering Task Force OAuth 2.0 for Native Apps documentation, HERE, states: best current practice requires that native apps MUST NOT use embedded user-agents to perform authorization requests

OAuth best practices

For authorizing users in native apps, the best current practice is to perform the OAuth authorization request in an external user-agent(typically the browser) rather than an embedded user-agent (such as one implemented with web-views

  • Your application should NOT use a Android WebView. Instead, use a implicit intent to redirect the user to the browser to login

Redirect URI

  • When defining redirect URIs inside of an intent filter, they should follow this pattern: <scheme>://<host>:<port>[<path>|<pathPrefix>|<pathPattern>|<pathAdvancedPattern>|<pathSuffix>]
  • if you had a redirect URI of https://my-app.com/callback. The intent filter would be:
<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:host="my-app.com"
   android:scheme="https"
   android:path="/callback"
   />
</intent-filter>

Example

  • I have written a blog post, HERE, about using OAuth with the GitHub API in Android
Nadianadine answered 16/7, 2023 at 14:19 Comment(5)
please fix typo in ndroid:path="/callback"Rock
@Rock good catch!! just changed it nowNadianadine
This is a solution for vast majority of the apps. The problem however is when your app is a browser itself. The moment you add default http/https intent filter into manifests, this stops working. If anyone knows a workaround to this, let me know please.Mailbag
@Mailbag True! This solution is not suitable if you are using your application as a web browser(WebVIew). Also, I would like to add. It is not recommended to login via your application(Embedded User-Agents). The official Internet Engineering Task Force documentation, HERE, states: current practice requires that native apps MUST NOT use embedded user-agents to perform authorization requestsNadianadine
I'm using instagram basic display API but facebook is forcing me to put a valid URL in "Valid OAuth Redirect URIs" which doesn't make sense. I'm trying to put <my-app>://callback as a URI and it does not allow me so I switched to my-app.com/callback and the browser does not redirect me to the app, it just open the link from the browser. Am I missing something? How can go back to the app after authentication?Cheston
P
1

It turns out <data android:scheme="http" android:host="my-app.com/callback" /> was wrong and instead of this, <data android:scheme="http" android:host="my-app.com" android:path="/callback" /> should be used. android:host should never contain the path. I confirmed it is working well without any additional user gesture, just like if it were a plain deep-link. The browser actually recognizes that this url is a claimed url and forwards the response to the app.

Psychosomatics answered 28/4, 2021 at 12:20 Comment(0)
U
0

It is definitely possible (and recommended) to use Claimed HTTPS Schemes like this, though I have not done so with a WebView.

The tricky part is that redirection back to the app won't work reliably without a User Gesture - something that the user clicks. The user experience and reliability are both a little tricky and you may need an 'interstitial' internet web page.

In mobile OAuth it is recommended to use the AppAuth Pattern, where the system browser is used to handle the redirect, so that the app never has access to credentials.

For further details see the below code sample, which you can run on an emulator. The sample links to some blog posts, which discuss pros and cons, so that you can see if this type of solution is to your liking:

Unoccupied answered 27/4, 2021 at 18:12 Comment(2)
Thank you, the RFC ensured me that this is possible.Psychosomatics
what is the redirect_uri in Mobile App flow when it wants to send the credentials (i.e. access token and refresh token) toward the backend side? is it a backend endpoint or not?Leveret

© 2022 - 2024 — McMap. All rights reserved.