Issue
I am using AppAuth-Android in my app to handle the OAuth flow. When the flow starts, I call the startActivityForResults method as described in the https://github.com/openid/AppAuth-Android#obtaining-an-authorization-code step. After calling this method, the browser pops up waiting for the user login.
In my manifest I have
<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="com.app.name"
android:host="oauth2redirect/login-callback" />
</intent-filter>
that is needed for handling the redirect callback when login step is done, as specified in the AppAuth documentation.
During a penetration test on my app, came to light that if in this particular moment (when browser for authentication is visible), you follow the steps below, the app crash
- switch app (e.g. I open a browser, not closing my app)
- click on a NOT hierarchical link, com.name.app:abcd in my case (this URL was ready-made by the tester)
This is the stack trace of the crash.
E/AndroidRuntime: FATAL EXCEPTION: main
Process: io.app.mobile, PID: 29226
java.lang.RuntimeException: Unable to resume activity {com.app.name/net.openid.appauth.AuthorizationManagementActivity}: java.lang.UnsupportedOperationException: This isn't a hierarchical URI.
at android.app.ActivityThread.performResumeActivity(ActivityThread.java:3830)
at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:3862)
at android.app.servertransaction.ResumeActivityItem.execute(ResumeActivityItem.java:51)
at android.app.servertransaction.TransactionExecutor.executeLifecycleState(TransactionExecutor.java:145)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:70)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1816)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:193)
at android.app.ActivityThread.main(ActivityThread.java:6854)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:860)
Caused by: java.lang.UnsupportedOperationException: This isn't a hierarchical URI.
at android.net.Uri.getQueryParameterNames(Uri.java:1590)
at net.openid.appauth.AuthorizationManagementActivity.extractResponseData(AuthorizationManagementActivity.java:318)
at net.openid.appauth.AuthorizationManagementActivity.handleAuthorizationComplete(AuthorizationManagementActivity.java:259)
at net.openid.appauth.AuthorizationManagementActivity.onResume(AuthorizationManagementActivity.java:234)
at android.app.Instrumentation.callActivityOnResume(Instrumentation.java:1413)
at android.app.Activity.performResume(Activity.java:7307)
at android.app.ActivityThread.performResumeActivity(ActivityThread.java:3822)
The problem seems to be that opening com.name.app:abcd, makes the app believing that there is a result from the intent and net.openid.appauth.AuthorizationManagementActivity tries to handle it
private Intent extractResponseData(Uri responseUri) {
if (responseUri.getQueryParameterNames().contains(AuthorizationException.PARAM_ERROR)) {
return AuthorizationException.fromOAuthRedirect(responseUri).toIntent();
}
(...)
}
but the getQueryParameterNames of the class java.net.URI throws an exception if the URL is NOT hierarchical.
I am not sure if it is a problem related to the library itself, or if there is a solution that can be accomplished (maybe changing the manifest deep linking handling). The fact is that I do not know how to fix this.
If the question seems too synthetic and you need some additional information to reproduce the problem, feel free to ask for more details. Thanks :)
Solution
I assume the intent-filter you posted is set for RedirectUriReceiverActivity, but you can actually have your own Activity instead to be the man-in-the-middle. If you look into the source code it basically does nothing more than
startActivity(AuthorizationManagementActivity.createResponseHandlingIntent(
this, getIntent().getData()));
- Create your own Activity e.g.
AllUriReceiverActivity - set intent-filter (that you posted above) for this
AllUriReceiverActivity in
onCreate()ofAllUriReceiverActivityadd check ifgetIntent().getData()contains hierarchical URI before performingstartActivity()call.Reuse library's
RedirectUriReceiverActivity, so you don't need to worry when library updates the way of instantiatingAuthorizationManagementActivity
So in onCreate() it should be sth like this:
Uri uri = getIntent().getData();
if (uri.isHierarchical()) {
Intent i = new Intent(context, RedirectUriReceiverActivity.class);
i.setData(uri);
startActivity(i);
}
finish();
EDIT: Additionally to get rid of the handling your URI by RedirectUriReceiverActivity, you can remove completely this part suggested by AppAuth lib:
android.defaultConfig.manifestPlaceholders = [
'appAuthRedirectScheme': '...'
]
Answered By - moozg
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.