diff --git a/changelog.txt b/changelog.txt index 6a1f88ac14..b1fe40fc1a 100644 --- a/changelog.txt +++ b/changelog.txt @@ -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) diff --git a/common4j/build.gradle b/common4j/build.gradle index 08dd9263d9..997eee0854 100644 --- a/common4j/build.gradle +++ b/common4j/build.gradle @@ -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 @@ -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"] @@ -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'] diff --git a/common4j/src/main/com/microsoft/identity/common/java/authorities/Authority.java b/common4j/src/main/com/microsoft/identity/common/java/authorities/Authority.java index ae39929290..4506cc7eed 100644 --- a/common4j/src/main/com/microsoft/identity/common/java/authorities/Authority.java +++ b/common4j/src/main/com/microsoft/identity/common/java/authorities/Authority.java @@ -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; @@ -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)) { @@ -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) { @@ -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)); } @@ -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 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) ); @@ -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 && diff --git a/common4j/src/main/com/microsoft/identity/common/java/authorities/AuthorityDeserializer.java b/common4j/src/main/com/microsoft/identity/common/java/authorities/AuthorityDeserializer.java index 02ca361d0c..7acfab2803 100644 --- a/common4j/src/main/com/microsoft/identity/common/java/authorities/AuthorityDeserializer.java +++ b/common4j/src/main/com/microsoft/identity/common/java/authorities/AuthorityDeserializer.java @@ -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); diff --git a/common4j/src/main/com/microsoft/identity/common/java/authorities/Environment.java b/common4j/src/main/com/microsoft/identity/common/java/authorities/Environment.java index 3fbba67ccf..13eb56a7a0 100644 --- a/common4j/src/main/com/microsoft/identity/common/java/authorities/Environment.java +++ b/common4j/src/main/com/microsoft/identity/common/java/authorities/Environment.java @@ -24,5 +24,6 @@ public enum Environment { PreProduction, - Production + Production, + OneBox // local ests setup } diff --git a/common4j/src/main/com/microsoft/identity/common/java/providers/microsoft/azureactivedirectory/AzureActiveDirectory.java b/common4j/src/main/com/microsoft/identity/common/java/providers/microsoft/azureactivedirectory/AzureActiveDirectory.java index 77c5a8d5b7..649d66b620 100644 --- a/common4j/src/main/com/microsoft/identity/common/java/providers/microsoft/azureactivedirectory/AzureActiveDirectory.java +++ b/common4j/src/main/com/microsoft/identity/common/java/providers/microsoft/azureactivedirectory/AzureActiveDirectory.java @@ -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; } diff --git a/common4j/src/main/com/microsoft/identity/common/java/providers/microsoft/azureactivedirectory/AzureActiveDirectoryEnvironment.java b/common4j/src/main/com/microsoft/identity/common/java/providers/microsoft/azureactivedirectory/AzureActiveDirectoryEnvironment.java index 0ade939a82..df19d5d511 100644 --- a/common4j/src/main/com/microsoft/identity/common/java/providers/microsoft/azureactivedirectory/AzureActiveDirectoryEnvironment.java +++ b/common4j/src/main/com/microsoft/identity/common/java/providers/microsoft/azureactivedirectory/AzureActiveDirectoryEnvironment.java @@ -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 }