Skip to content

Commit

Permalink
1.10.1 Release (#406)
Browse files Browse the repository at this point in the history
* Pesomka/b2b stage1 (#356)

multi cloud accounts

* Pesomka/key store provider (#358)

general purpose API should not be tied to specific security provider

* Instance aware support (#362)

 Instance aware support for interactive requests

* Update telemetry to reduce size of payload (#361)

* Update telemetry implementation

* Bump guava from 26.0-jre to 29.0-jre (#366)

Bumps [guava](https://github.com/google/guava) from 26.0-jre to 29.0-jre.

* Bump guava from 26.0-jre to 29.0-jre in /src/samples/msal-obo-sample (#367)

Bumps [guava](https://github.com/google/guava) from 26.0-jre to 29.0-jre.

* survey added to README.md

Loyalty developer survey added to README.md
Link placed in tab and new feedback section.

* Update oauth2-oidc-sdk dependency (#373)

Upgrade oauth2-oidc-sdk dependency

* Add default cache lookup to client credential flow (#368)

* Add default cache lookup to client credential flow

* Bump commons-io from 2.6 to 2.7 (#376)

Bumps commons-io from 2.6 to 2.7.

* Sagonzal/update client credentials (#377)

* Update obo flow to attempt cache lookup by default

* 1.10.0 release

* fix for issue with common scopes override (#385)

fix for issue with common scopes override

* Add ccs routing headers. Add option to pass in header map

* Rename IApiParameters to IAcquireTokenParameters

* PR Feedback

* Add CCS routing information to /authorize query parameters

* Update log levels for operations in OBO and ClientCredential supliers

* Update how non 200 http response are handled. Update to only throw MsalExceptions

* Update unit tests

* Retrigger build

* Update unit test

* Bump httpclient from 4.5.9 to 4.5.13 (#401)

Bumps httpclient from 4.5.9 to 4.5.13.

---
updated-dependencies:
- dependency-name: org.apache.httpcomponents:httpclient
  dependency-type: direct:development
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* Improve region support and add region telemetry (#388)

* Improve region support and add region telemetry

* Finish implementation of most recent telemetry design

* Update oauth dependency

* Address code review comments

* integration test for cross cloud b2b (#396)

integration test for cross cloud b2b

* Version and changelog updates for release 1.10.1 (#405)

* Fix merge conflicts

Co-authored-by: SomkaPe <pesomka@microsoft.com>
Co-authored-by: Santiago Gonzalez <35743865+sangonzal@users.noreply.github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: ShannonCanTech <shfost@microsoft.com>
Co-authored-by: Santiago Gonzalez <sagonzal@microsoft.com>
  • Loading branch information
6 people authored Jun 16, 2021
1 parent e1d96e7 commit 050d188
Show file tree
Hide file tree
Showing 63 changed files with 1,076 additions and 322 deletions.
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ Quick links:
The library supports the following Java environments:
- Java 8 (or higher)

Current version - 1.10.0
Current version - 1.10.1

You can find the changes for each version in the [change log](https://github.com/AzureAD/microsoft-authentication-library-for-java/blob/master/changelog.txt).

Expand All @@ -28,13 +28,13 @@ Find [the latest package in the Maven repository](https://mvnrepository.com/arti
<dependency>
<groupId>com.microsoft.azure</groupId>
<artifactId>msal4j</artifactId>
<version>1.10.0</version>
<version>1.10.1</version>
</dependency>
```
### Gradle

```
compile group: 'com.microsoft.azure', name: 'msal4j', version: '1.10.0'
compile group: 'com.microsoft.azure', name: 'msal4j', version: '1.10.1'
```

## Usage
Expand Down
10 changes: 10 additions & 0 deletions changelog.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,13 @@
Version 1.10.1
=============
- Improved behavior when using regional authorities
- Fix scope override issue in OBO flow
- Update server-side telemetry
- Adjusted logging levels to reduce noise
- Improved HTTP error handling and messaging
- Upgrade oauth2-oidc-sdk dependency 9.4 -> 9.7
- Upgrade httpclient dependency 4.5.9 -> 4.5.13

Version 1.10.0
=============
- Instance aware support for interactive requests
Expand Down
6 changes: 3 additions & 3 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>com.microsoft.azure</groupId>
<artifactId>msal4j</artifactId>
<version>1.10.0</version>
<version>1.10.1</version>
<packaging>jar</packaging>
<name>msal4j</name>
<description>
Expand Down Expand Up @@ -36,7 +36,7 @@
<dependency>
<groupId>com.nimbusds</groupId>
<artifactId>oauth2-oidc-sdk</artifactId>
<version>9.4</version>
<version>9.7</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
Expand Down Expand Up @@ -95,7 +95,7 @@
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.9</version>
<version>4.5.13</version>
<scope>test</scope>
</dependency>
<dependency>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
import java.net.URI;
import java.net.URL;
import java.util.Collections;
import java.util.concurrent.ExecutionException;

public class AcquireTokenInteractiveIT extends SeleniumTest {
private final static Logger LOG = LoggerFactory.getLogger(AuthorizationCodeIT.class);
Expand Down Expand Up @@ -168,6 +169,52 @@ private void assertAcquireTokenInstanceAware(User user) {
Assert.assertEquals(result.account().environment(), pca.getAccounts().join().iterator().next().environment());
}

@Test
public void acquireTokensInHomeAndGuestClouds_ArlingtonAccount() throws MalformedURLException, ExecutionException, InterruptedException {
acquireTokensInHomeAndGuestClouds(AzureEnvironment.AZURE_US_GOVERNMENT, TestConstants.AUTHORITY_ARLINGTON);
}

@Test
public void acquireTokensInHomeAndGuestClouds_MooncakeAccount() throws MalformedURLException, ExecutionException, InterruptedException {
acquireTokensInHomeAndGuestClouds(AzureEnvironment.AZURE_CHINA, TestConstants.AUTHORITY_MOONCAKE);
}

public void acquireTokensInHomeAndGuestClouds(String homeCloud, String homeCloudAuthority) throws MalformedURLException, ExecutionException, InterruptedException {

User user = labUserProvider.getUserByGuestHomeAzureEnvironments
(AzureEnvironment.AZURE, homeCloud);

// use user`s upn from home cloud
user.setUpn(user.getHomeUPN());

ITokenCacheAccessAspect persistenceAspect = new ITokenCacheAccessAspect() {
String data;
@Override
public void beforeCacheAccess(ITokenCacheAccessContext iTokenCacheAccessContext) {
iTokenCacheAccessContext.tokenCache().deserialize(data);
}
@Override
public void afterCacheAccess(ITokenCacheAccessContext iTokenCacheAccessContext) {
data = iTokenCacheAccessContext.tokenCache().serialize();
}
};

PublicClientApplication publicCloudPca = PublicClientApplication.builder(
user.getAppId()).
authority(TestConstants.AUTHORITY_PUBLIC_TENANT_SPECIFIC).setTokenCacheAccessAspect(persistenceAspect).
build();

IAuthenticationResult result = acquireTokenInteractive(user, publicCloudPca, TestConstants.USER_READ_SCOPE);
Assert.assertNotNull(result);
Assert.assertNotNull(result.accessToken());
Assert.assertNotNull(result.idToken());
Assert.assertEquals(user.getHomeUPN(), result.account().username());

publicCloudPca.removeAccount(publicCloudPca.getAccounts().join().iterator().next()).join();

Assert.assertEquals(publicCloudPca.getAccounts().join().size(), 0);
}

private IAuthenticationResult acquireTokenInteractive(
User user,
PublicClientApplication pca,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,7 @@
import org.testng.Assert;
import org.testng.annotations.Test;

import java.util.Collections;
import java.util.Map;
import java.util.*;
import java.util.concurrent.ExecutionException;

public class OAuthRequestValidationUnitT extends OAuthRequestValidationTest {
Expand Down Expand Up @@ -41,8 +40,16 @@ public void oAuthRequest_for_acquireTokenByClientCertificate() throws Exception
// validate Client Authentication query params
Assert.assertFalse(StringUtils.isEmpty(queryParams.get("client_assertion")));

// to do validate scopes
Assert.assertEquals(SCOPES, queryParams.get("scope"));
Set<String> scopes = new HashSet<>(
Arrays.asList(queryParams.get("scope").split(AbstractMsalAuthorizationGrant.SCOPES_DELIMITER)));

// validate custom scopes
Assert.assertTrue(scopes.contains(SCOPES));

// validate common scopes
Assert.assertTrue(scopes.contains(AbstractMsalAuthorizationGrant.SCOPE_OPEN_ID));
Assert.assertTrue(scopes.contains(AbstractMsalAuthorizationGrant.SCOPE_PROFILE));
Assert.assertTrue(scopes.contains(AbstractMsalAuthorizationGrant.SCOPE_OFFLINE_ACCESS));

Assert.assertEquals(CLIENT_ASSERTION_TYPE_JWT, queryParams.get("client_assertion_type"));
Assert.assertEquals(ON_BEHALF_OF_USE_JWT, queryParams.get("requested_token_use"));
Expand Down Expand Up @@ -86,7 +93,7 @@ public void oAuthRequest_for_acquireTokenByClientAssertion() throws Exception {
Assert.assertEquals(CLIENT_ASSERTION_TYPE_JWT, queryParams.get("client_assertion_type"));

// to do validate scopes
Assert.assertEquals("openid profile offline_access https://SomeResource.azure.net", queryParams.get("scope"));
Assert.assertEquals("https://SomeResource.azure.net openid profile offline_access", queryParams.get("scope"));

Assert.assertEquals(CLIENT_INFO_VALUE, queryParams.get("client_info"));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,4 +50,9 @@ public class TestConstants {
public final static String CLAIMS = "{\"id_token\":{\"auth_time\":{\"essential\":true}}}";
public final static Set<String> CLIENT_CAPABILITIES_EMPTY = new HashSet<String>(Collections.emptySet());
public final static Set<String> CLIENT_CAPABILITIES_LLT = new HashSet<String>(Collections.singletonList("llt"));

// cross cloud b2b settings
public final static String AUTHORITY_ARLINGTON = "https://login.microsoftonline.us/arlmsidlab1.onmicrosoft.us";
public final static String AUTHORITY_MOONCAKE = "https://login.chinacloudapi.cn/mncmsidlab1.partner.onmschina.cn";
public final static String AUTHORITY_PUBLIC_TENANT_SPECIFIC = "https://login.microsoftonline.com/msidlab4.onmicrosoft.com";
}
Original file line number Diff line number Diff line change
Expand Up @@ -47,4 +47,11 @@ public class SeleniumConstants {
final static String B2C_LOCAL_USERNAME_ID = "cred_userid_inputtext";
final static String B2C_LOCAL_PASSWORD_ID = "cred_password_inputtext";
final static String B2C_LOCAL_SIGN_IN_BUTTON_ID = "cred_sign_in_button";

// Stay signed in?
final static String STAY_SIGN_IN_NO_BUTTON_ID = "idBtn_Back";

// Are you trying to sign in to ...
//Only continue if you downloaded the app from a store or website that you trust.
final static String ARE_YOU_TRYING_TO_SIGN_IN_TO = "idSIButton9";
}
53 changes: 48 additions & 5 deletions src/integrationtest/java/infrastructure/SeleniumExtensions.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@

package infrastructure;

import com.microsoft.aad.msal4j.TestConstants;
import labapi.FederationProvider;
import labapi.LabConstants;
import labapi.User;
Expand All @@ -12,10 +11,12 @@
import org.openqa.selenium.OutputType;
import org.openqa.selenium.StaleElementReferenceException;
import org.openqa.selenium.TakesScreenshot;
import org.openqa.selenium.TimeoutException;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.support.ui.ExpectedCondition;
import org.openqa.selenium.support.ui.WebDriverWait;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
Expand All @@ -41,8 +42,8 @@ public static WebDriver createDefaultWebDriver(){
return driver;
}

public static WebElement waitForElementToBeVisibleAndEnable(WebDriver driver, By by){
WebDriverWait webDriverWait = new WebDriverWait(driver, 15);
public static WebElement waitForElementToBeVisibleAndEnable(WebDriver driver, By by, int timeOutInSeconds) {
WebDriverWait webDriverWait = new WebDriverWait(driver, timeOutInSeconds);
return webDriverWait.until((dr) ->
{
try {
Expand All @@ -52,11 +53,17 @@ public static WebElement waitForElementToBeVisibleAndEnable(WebDriver driver, By
}
return null;
} catch (StaleElementReferenceException e) {
return null;
return null;
}
});
}

public static WebElement waitForElementToBeVisibleAndEnable(WebDriver driver, By by){
int DEFAULT_TIMEOUT_IN_SEC = 15;

return waitForElementToBeVisibleAndEnable(driver, by, DEFAULT_TIMEOUT_IN_SEC);
}

public static void performADLogin(WebDriver driver, User user){
LOG.info("PerformADLogin");

Expand All @@ -81,8 +88,44 @@ public static void performADLogin(WebDriver driver, User user){
waitForElementToBeVisibleAndEnable(driver, by).sendKeys(user.getPassword());

LOG.info("Loggin in ... click submit");
waitForElementToBeVisibleAndEnable(driver, new By.ById(fields.getPasswordSigInButtonId())).
waitForElementToBeVisibleAndEnable(driver, new By.ById(fields.getPasswordSigInButtonId())).
click();

try {
checkAuthenticationCompletePage(driver);
return;
} catch (TimeoutException ex) {
}

LOG.info("Checking optional questions");

try {
LOG.info("Are you trying to sign in to ... ? checking");
waitForElementToBeVisibleAndEnable(driver, new By.ById(SeleniumConstants.ARE_YOU_TRYING_TO_SIGN_IN_TO), 3).
click();
LOG.info("Are you trying to sign in to ... ? click Continue");

} catch (TimeoutException ex) {
}

try {
LOG.info("Stay signed in? checking");
waitForElementToBeVisibleAndEnable(driver, new By.ById(SeleniumConstants.STAY_SIGN_IN_NO_BUTTON_ID), 3).
click();
LOG.info("Stay signed in? click NO");
} catch (TimeoutException ex) {
}
}

private static void checkAuthenticationCompletePage(WebDriver driver) {
(new WebDriverWait(driver, 5)).until((ExpectedCondition<Boolean>) d -> {
boolean condition = false;
WebElement we = d.findElement(new By.ByTagName("body"));
if (we != null && we.getText().contains("Authentication complete")) {
condition = true;
}
return condition;
});
}

public static void performADFS2019Login(WebDriver driver, User user){
Expand Down
2 changes: 2 additions & 0 deletions src/integrationtest/java/labapi/LabConstants.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,6 @@ public class LabConstants {
public final static String MSA_APP_ID = "9668f2bd-6103-4292-9024-84fa2d1b6fb2";

public final static String ARLINGTON_LAB_NAME = "ARLMSIDLAB1";
public final static String GUEST_USER_TYPE = "Guest";

}
8 changes: 7 additions & 1 deletion src/integrationtest/java/labapi/LabService.java
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,13 @@ User getUser(UserQueryParameters query){

User[] users = convertJsonToObject(result, User[].class);
User user = users[0];
user.setPassword(getSecret(user.getLabName()));
if(user.getUserType().equals("Guest")){
String secretId = user.getHomeDomain().split("\\.")[0];
user.setPassword(getSecret(secretId));
}
else {
user.setPassword(getSecret(user.getLabName()));
}
if (query.parameters.containsKey(UserQueryParameters.FEDERATION_PROVIDER)) {
user.setFederationProvider(query.parameters.get(UserQueryParameters.FEDERATION_PROVIDER));
} else {
Expand Down
12 changes: 12 additions & 0 deletions src/integrationtest/java/labapi/LabUserProvider.java
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,18 @@ public User getUserByAzureEnvironment(String azureEnvironment) {
return getLabUser(query);
}

public User getUserByGuestHomeAzureEnvironments(String guestEnvironment, String homeEnvironment) {

UserQueryParameters query = new UserQueryParameters();
query.parameters.put(UserQueryParameters.USER_TYPE, "guest");
query.parameters.put(UserQueryParameters.AZURE_ENVIRONMENT, guestEnvironment);
query.parameters.put(UserQueryParameters.HOME_AZURE_ENVIRONMENT, homeEnvironment);
query.parameters.put(UserQueryParameters.GUEST_HOME_DIN, "hostazuread");
query.parameters.put(UserQueryParameters.SIGN_IN_AUDIENCE, "azureadmyorg");

return getLabUser(query);
}

public User getLabUser(UserQueryParameters userQuery){
if(userCache.containsKey(userQuery)){
return userCache.get(userQuery);
Expand Down
1 change: 1 addition & 0 deletions src/integrationtest/java/labapi/User.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ public class User
private String licenses;

@JsonProperty("upn")
@Setter
private String upn;

@JsonProperty("mfa")
Expand Down
4 changes: 3 additions & 1 deletion src/integrationtest/java/labapi/UserQueryParameters.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@ public class UserQueryParameters {
public static final String B2C_PROVIDER = "b2cprovider";
public static final String FEDERATION_PROVIDER = "federationprovider";
public static final String AZURE_ENVIRONMENT = "azureenvironment";
public static final String SIGN_IN_AUDIENCE = "signinaudience";
public static final String HOME_AZURE_ENVIRONMENT = "guesthomeazureenvironment";
public static final String GUEST_HOME_DIN = "guesthomedin";
public static final String SIGN_IN_AUDIENCE = "signInAudience";

public Map<String, String> parameters = new HashMap<>();
}
Loading

0 comments on commit 050d188

Please sign in to comment.