Skip to content

Commit 6a3a974

Browse files
authored
Fix for App Link Usage in DUNA / SSO scenarios (#2745)
**Issue:** When app link redirect URI is used from within CCT then CCT may not redirect to the native app to handle the redirect and instead open it directly within the browser. From experience I've seen this happen there are existing cookies present at the IdP and there is no user interaction. **Solution:** Per [this chromium thread](https://issues.chromium.org/issues/40918490), the solution is set a flag when launching CCT called as [EXTRA_SEND_TO_EXTERNAL_DEFAULT_HANDLER](https://developer.android.com/reference/kotlin/androidx/browser/customtabs/CustomTabsIntent#EXTRA_SEND_TO_EXTERNAL_DEFAULT_HANDLER()). That flag was actually introduced in `androidx.browser` library version `1.7.0` and we were on a very ancient version (1.0.0). So this PR updates that library version to `1.7.0` As a side effect of that upgrade we can no longer use LocalBroadcastManager API (it's deprecated). So I've updated that accordingly similar to what @p3dr0rv was doing earlier when he tried upgrading browser library to 1.9.0 (which we couldn't do due to requiring compile sdk 36)
1 parent 6bd258b commit 6a3a974

File tree

4 files changed

+21
-7
lines changed

4 files changed

+21
-7
lines changed

changelog.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ vNext
77
- [MINOR] Add AAD authority validation for DUNA flow (#2740)
88
- [PATCH] Fix DualScreenActivity theme color constant (#2737)
99
- [MINOR] [SDL Assessment task] Secure webview settings (#2715)
10+
- [MINOR] Fix for App Link Usage in DUNA / SSO scenarios (#2745)
1011

1112
Version 22.0.3
1213
----------

common/src/main/java/com/microsoft/identity/common/internal/providers/oauth2/CurrentTaskAuthorizationActivity.java

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,15 +22,16 @@
2222
// THE SOFTWARE.
2323
package com.microsoft.identity.common.internal.providers.oauth2;
2424

25+
import android.annotation.SuppressLint;
2526
import android.content.BroadcastReceiver;
2627
import android.content.Context;
2728
import android.content.Intent;
2829
import android.content.IntentFilter;
30+
import android.os.Build;
2931
import android.os.Bundle;
3032

3133
import androidx.annotation.Nullable;
3234
import androidx.fragment.app.Fragment;
33-
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
3435

3536
import com.microsoft.identity.common.internal.ui.DualScreenActivity;
3637
import com.microsoft.identity.common.logging.Logger;
@@ -56,6 +57,7 @@ public class CurrentTaskAuthorizationActivity extends DualScreenActivity {
5657
private boolean mCloseCustomTabs = true;
5758
private BroadcastReceiver redirectReceiver;
5859

60+
@SuppressLint("UnspecifiedRegisterReceiverFlag")
5961
@Override
6062
public void onCreate(@Nullable Bundle savedInstanceState) {
6163
super.onCreate(savedInstanceState);
@@ -109,9 +111,16 @@ public void onReceive(Context context, Intent intent) {
109111
startActivity(newIntent);
110112
}
111113
};
112-
LocalBroadcastManager.getInstance(this).registerReceiver(redirectReceiver,
113-
new IntentFilter(REDIRECT_RETURNED_ACTION)
114-
);
114+
115+
116+
IntentFilter filter = new IntentFilter(REDIRECT_RETURNED_ACTION);
117+
// Use backward-compatible receiver registration
118+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { // API 33 = TIRAMISU
119+
// Use RECEIVER_NOT_EXPORTED for Android 13+ to prevent external apps from sending broadcasts
120+
registerReceiver(redirectReceiver, filter, Context.RECEIVER_NOT_EXPORTED); // 0x4 = RECEIVER_NOT_EXPORTED
121+
} else {
122+
registerReceiver(redirectReceiver, filter);
123+
}
115124
}
116125
}
117126

@@ -126,7 +135,8 @@ protected void onNewIntent(final Intent intent) {
126135
super.onNewIntent(intent);
127136
if (REFRESH_TO_CLOSE.equals(intent.getAction())) {
128137
final Intent broadcast = new Intent(DESTROY_REDIRECT_RECEIVING_ACTIVITY_ACTION);
129-
LocalBroadcastManager.getInstance(this).sendBroadcast(broadcast);
138+
broadcast.setPackage(getPackageName()); // Restrict to our app only
139+
sendBroadcast(broadcast);
130140
unregisterAndFinish();
131141
}
132142
//IMPORTANT: If you don't call this...
@@ -158,7 +168,9 @@ protected void onResume() {
158168
}
159169

160170
private void unregisterAndFinish() {
161-
LocalBroadcastManager.getInstance(this).unregisterReceiver(redirectReceiver);
171+
if (redirectReceiver != null) {
172+
unregisterReceiver(redirectReceiver);
173+
}
162174
finish();
163175
}
164176
}

common/src/main/java/com/microsoft/identity/common/internal/ui/browser/CustomTabsManager.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,7 @@ public synchronized boolean bind(final @Nullable Context context, @NonNull Strin
132132

133133
// Create the Intent used to launch the Url
134134
final CustomTabsIntent.Builder builder = new CustomTabsIntent.Builder(createSession(null));
135+
builder.setSendToExternalDefaultHandlerEnabled(true);
135136
mCustomTabsIntent = builder.setShowTitle(true).build();
136137
mCustomTabsIntent.intent.setPackage(browserPackage);
137138
return true;

gradle/versions.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ ext {
2525
androidxCoreVersion = "1.5.0"
2626
annotationVersion = "1.0.0"
2727
appCompatVersion = "1.1.0"
28-
browserVersion = "1.0.0"
28+
browserVersion = "1.7.0"
2929
constraintLayoutVersion = "1.1.3"
3030
dexmakerMockitoVersion = "2.19.0"
3131
espressoCoreVersion = "3.1.0"

0 commit comments

Comments
 (0)