Skip to content

Commit 9773a6b

Browse files
authored
Merge branch 'dev' into feature/handle-error-when-activity-not-found
2 parents 8b43097 + 2541bf6 commit 9773a6b

File tree

44 files changed

+391
-224
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+391
-224
lines changed

LabApiUtilities/src/main/com/microsoft/identity/labapi/utilities/authentication/LabApiAuthenticationClient.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,8 @@ public class LabApiAuthenticationClient implements IAccessTokenSupplier {
4747
private final static String AUTHORITY = "https://login.microsoftonline.com/" + TENANT_ID;
4848
private final static String KEYSTORE_TYPE = "Windows-MY";
4949
private final static String KEYSTORE_PROVIDER = "SunMSCAPI";
50-
private final int DEFAULT_ACCESS_TOKEN_RETRIES = 2;
51-
private final int ATTEMPT_RETRY_WAIT = 3;
50+
private final static int DEFAULT_ACCESS_TOKEN_RETRIES = 2;
51+
private final static int ATTEMPT_RETRY_WAIT = 3;
5252
private final String mLabCredential;
5353
private final String mLabCertPassword;
5454
private final String mScope;

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,4 +21,4 @@ For more information see the [Code of Conduct FAQ](https://opensource.microsoft.
2121
contact [[email protected]](mailto:[email protected]) with any additional questions or comments.
2222

2323
### Android Studio Build Requirement
24-
Please note that this project uses [Lombok](https://projectlombok.org/) internally and while using Android Studio you will need to install [Lobmok Plugin](https://plugins.jetbrains.com/plugin/6317-lombok) to get the project to build successfully within Android Studio.
24+
Please note that this project uses [Lombok](https://projectlombok.org/) internally and while using Android Studio you will need to install [Lombok Plugin](https://plugins.jetbrains.com/plugin/6317-lombok) to get the project to build successfully within Android Studio.

changelog.txt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,23 @@
11
vNext
22
----------
3+
- [MINOR] Add switch_browser toMicrosoftStsAuthorizationRequest (#2550)
4+
- [MAJOR] Add suberror for network errors (#2537)
35
- [PATCH] Translate MFA token error to UIRequiredException instead of ServiceException (#2538)
46
- [MINOR] Add Child Spans for Interactive Span (#2516)
57
- [MINOR] For MSAL CPP flows, match exact claims when deleting AT with intersecting scopes (#2548)
68
- [MINOR] Handle error gracefully when amazon app url scheme is not found (#2515)
9+
- [MINOR] Replace Deprecated Keystore API for Android 28+ (#2558)
710

811
Version 18.2.2
912
----------
1013
(common4j 15.2.2)
1114
- [PATCH] Debug errors in Keystore layer (#2544)
1215

16+
Version 18.2.1
17+
----------
18+
(common4j 15.2.1)
19+
- [PATCH] Translate MFA token error to UIRequiredException instead of ServiceException (#2538)
20+
1321
Version 18.2.0
1422
----------
1523
(common4j 15.2.0)

common/src/main/java/com/microsoft/identity/common/crypto/AndroidWrappedKeyLoader.java

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@
2626
import android.content.Context;
2727
import android.os.Build;
2828
import android.security.KeyPairGeneratorSpec;
29+
import android.security.keystore.KeyGenParameterSpec;
30+
import android.security.keystore.KeyProperties;
2931

3032
import androidx.annotation.RequiresApi;
3133

@@ -44,7 +46,9 @@
4446
import java.security.KeyStore;
4547
import java.security.spec.AlgorithmParameterSpec;
4648
import java.util.Calendar;
49+
import java.util.Date;
4750
import java.util.Locale;
51+
import java.util.concurrent.TimeUnit;
4852

4953
import javax.crypto.SecretKey;
5054
import javax.security.auth.x500.X500Principal;
@@ -269,12 +273,13 @@ public void deleteSecretKeyFromStorage() throws ClientException {
269273
/**
270274
* Generate a self-signed cert and derive an AlgorithmParameterSpec from that.
271275
* This is for the key to be generated in {@link KeyStore} via {@link KeyPairGenerator}
276+
* Note : This is now only for API level < 28
272277
*
273278
* @param context an Android {@link Context} object.
274279
* @return a {@link AlgorithmParameterSpec} for the keystore key (that we'll use to wrap the secret key).
275280
*/
276281
@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2)
277-
private static AlgorithmParameterSpec getSpecForKeyStoreKey(@NonNull final Context context,
282+
private static AlgorithmParameterSpec getLegacySpecForKeyStoreKey(@NonNull final Context context,
278283
@NonNull final String alias) {
279284
// Generate a self-signed cert.
280285
final String certInfo = String.format(Locale.ROOT, "CN=%s, OU=%s",
@@ -295,6 +300,34 @@ private static AlgorithmParameterSpec getSpecForKeyStoreKey(@NonNull final Conte
295300
.build();
296301
}
297302

303+
/**
304+
* Generate a self-signed cert and derive an AlgorithmParameterSpec from that.
305+
* This is for the key to be generated in {@link KeyStore} via {@link KeyPairGenerator}
306+
*
307+
* @param context an Android {@link Context} object.
308+
* @return a {@link AlgorithmParameterSpec} for the keystore key (that we'll use to wrap the secret key).
309+
*/
310+
private static AlgorithmParameterSpec getSpecForKeyStoreKey(@NonNull final Context context, @NonNull final String alias) {
311+
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.P) {
312+
return getLegacySpecForKeyStoreKey(context, alias);
313+
} else {
314+
final String certInfo = String.format(Locale.ROOT, "CN=%s, OU=%s",
315+
alias,
316+
context.getPackageName());
317+
final int certValidYears = 100;
318+
int purposes = KeyProperties.PURPOSE_WRAP_KEY | KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT;
319+
return new KeyGenParameterSpec.Builder(alias, purposes)
320+
.setCertificateSubject(new X500Principal(certInfo))
321+
.setCertificateSerialNumber(BigInteger.ONE)
322+
.setCertificateNotBefore(new Date())
323+
.setCertificateNotAfter(new Date(System.currentTimeMillis() + TimeUnit.DAYS.toMillis(365 * certValidYears)))
324+
.setKeySize(2048)
325+
.setDigests(KeyProperties.DIGEST_SHA256, KeyProperties.DIGEST_SHA512)
326+
.setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_RSA_PKCS1)
327+
.build();
328+
}
329+
}
330+
298331
/**
299332
* Get the file that stores the wrapped key.
300333
*/

common/src/main/java/com/microsoft/identity/common/internal/broker/BrokerResult.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@
3030
import com.microsoft.identity.common.java.exception.ErrorStrings;
3131

3232
import java.util.ArrayList;
33-
import java.util.Collections;
3433
import java.util.List;
3534

3635
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
@@ -647,7 +646,7 @@ public Builder correlationId(final String correlationId) {
647646
return this;
648647
}
649648

650-
public Builder oauthSubErrorCode(final String subErrorCode) {
649+
public Builder subErrorCode(final String subErrorCode) {
651650
this.mSubErrorCode = subErrorCode;
652651
return this;
653652
}

common/src/main/java/com/microsoft/identity/common/internal/migration/AdalMigrationAdapter.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
import com.google.gson.JsonObject;
3636
import com.google.gson.JsonSyntaxException;
3737
import com.microsoft.identity.common.adal.internal.AuthenticationConstants;
38+
import com.microsoft.identity.common.java.exception.ClientException;
3839
import com.microsoft.identity.common.java.exception.ServiceException;
3940
import com.microsoft.identity.common.adal.internal.cache.ADALTokenCacheItem;
4041
import com.microsoft.identity.common.java.providers.microsoft.MicrosoftAccount;
@@ -239,7 +240,7 @@ public static boolean loadCloudDiscoveryMetadata() {
239240
if (!AzureActiveDirectory.isInitialized()) {
240241
try {
241242
AzureActiveDirectory.performCloudDiscovery();
242-
} catch (final IOException | URISyntaxException e) {
243+
} catch (final ClientException e) {
243244
Logger.error(
244245
methodTag,
245246
"Failed to load instance discovery metadata",

common/src/main/java/com/microsoft/identity/common/internal/result/AdalBrokerResultAdapter.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -295,7 +295,7 @@ private void setServiceExceptionPropertiesToBundle(@NonNull final Bundle resultB
295295
// so adding values to these constants as well
296296
resultBundle.putString(AuthenticationConstants.OAuth2.ERROR, serviceException.getErrorCode());
297297
resultBundle.putString(AuthenticationConstants.OAuth2.ERROR_DESCRIPTION, serviceException.getMessage());
298-
resultBundle.putString(AuthenticationConstants.OAuth2.SUBERROR, serviceException.getOAuthSubErrorCode());
298+
resultBundle.putString(AuthenticationConstants.OAuth2.SUBERROR, serviceException.getSubErrorCode());
299299

300300
if (null != serviceException.getHttpResponseBody()) {
301301
resultBundle.putSerializable(

common/src/main/java/com/microsoft/identity/common/internal/result/MsalBrokerResultAdapter.java

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,6 @@
7676
import com.microsoft.identity.common.java.opentelemetry.OTelUtility;
7777
import com.microsoft.identity.common.java.opentelemetry.SpanExtension;
7878
import com.microsoft.identity.common.java.opentelemetry.SpanName;
79-
import com.microsoft.identity.common.java.providers.microsoft.azureactivedirectory.ClientInfo;
8079
import com.microsoft.identity.common.java.providers.microsoft.microsoftsts.MicrosoftStsAuthorizationResult;
8180
import com.microsoft.identity.common.java.providers.oauth2.AuthorizationResult;
8281
import com.microsoft.identity.common.java.request.SdkType;
@@ -308,6 +307,7 @@ public Bundle bundleFromBaseException(@NonNull final BaseException exception,
308307
final BrokerResult.Builder builder = new BrokerResult.Builder()
309308
.success(false)
310309
.errorCode(exception.getErrorCode())
310+
.subErrorCode(exception.getSubErrorCode())
311311
.errorMessage(exception.getMessage())
312312
.exceptionType(exception.getExceptionName())
313313
.correlationId(exception.getCorrelationId())
@@ -318,7 +318,7 @@ public Bundle bundleFromBaseException(@NonNull final BaseException exception,
318318

319319
if (exception instanceof ServiceException) {
320320
final ServiceException serviceException = (ServiceException) exception;
321-
builder.oauthSubErrorCode(serviceException.getOAuthSubErrorCode())
321+
builder.subErrorCode(serviceException.getSubErrorCode())
322322
.httpStatusCode(serviceException.getHttpStatusCode())
323323
.httpResponseBody(AuthenticationSchemeTypeAdapter.getGsonInstance().toJson(
324324
serviceException.getHttpResponseBody()));
@@ -522,6 +522,7 @@ private BaseException getBaseExceptionFromExceptionType(@NonNull final String ex
522522
);
523523
}
524524

525+
baseException.setSubErrorCode(brokerResult.getSubErrorCode());
525526
baseException.setCliTelemErrorCode(brokerResult.getCliTelemErrorCode());
526527
baseException.setCliTelemSubErrorCode(brokerResult.getCliTelemSubErrorCode());
527528
baseException.setCorrelationId(brokerResult.getCorrelationId());
@@ -595,6 +596,7 @@ private BaseException getBaseExceptionFromErrorCodes(@NonNull final BrokerResult
595596
);
596597
}
597598

599+
baseException.setSubErrorCode(brokerResult.getSubErrorCode());
598600
baseException.setCliTelemErrorCode(brokerResult.getCliTelemErrorCode());
599601
baseException.setCliTelemSubErrorCode(brokerResult.getCliTelemSubErrorCode());
600602
baseException.setCorrelationId(brokerResult.getCorrelationId());
@@ -620,7 +622,7 @@ private IntuneAppProtectionPolicyRequiredException getIntuneProtectionRequiredEx
620622
exception.setAuthorityUrl(brokerResult.getAuthority());
621623
exception.setAccountUserId(brokerResult.getLocalAccountId());
622624
exception.setAccountUpn(brokerResult.getUserName());
623-
exception.setOauthSubErrorCode(brokerResult.getSubErrorCode());
625+
exception.setSubErrorCode(brokerResult.getSubErrorCode());
624626
try {
625627
exception.setHttpResponseBody(HashMapExtensions.jsonStringAsMap(
626628
brokerResult.getHttpResponseBody())
@@ -649,8 +651,6 @@ private ServiceException getServiceException(@NonNull final BrokerResult brokerR
649651
null
650652
);
651653

652-
serviceException.setOauthSubErrorCode(brokerResult.getSubErrorCode());
653-
654654
try {
655655
serviceException.setHttpResponseBody(
656656
brokerResult.getHttpResponseBody() != null ?
@@ -686,7 +686,7 @@ private UiRequiredException getUiRequiredException(@NonNull final BrokerResult b
686686
);
687687
if (OAuth2ErrorCode.INTERACTION_REQUIRED.equalsIgnoreCase(errorCode) ||
688688
OAuth2ErrorCode.INVALID_GRANT.equalsIgnoreCase(errorCode)) {
689-
exception.setOauthSubErrorCode(brokerResult.getSubErrorCode());
689+
exception.setSubErrorCode(brokerResult.getSubErrorCode());
690690
}
691691
return exception;
692692
}

common/src/test/java/com/microsoft/identity/common/internal/authorities/AzureActiveDirectoryAuthorityTests.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@
4444
@RunWith(RobolectricTestRunner.class)
4545
public class AzureActiveDirectoryAuthorityTests {
4646
@Test
47-
public void isSameCloudAsAuthority_Returns_True_For_Authority_With_ValidAliases_For_SameCloud() throws IOException, URISyntaxException {
47+
public void isSameCloudAsAuthority_Returns_True_For_Authority_With_ValidAliases_For_SameCloud() throws ClientException {
4848
final String[] cloudAliasesWW = new String[]{"https://login.microsoftonline.com", "https://login.windows.net", "https://login.microsoft.com", "https://sts.windows.net"};
4949
final String[] cloudAliasesCN = new String[]{"https://login.chinacloudapi.cn", "https://login.partner.microsoftonline.cn"};
5050
final String[] cloudAliasesUSGov = new String[]{"https://login.microsoftonline.us", "https://login.usgovcloudapi.net"};
@@ -69,7 +69,7 @@ public void isSameCloudAsAuthority_Returns_True_For_Authority_With_ValidAliases_
6969
}
7070

7171
@Test
72-
public void isSameCloudAsAuthority_Returns_False_For_Authorities_From_Different_Clouds() throws IOException, URISyntaxException {
72+
public void isSameCloudAsAuthority_Returns_False_For_Authorities_From_Different_Clouds() throws ClientException {
7373
final AzureActiveDirectoryAuthority authorityWW = new AzureActiveDirectoryAuthority(new AllAccounts("https://login.microsoftonline.com"));
7474
final AzureActiveDirectoryAuthority authorityCN = new AzureActiveDirectoryAuthority(new AllAccounts("https://login.partner.microsoftonline.cn"));
7575
final AzureActiveDirectoryAuthority authorityUSGov = new AzureActiveDirectoryAuthority(new AllAccounts("https://login.microsoftonline.us"));

common4j/src/main/com/microsoft/identity/common/java/authorities/Authority.java

Lines changed: 3 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -303,7 +303,7 @@ public int hashCode() {
303303
private static final Object sLock = new Object();
304304

305305
private static void performCloudDiscovery()
306-
throws IOException, URISyntaxException {
306+
throws ClientException {
307307
final String methodName = ":performCloudDiscovery";
308308
Logger.verbose(
309309
TAG + methodName,
@@ -389,18 +389,8 @@ public static KnownAuthorityResult getKnownAuthorityResult(Authority authority)
389389

390390
try {
391391
performCloudDiscovery();
392-
} catch (final IOException ex) {
393-
clientException = new ClientException(
394-
ClientException.IO_ERROR,
395-
"Unable to perform cloud discovery",
396-
ex
397-
);
398-
} catch (final URISyntaxException ex) {
399-
clientException = new ClientException(
400-
ClientException.MALFORMED_URL,
401-
"Unable to construct cloud discovery URL",
402-
ex
403-
);
392+
} catch (final ClientException ex) {
393+
clientException = ex;
404394
}
405395

406396
Logger.info(TAG + methodName, "Cloud discovery complete.");

0 commit comments

Comments
 (0)