Skip to content

Commit

Permalink
Add support for OneBox Environment, Fixes AB#3113751 (#2559)
Browse files Browse the repository at this point in the history
Fixes
[AB#3113751](https://identitydivision.visualstudio.com/fac9d424-53d2-45c0-91b5-ef6ba7a6bf26/_workitems/edit/3113751)

Changes to allow MSAL/Broker to talk to eSTS running locally. This
basically does the following:

- Add build config flag to bypass authority validation. This is required
because local eSTS authorities are not discovered via cloud discovery.
We can enable this flag locally in gradle project properties to target
local eSTS.
- Read the port number of the authority when constructing the cloud URL
because targeting local eSTS requires supplying exact port. I've scoped
the change to read port only when environment is specified as onebox.

Related MSAL PR:
AzureAD/microsoft-authentication-library-for-android#2231
  • Loading branch information
shahzaibj authored Jan 8, 2025
1 parent 00aace6 commit c69eb7d
Show file tree
Hide file tree
Showing 7 changed files with 39 additions and 9 deletions.
1 change: 1 addition & 0 deletions changelog.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ vNext
- [MINOR] Add Child Spans for Interactive Span (#2516)
- [MINOR] For MSAL CPP flows, match exact claims when deleting AT with intersecting scopes (#2548)
- [MINOR] Replace Deprecated Keystore API for Android 28+ (#2558)
- [MINOR] Add support for OneBox Environment (#2559)
- [MINOR] Managed profile Android util method (#2561)
- [PATCH] Make userHandle response field optional (#2560)
- [MINOR] Nonce redirect changes (#2552)
Expand Down
6 changes: 6 additions & 0 deletions common4j/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,7 @@ def dcParameter = "" // will be blank unless specified by developer
def useMockApiForNativeAuthParameter = false // will be false unless specified by developer
def mockApiUrlParameter = "" // will be blank unless specified by developer
def disableAcquireTokenSilentTimeoutParameter = false // will be false unless specified by developer
def allowOneboxAuthorities = false // will be false unless specified by developer

if (project.hasProperty("slice")) {
sliceParameter = slice
Expand All @@ -175,6 +176,10 @@ if (project.hasProperty("disableAcquireTokenSilentTimeout")) {
disableAcquireTokenSilentTimeoutParameter = true
}

if (project.hasProperty("allowOneboxAuthorities")) {
allowOneboxAuthorities = true
}

sourceSets {
main {
java.srcDirs = ['src/main', "$project.buildDir/generated/source/buildConfig/main"]
Expand All @@ -183,6 +188,7 @@ sourceSets {
buildConfigField("boolean", "USE_MOCK_API_FOR_NATIVE_AUTH_AUTHORITY", "${useMockApiForNativeAuthParameter}")
buildConfigField("String", "MOCK_API_URL", "\"$mockApiUrlParameter\"")
buildConfigField("boolean", "DISABLE_ACQUIRE_TOKEN_SILENT_TIMEOUT", "${disableAcquireTokenSilentTimeoutParameter}")
buildConfigField("boolean", "ALLOW_ONEBOX_AUTHORITIES", "${allowOneboxAuthorities}")
}
test {
java.srcDirs = ['src/test']
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,13 @@
import com.microsoft.identity.common.java.logging.Logger;
import com.microsoft.identity.common.java.nativeauth.authorities.NativeAuthCIAMAuthority;
import com.microsoft.identity.common.java.providers.microsoft.azureactivedirectory.AzureActiveDirectory;
import com.microsoft.identity.common.java.providers.microsoft.azureactivedirectory.AzureActiveDirectoryEnvironment;
import com.microsoft.identity.common.java.providers.microsoft.azureactivedirectory.AzureActiveDirectorySlice;
import com.microsoft.identity.common.java.providers.oauth2.OAuth2Strategy;
import com.microsoft.identity.common.java.providers.oauth2.OAuth2StrategyParameters;
import com.microsoft.identity.common.java.util.CommonURIBuilder;
import com.microsoft.identity.common.java.util.StringUtil;

import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
Expand Down Expand Up @@ -107,8 +107,8 @@ public void setDefault(Boolean isDefault) {
}


@SuppressFBWarnings(value="RpC_REPEATED_CONDITIONAL_TEST",
justification="Somehow, spotbugs thinks that BuildConfig.SLICE and BuildConfig.DC are the same values.")
@SuppressFBWarnings(value = "RpC_REPEATED_CONDITIONAL_TEST",
justification = "Somehow, spotbugs thinks that BuildConfig.SLICE and BuildConfig.DC are the same values.")
public Authority() {
// setting slice directly here in constructor if slice provided as command line param
if (!StringUtil.isNullOrEmpty(BuildConfig.SLICE) || !StringUtil.isNullOrEmpty(BuildConfig.DC)) {
Expand All @@ -134,7 +134,7 @@ public static Authority getAuthorityFromAuthorityUrl(String authorityUrl) {
* determine the authority type and tenantid associated with it.
*
* @param authorityUrl
* @param clientId This parameter is optional and can be null. It is used to construct NativeAuthCIAMAuthority when authority type is AAD_NA.
* @param clientId This parameter is optional and can be null. It is used to construct NativeAuthCIAMAuthority when authority type is AAD_NA.
* @return
*/
public static Authority getAuthorityFromAuthorityUrl(String authorityUrl, @Nullable String clientId) {
Expand All @@ -150,7 +150,7 @@ public static Authority getAuthorityFromAuthorityUrl(String authorityUrl, @Nulla

// Adding check in case we have a trailing "/" at the end of the authority
if (pathSegments.size() == 0 || (pathSegments.size() == 1 && pathSegments.get(0).equals(""))) {
if (authorityUrl.contains(CIAMAuthority.CIAM_LOGIN_URL_SEGMENT)){
if (authorityUrl.contains(CIAMAuthority.CIAM_LOGIN_URL_SEGMENT)) {
// This is a CIAM authority, return CIAMAuthority
return new CIAMAuthority(CIAMAuthority.getTenantNameVariantUrlFromAuthorityWithoutPath(authorityUrl));
}
Expand Down Expand Up @@ -250,10 +250,17 @@ private static boolean authorityIsKnownFromConfiguration(@NonNull final String a
return null != getEquivalentConfiguredAuthority(authorityStr);
}

private static Authority createAadAuthority(@NonNull final CommonURIBuilder authorityCommonUriBuilder,
private static Authority createAadAuthority(@NonNull final CommonURIBuilder uriBuilder,
@NonNull final List<String> pathSegments) {
final String cloudUrl;
if (uriBuilder.getPort() != -1) {
cloudUrl = uriBuilder.getScheme() + "://" + uriBuilder.getHost() + ":" + uriBuilder.getPort();
} else {
cloudUrl = uriBuilder.getScheme() + "://" + uriBuilder.getHost();
}

AzureActiveDirectoryAudience audience = AzureActiveDirectoryAudience.getAzureActiveDirectoryAudience(
authorityCommonUriBuilder.getScheme() + "://" + authorityCommonUriBuilder.getHost(),
cloudUrl,
pathSegments.get(0)
);

Expand Down Expand Up @@ -344,6 +351,10 @@ public static boolean isKnownAuthority(Authority authority) {
return false;
}

if (BuildConfig.ALLOW_ONEBOX_AUTHORITIES && AzureActiveDirectoryEnvironment.ONEBOX_AUTHORITY.equals(authority.getAuthorityURL().getAuthority())) {
return true; // onebox authorities are always considered to be known.
}

//Check if authority was added to configuration
for (final Authority currentAuthority : knownAuthorities) {
if (currentAuthority.mAuthorityUrlString != null &&
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,13 @@ public Authority deserialize(JsonElement json, Type typeOfT, JsonDeserialization
if (aadAuthority != null && aadAuthority.mAuthorityUrlString != null) {
try {
final CommonURIBuilder uri = new CommonURIBuilder(URI.create(aadAuthority.mAuthorityUrlString));
final String cloudUrl = uri.getScheme() + "://" + uri.getHost();
final String cloudUrl;
if (uri.getPort() != -1) {
cloudUrl = uri.getScheme() + "://" + uri.getHost() + ":" + uri.getPort();
} else {
cloudUrl = uri.getScheme() + "://" + uri.getHost();
}

final String tenant = uri.getLastPathSegment();
if (!StringUtil.isNullOrEmpty(tenant)) {
aadAuthority.mAudience = AzureActiveDirectoryAudience.getAzureActiveDirectoryAudience(cloudUrl, tenant);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,5 +24,6 @@

public enum Environment {
PreProduction,
Production
Production,
OneBox // local ests setup
}
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,8 @@ public static synchronized void initializeCloudMetadata(@NonNull final String au
public static synchronized String getDefaultCloudUrl() {
if (sEnvironment == Environment.PreProduction) {
return AzureActiveDirectoryEnvironment.PREPRODUCTION_CLOUD_URL;
} else if (sEnvironment == Environment.OneBox) {
return AzureActiveDirectoryEnvironment.ONEBOX_CLOUD_URL;
} else {
return AzureActiveDirectoryEnvironment.PRODUCTION_CLOUD_URL;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,7 @@
public class AzureActiveDirectoryEnvironment {
public static final String PRODUCTION_CLOUD_URL = "https://login.microsoftonline.com"; //Prod
public static final String PREPRODUCTION_CLOUD_URL = "https://login.windows-ppe.net"; //PPE

public static final String ONEBOX_AUTHORITY = "zurich.test.dnsdemo1.test:8478";
public static final String ONEBOX_CLOUD_URL = "https://" + ONEBOX_AUTHORITY; // Local ESTS Deployment
}

0 comments on commit c69eb7d

Please sign in to comment.