Skip to content

Commit 760b740

Browse files
somalayaCopilot
andauthored
Handling https scheme for device enrollment link, Fixes AB#3344894 (#2732)
Issue : In my testing, I noticed that OneAuth team started sending a config for a confidential client and that there is a corner case for device enrollment url's scheme on eSTS side. Our contract with eSTS has been to send "browser://" scheme for device enrollment url redirect and we enable webcp flow once we notice the url is of browser scheme and has device enrollment parameters. But eSTS's corner case is that when the calling app is a web app, they pass https:// scheme instead. My logic to handle webcp flow is not triggered in this case and breaks the user's sign in. Although this is a corner case scenario, we may start seeing issues if consumers of OneAuth or MSAL register themselves as webapp/confidential clients unknowingly. Link to ests code where they replace browser scheme with https in specific cases : https://msazure.visualstudio.com/One/_git/ESTS-Main?path=/src/Product/Microsoft.AzureAD.ESTS/Sts/ConditionalAccess/DevicePolicyError.cs&version=GBmaster&_a=contents&line=497&lineStyle=plain&lineEnd=503&lineStartColumn=1&lineEndColumn=10 My fix : Is a small change to start supporting webcp flow with https:// scheme as well. Fixes [AB#3344894](https://identitydivision.visualstudio.com/fac9d424-53d2-45c0-91b5-ef6ba7a6bf26/_workitems/edit/3344894) --------- Co-authored-by: Copilot <[email protected]>
1 parent 53fb015 commit 760b740

File tree

3 files changed

+47
-17
lines changed

3 files changed

+47
-17
lines changed

