OAuth2 - mobile app redirection issue, stays in browser

Viewed 659

I know that similar threads exist but I could not find the solution for my use case.

I am trying to authentify using OAuth2 from a mobile app made with Flutter. As a example here I am showing the Android case.

The redirect url I provide must start with http(s), otherwise identity provider refuses it. I have added the following Activity in my AndroidManifest.xml:

<activity android:name="com.linusu.flutter_web_auth.CallbackActivity">
        <intent-filter android:label="flutter_web_auth" 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" />
        </intent-filter>
    </activity>

I am using the lib oauth2_client to make the requests.

var myOAuth2Client = new MyOAuth2Client(redirectUri: "http://my-app", customUriScheme: "http");
AccessTokenResponse tknResp = await myOAuth2Client.getTokenWithAuthCodeFlow(
    clientId: 'xxxxxxxxxxxxxx',
    clientSecret: 'xxxxxxxxxxxxxx',
    scopes: ['the.profile']).catchError((onError) {
  print("Error $onError");
});

With this, I am well redirected to the identity provider login page in the browser. Once I login with the credentials, I am not redirected to my app. Instead, I am redirected to an invalid url in the browser. Note that if I force to open the url with my app instead of browser, it works well.

I have read about Android app links, but I understood that it requires editing on server side, which I do not have access to (the goal here is to have a standalone mobile app authentifying).

Could somebody guide me on how to get redirected to my app? (If this is not possible and would require a server on my side, what would be the flow?) Thanks! :)

1 Answers

If you want to use https redirect URIs then you will have to use app links to return to the app. It is a tricky flow to get right.

There is a well known issue where you need a User Gesture for the response to be received and to avoid the problem you describe.

A possible quick solution is to configure the Authorization Server to show a consent screen after every user login, to act as a user gesture.

There is a code sample of mine which you can run on an emulator, and it has some links to blog posts which explain the tricky issues in more detail:

Android Claimed HTTPS Schemes Code Sample

It is written in Kotlin though, and you may find that the mobile security is harder to get right in Flutter.

Related