common/src/main/java/com/microsoft/identity/common/adal/internal/AuthenticationConstants.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1282,6 +1282,11 @@ public static String computeMaxHostBrokerProtocol() {
12821282
*/
12831283
public static final String BROWSER_DEVICE_CA_URL_QUERY_STRING_PARAMETER = "&ismdmurl=1";
12841284

1285+
/**
1286+
* The scheme for HTTPS URLs.
1287+
*/
1288+
public static final String HTTPS_SCHEME = "https";
1289+
12851290
/**
12861291
* Activity name to launch company portal.
12871292
*/

common/src/main/java/com/microsoft/identity/common/internal/ui/webview/AzureActiveDirectoryWebViewClient.java

Lines changed: 35 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -343,6 +343,9 @@ else if (isRedirectUrl(formattedURL)) {
343343
processWebCpEnrollmentUrl(view, url);
344344
} else if (mIsWebCpInWebViewFeatureEnabled && isWebCpAuthorizeUrl(url)) {
345345
processWebCpAuthorize(view, url);
346+
} else if (isDeviceCaRequest(url) && isHttpsScheme(url)) {
347+
// Special handling for device CA requests due to a corner case in eSTS for webapps/confidential clients, which should be handled by the WebView.
348+
processDeviceCaRequest(view, url);
346349
} else {
347350
Logger.info(methodTag,"This maybe a valid URI, but no special handling for this mentioned URI, hence deferring to WebView for loading.");
348351
processInvalidUrl(url);
@@ -575,33 +578,47 @@ private void processWebsiteRequest(@NonNull final WebView view, @NonNull final S
575578
view.stopLoading();
576579

577580
if (isDeviceCaRequest(url)) {
578-
Logger.info(methodTag, "This is a device CA request.");
579-
580-
if (shouldLaunchCompanyPortal()) {
581-
// If CP is installed, redirect to CP.
582-
// TODO: Until we get a signal from eSTS that CP is the MDM app, we cannot assume that.
583-
// CP is currently working on this.
584-
// Until that comes, we'll only handle this in ipphone.
585-
try {
586-
launchCompanyPortal();
587-
return;
588-
} catch (final Exception ex) {
589-
Logger.warn(methodTag, "Failed to launch Company Portal, falling back to browser.");
590-
}
591-
}
592-
593-
loadDeviceCaUrl(url, view);
581+
processDeviceCaRequest(view, url);
594582
} else {
595583
Logger.info(methodTag, "Not a device CA request. Redirecting to browser.");
596584
openLinkInBrowser(url);
597585
returnResult(RawAuthorizationResult.ResultCode.CANCELLED);
598586
}
599587
}
600588

589+
/**
590+
* Processed device CA requests detected in the web flow.
591+
* @param view The {@link WebView} instance in which the request originated.
592+
* @param url The URL representing the device CA request.
593+
*/
594+
private void processDeviceCaRequest(@NonNull final WebView view, @NonNull final String url) {
595+
final String methodTag = TAG + ":processDeviceCaRequest";
596+
Logger.info(methodTag, "This is a device CA request.");
597+
598+
if (shouldLaunchCompanyPortal()) {
599+
// If CP is installed, redirect to CP.
600+
// TODO: Until we get a signal from eSTS that CP is the MDM app, we cannot assume that.
601+
// CP is currently working on this.
602+
// Until that comes, we'll only handle this in ipphone.
603+
try {
604+
launchCompanyPortal();
605+
return;
606+
} catch (final Exception ex) {
607+
Logger.warn(methodTag, "Failed to launch Company Portal, falling back to browser.");
608+
}
609+
}
610+
611+
loadDeviceCaUrl(url, view);
612+
}
613+
601614
private boolean isDeviceCaRequest(@NonNull final String url) {
602615
return url.contains(AuthenticationConstants.Broker.BROWSER_DEVICE_CA_URL_QUERY_STRING_PARAMETER);
603616
}
604617

618+
private boolean isHttpsScheme(@NonNull final String url) {
619+
return url.startsWith(AuthenticationConstants.Broker.HTTPS_SCHEME);
620+
}
621+
605622
// Decides whether to launch the Company Portal app based on the presence of the IPPhone app and its signature.
606623
private boolean shouldLaunchCompanyPortal() {
607624
final PackageHelper packageHelper = new PackageHelper(getActivity().getPackageManager());
@@ -647,6 +664,7 @@ protected boolean isWebCpInWebviewFeatureEnabled(@NonNull final String originalU
647664
try {
648665
if (!ProcessUtil.isRunningOnAuthService(getActivity().getApplicationContext())) {
649666
// Enabling webcp in webview feature for brokered flows only for now.
667+
Logger.info(methodTag, "Not running on AuthService, skipping WebCP in WebView feature check.");
650668
return false;
651669
}
652670

@@ -662,7 +680,7 @@ protected boolean isWebCpInWebviewFeatureEnabled(@NonNull final String originalU
662680
SpanExtension.current().setAttribute(AttributeName.web_cp_flight_get_time.name(), (System.currentTimeMillis() - webCpGetFlightStartTime));
663681
if (isWebCpFlightEnabled) {
664682
// Directly enabled via flight rollout.
665-
Logger.info(methodTag, "WebCP in WebView feature is enabled. ");
683+
Logger.info(methodTag, "WebCP in WebView feature is enabled.");
666684
mIsWebCpInWebViewFeatureEnabled = true;
667685
return true;
668686
}

common/src/test/java/com/microsoft/identity/common/internal/ui/webview/AzureActiveDirectoryWebViewClientTest.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,8 @@ public class AzureActiveDirectoryWebViewClientTest {
9595
private static final String TEST_REDIRECT_URL = "ABC12/xyz";
9696
private static final String TEST_WEBSITE_REQUEST_URL = "browser://abcxyz/a";
9797
private static final String TEST_BROWSER_DEVICE_CA_URL_QUERY_STRING_PARAMETER = "browser://abcxyz/xyz&ismdmurl=1";
98+
99+
private static final String TEST_HTTPS_DEVICE_CA_URL_QUERY_STRING_PARAMETER = "https://abcxyz/xyz&ismdmurl=1";
98100
private static final String TEST_INSTALL_REQUEST_URL = "msauth://wpj/?username=someusername%somedomain.onmicrosoft.com&app_link=https%3a%2f%2fplay.google.com%2fstore%2fapps%2fdetails%3fid%3dcom.azure.authenticator%26referrer%3dcom.msft.identity.client.sample.local";
99101
private static final String TEST_DEVICE_REGISTRATION_URL = "msauth://wpj/?username=someusername%somedomain.onmicrosoft.com";
100102
private static final String TEST_BLANK_PAGE_REQUEST_URL = "about:blank";
@@ -170,6 +172,11 @@ public void testUrlOverrideHandlesWebsiteRequestUrl() {
170172
assertTrue(mWebViewClient.shouldOverrideUrlLoading(mMockWebView, TEST_BROWSER_DEVICE_CA_URL_QUERY_STRING_PARAMETER));
171173
}
172174

175+
@Test
176+
public void testUrlOverrideHandlesHttpsDeviceCARequestUrl() {
177+
assertTrue(mWebViewClient.shouldOverrideUrlLoading(mMockWebView, TEST_HTTPS_DEVICE_CA_URL_QUERY_STRING_PARAMETER));
178+
}
179+
173180
@Test
174181
public void testUrlOverrideHandlesInstallRequest() {
175182
assertTrue(mWebViewClient.shouldOverrideUrlLoading(mMockWebView, TEST_INSTALL_REQUEST_URL));

0 commit comments

Comments
 (0)