Skip to content

Commit c6d9599

Browse files
authored
Merge pull request #133 from AzureAD/dev
1.1.0 Release
2 parents 27da5b9 + 3a00e31 commit c6d9599

Some content is hidden

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

43 files changed

+1172
-834
lines changed

README.md

Lines changed: 27 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4,45 +4,59 @@
44
--------------------|-----------------|---------------
55
[![Build status](https://identitydivision.visualstudio.com/IDDP/_apis/build/status/CI/Java/MSAL%20Java%20CI%20Build?branchName=master)](https://identitydivision.visualstudio.com/IDDP/_build/latest?definitionId=762) | [![Build status](https://identitydivision.visualstudio.com/IDDP/_apis/build/status/CI/Java/MSAL%20Java%20CI%20Build?branchName=dev)](https://identitydivision.visualstudio.com/IDDP/_build/latest?definitionId=762)| [![Javadocs](http://javadoc.io/badge/com.microsoft.azure/msal4j.svg)](http://javadoc.io/doc/com.microsoft.azure/msal4j)
66

7-
|[Getting Started](https://github.com/AzureAD/microsoft-authentication-library-for-java/wiki)| [Docs](https://aka.ms/aaddev)| [Support](README.md#community-help-and-support)
8-
| --- | --- | --- |
7+
The Microsoft Authentication Library for Java (MSAL4J) enables applications to integrate with the [Microsoft identity platform](https://aka.ms/aaddevv2). It allows you to sign in users or apps with Microsoft identities (Azure AD, Microsoft accounts and Azure AD B2C accounts) and obtain tokens to call Microsoft APIs such as [Microsoft Graph](https://graph.microsoft.io/) or your own APIs registered with the Microsoft identity platform. It is built using industry standard OAuth2 and OpenID Connect protocols.
98

10-
The MSAL library for Java gives your app the ability to begin using the Microsoft Cloud by supporting Microsoft Azure Active Directory and Microsoft Accounts in a converged experience using industry standard OAuth2 and OpenID Connect.
9+
Quick links:
1110

11+
| [Getting Started](https://docs.microsoft.com/azure/active-directory/develop/quickstart-v2-java-webapp) | [Docs](https://github.com/AzureAD/microsoft-authentication-library-for-java/wiki) | [Samples](https://aka.ms/aaddevsamplesv2) | [Support](README.md#community-help-and-support)
12+
| --- | --- | --- | --- |
1213

13-
## Versions
14-
Current version - 1.0.0
14+
## Install
15+
Current version - 1.1.0
1516

1617
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).
1718

19+
You can get the msal4j package through Maven or Gradle.
20+
1821
### Maven
1922

2023
```
2124
<dependency>
2225
<groupId>com.microsoft.azure</groupId>
2326
<artifactId>msal4j</artifactId>
24-
<version>1.0.0</version>
27+
<version>1.1.0</version>
2528
</dependency>
2629
```
2730
### Gradle
2831

2932
```
30-
compile group: 'com.microsoft.azure', name: 'msal4j', version: '1.0.0'
33+
compile group: 'com.microsoft.azure', name: 'msal4j', version: '1.1.0'
3134
```
3235

36+
## Usage
37+
38+
MSAL4J supports multiple [application types and authentication scenarios](https://docs.microsoft.com/azure/active-directory/develop/authentication-flows-app-scenarios).
39+
40+
Refer the [Uncyclo](https://github.com/AzureAD/microsoft-authentication-library-for-java/wiki) pages for more details on the usage of MSAL Java and the supported scenarios.
41+
42+
## Migrating from ADAL
43+
If your application is using ADAL for Java (ADAL4J), we recommend you to update to use MSAL4J. No new feature work will be done in ADAL4J.
44+
45+
See the [ADAL to MSAL migration](https://github.com/AzureAD/microsoft-authentication-library-for-java/wiki/Migrate-to-MSAL-Java) guide.
46+
47+
## Roadmap
48+
49+
You can follow the latest updates and plans for MSAL Java in the [Roadmap](https://github.com/AzureAD/microsoft-authentication-library-for-java/wiki#roadmap) published on our Uncyclo.
50+
3351
## Contribution
3452

3553
This project welcomes contributions and suggestions. Most contributions require you to agree to a Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us the rights to use your contribution. For details, visit https://cla.microsoft.com.
3654
When you submit a pull request, a CLA-bot will automatically determine whether you need to provide a CLA and decorate the PR appropriately (e.g., label, comment). Simply follow the instructions provided by the bot. You will only need to do this once across all repos using our CLA.
3755
This project has adopted the Microsoft Open Source Code of Conduct. For more information see the Code of Conduct FAQ or contact [email protected] with any additional questions or comments.
3856

39-
## Build and Run
40-
41-
Refer [this page](https://github.com/AzureAD/microsoft-authentication-library-for-java/wiki/Maven)
42-
4357
## Samples and Documentation
4458

45-
We provide a [full suite of sample applications](https://github.com/Azure-Samples) and [documentation](https://aka.ms/aaddev) to help you get started with learning the Azure Identity system. This includes tutorials for native clients such as Windows, Windows Phone, iOS, macOS, Android, and Linux. We also provide full walkthroughs for authentication flows such as OAuth2, OpenID Connect, Graph API, and other awesome features.
59+
We provide a [full suite of sample applications](https://aka.ms/aaddevsamplesv2) and [documentation](https://aka.ms/aaddevv2) to help you get started with learning the Microsoft identity platform.
4660

4761
## Community Help and Support
4862

@@ -52,7 +66,7 @@ We recommend you use the "msal" tag so we can see it! Here is the latest Q&A on
5266

5367
## Security Reporting
5468

55-
If you find a security issue with our libraries or services please report it to [[email protected]](mailto:[email protected]) with as much detail as possible. Your submission may be eligible for a bounty through the [Microsoft Bounty](http://aka.ms/bugbounty) program. Please do not post security issues to GitHub Issues or any other public site. We will contact you shortly upon receiving the information. We encourage you to get notifications of when security incidents occur by visiting [this page](https://technet.microsoft.com/en-us/security/dd252948) and subscribing to Security Advisory Alerts.
69+
If you find a security issue with our libraries or services please report it to [[email protected]](mailto:[email protected]) with as much detail as possible. Your submission may be eligible for a bounty through the [Microsoft Bounty](http://aka.ms/bugbounty) program. Please do not post security issues to GitHub Issues or any other public site. We will contact you shortly upon receiving the information. We encourage you to get notifications of when security incidents occur by visiting [this page](https://technet.microsoft.com/security/dd252948) and subscribing to Security Advisory Alerts.
5670

5771
## We Value and Adhere to the Microsoft Open Source Code of Conduct
5872

changelog.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
Version 1.1.0
2+
=============
3+
- Added support for configuring HTTP client
4+
15
Version 1.0.0
26
=============
37
- API surface is now stable and production ready. No breaking changes will be introduced without incrementing MAJOR version

pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
<modelVersion>4.0.0</modelVersion>
44
<groupId>com.microsoft.azure</groupId>
55
<artifactId>msal4j</artifactId>
6-
<version>1.0.0</version>
6+
<version>1.1.0</version>
77
<packaging>jar</packaging>
88
<name>msal4j</name>
99
<description>
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
// Copyright (c) Microsoft Corporation. All rights reserved.
2+
// Licensed under the MIT License.
3+
4+
package com.microsoft.aad.msal4j;
5+
6+
import org.apache.http.Header;
7+
import org.apache.http.client.methods.CloseableHttpResponse;
8+
import org.apache.http.client.methods.HttpGet;
9+
import org.apache.http.client.methods.HttpPost;
10+
import org.apache.http.client.methods.HttpRequestBase;
11+
import org.apache.http.entity.ContentType;
12+
import org.apache.http.entity.StringEntity;
13+
import org.apache.http.impl.client.CloseableHttpClient;
14+
import org.apache.http.impl.client.HttpClients;
15+
import org.apache.http.util.EntityUtils;
16+
17+
import java.io.IOException;
18+
import java.util.Collections;
19+
import java.util.HashMap;
20+
import java.util.List;
21+
import java.util.Map;
22+
23+
class ApacheHttpClientAdapter implements IHttpClient {
24+
25+
private CloseableHttpClient httpClient;
26+
27+
ApacheHttpClientAdapter(){
28+
this.httpClient = HttpClients.createDefault();
29+
}
30+
31+
@Override
32+
public IHttpResponse send(HttpRequest httpRequest) throws Exception {
33+
34+
HttpRequestBase request = buildApacheRequestFromMsalRequest(httpRequest);
35+
CloseableHttpResponse response = httpClient.execute(request);
36+
37+
return buildMsalResponseFromApacheResponse(response);
38+
}
39+
40+
41+
private HttpRequestBase buildApacheRequestFromMsalRequest(HttpRequest httpRequest){
42+
43+
if(httpRequest.httpMethod() == HttpMethod.GET){
44+
return builGetRequest(httpRequest);
45+
} else if(httpRequest.httpMethod() == HttpMethod.POST){
46+
return buildPostRequest(httpRequest);
47+
} else {
48+
throw new IllegalArgumentException("HttpRequest method should be either GET or POST");
49+
}
50+
}
51+
52+
private HttpGet builGetRequest(HttpRequest httpRequest){
53+
HttpGet httpGet = new HttpGet(httpRequest.url().toString());
54+
55+
for(Map.Entry<String, String> entry: httpRequest.headers().entrySet()){
56+
httpGet.setHeader(entry.getKey(), entry.getValue());
57+
}
58+
59+
return httpGet;
60+
}
61+
62+
private HttpPost buildPostRequest(HttpRequest httpRequest){
63+
64+
HttpPost httpPost = new HttpPost(httpRequest.url().toString());
65+
for(Map.Entry<String, String> entry: httpRequest.headers().entrySet()){
66+
httpPost.setHeader(entry.getKey(), entry.getValue());
67+
}
68+
69+
String contentTypeHeaderValue = httpRequest.headerValue("Content-Type");
70+
ContentType contentType = ContentType.getByMimeType(contentTypeHeaderValue);
71+
StringEntity stringEntity = new StringEntity(httpRequest.body(), contentType);
72+
73+
httpPost.setEntity(stringEntity);
74+
return httpPost;
75+
}
76+
77+
private IHttpResponse buildMsalResponseFromApacheResponse(CloseableHttpResponse apacheResponse)
78+
throws IOException {
79+
80+
IHttpResponse httpResponse = new HttpResponse();
81+
((HttpResponse) httpResponse).statusCode(apacheResponse.getStatusLine().getStatusCode());
82+
83+
Map<String, List<String>> headers = new HashMap<>();
84+
for(Header header: apacheResponse.getAllHeaders()){
85+
headers.put(header.getName(), Collections.singletonList(header.getValue()));
86+
}
87+
((HttpResponse) httpResponse).headers(headers);
88+
89+
String responseBody = EntityUtils.toString(apacheResponse.getEntity(), "UTF-8");
90+
((HttpResponse) httpResponse).body(responseBody);
91+
return httpResponse;
92+
}
93+
}
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
// Copyright (c) Microsoft Corporation. All rights reserved.
2+
// Licensed under the MIT License.
3+
4+
package com.microsoft.aad.msal4j;
5+
6+
import labapi.LabResponse;
7+
import labapi.LabUserProvider;
8+
import labapi.NationalCloud;
9+
import org.testng.Assert;
10+
import org.testng.annotations.BeforeClass;
11+
import org.testng.annotations.Test;
12+
13+
import java.util.Collections;
14+
15+
public class HttpClientIT {
16+
private LabUserProvider labUserProvider;
17+
18+
@BeforeClass
19+
public void setUp() {
20+
labUserProvider = LabUserProvider.getInstance();
21+
}
22+
23+
@Test
24+
public void acquireToken_okHttpClient() throws Exception {
25+
26+
LabResponse labResponse = getManagedUserAccountWithPassword();
27+
assertAcquireTokenCommon(labResponse, new OkHttpClientAdapter());
28+
}
29+
30+
@Test
31+
public void acquireToken_apacheHttpClient() throws Exception {
32+
33+
LabResponse labResponse = getManagedUserAccountWithPassword();
34+
assertAcquireTokenCommon(labResponse, new ApacheHttpClientAdapter());
35+
}
36+
37+
private void assertAcquireTokenCommon(LabResponse labResponse, IHttpClient httpClient)
38+
throws Exception{
39+
PublicClientApplication pca = PublicClientApplication.builder(
40+
labResponse.getAppId()).
41+
authority(TestConstants.ORGANIZATIONS_AUTHORITY).
42+
httpClient(httpClient).
43+
build();
44+
45+
IAuthenticationResult result = pca.acquireToken(UserNamePasswordParameters.
46+
builder(Collections.singleton(TestConstants.GRAPH_DEFAULT_SCOPE),
47+
labResponse.getUser().getUpn(),
48+
labResponse.getUser().getPassword().toCharArray())
49+
.build())
50+
.get();
51+
52+
Assert.assertNotNull(result);
53+
Assert.assertNotNull(result.accessToken());
54+
Assert.assertNotNull(result.idToken());
55+
Assert.assertEquals(labResponse.getUser().getUpn(), result.account().username());
56+
}
57+
58+
private LabResponse getManagedUserAccountWithPassword(){
59+
LabResponse labResponse = labUserProvider.getDefaultUser(
60+
NationalCloud.AZURE_CLOUD,
61+
false);
62+
labUserProvider.getUserPassword(labResponse.getUser());
63+
64+
return labResponse;
65+
}
66+
}
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
// Copyright (c) Microsoft Corporation. All rights reserved.
2+
// Licensed under the MIT License.
3+
4+
package com.microsoft.aad.msal4j;
5+
6+
import okhttp3.Headers;
7+
import okhttp3.MediaType;
8+
import okhttp3.OkHttpClient;
9+
import okhttp3.Request;
10+
import okhttp3.RequestBody;
11+
import okhttp3.Response;
12+
import okhttp3.ResponseBody;
13+
14+
import java.io.IOException;
15+
16+
class OkHttpClientAdapter implements IHttpClient{
17+
18+
private OkHttpClient client;
19+
20+
OkHttpClientAdapter(){
21+
this.client = new OkHttpClient();
22+
}
23+
24+
@Override
25+
public IHttpResponse send(HttpRequest httpRequest) throws IOException {
26+
27+
Request request = buildOkRequestFromMsalRequest(httpRequest);
28+
29+
Response okHttpResponse= client.newCall(request).execute();
30+
return buildMsalResponseFromOkResponse(okHttpResponse);
31+
}
32+
33+
private Request buildOkRequestFromMsalRequest(HttpRequest httpRequest){
34+
35+
if(httpRequest.httpMethod() == HttpMethod.GET){
36+
return buildGetRequest(httpRequest);
37+
} else if(httpRequest.httpMethod() == HttpMethod.POST){
38+
return buildPostRequest(httpRequest);
39+
} else {
40+
throw new IllegalArgumentException("HttpRequest method should be either GET or POST");
41+
}
42+
}
43+
44+
private Request buildGetRequest(HttpRequest httpRequest){
45+
Headers headers = Headers.of(httpRequest.headers());
46+
47+
return new Request.Builder()
48+
.url(httpRequest.url())
49+
.headers(headers)
50+
.build();
51+
}
52+
53+
private Request buildPostRequest(HttpRequest httpRequest){
54+
Headers headers = Headers.of(httpRequest.headers());
55+
String contentType = httpRequest.headerValue("Content-Type");
56+
MediaType type = MediaType.parse(contentType);
57+
58+
RequestBody requestBody = RequestBody.create(type, httpRequest.body());
59+
60+
return new Request.Builder()
61+
.url(httpRequest.url())
62+
.post(requestBody)
63+
.headers(headers)
64+
.build();
65+
}
66+
67+
private IHttpResponse buildMsalResponseFromOkResponse(Response okHttpResponse) throws IOException{
68+
69+
IHttpResponse httpResponse = new HttpResponse();
70+
((HttpResponse) httpResponse).statusCode(okHttpResponse.code());
71+
72+
ResponseBody body = okHttpResponse.body();
73+
if(body != null){
74+
((HttpResponse) httpResponse).body(body.string());
75+
}
76+
77+
Headers headers = okHttpResponse.headers();
78+
if(headers != null){
79+
((HttpResponse) httpResponse).headers(headers.toMultimap());
80+
}
81+
return httpResponse;
82+
}
83+
}

src/integrationtest/java/com.microsoft.aad.msal4j/UsernamePasswordIT.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ public void acquireTokenWithUsernamePassword_ADFSv2() throws Exception{
7373
assertAcquireTokenCommon(labResponse, password);
7474
}
7575

76-
public void assertAcquireTokenCommon(LabResponse labResponse, String password)
76+
private void assertAcquireTokenCommon(LabResponse labResponse, String password)
7777
throws Exception{
7878
PublicClientApplication pca = PublicClientApplication.builder(
7979
labResponse.getAppId()).

src/integrationtest/java/labapi/KeyVaultSecretsProvider.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ private IClientCredential getClientCredentialFromKeyStore() {
7575
key = (PrivateKey) keystore.getKey(CERTIFICATE_ALIAS, null);
7676
publicCertificate = (X509Certificate) keystore.getCertificate(
7777
CERTIFICATE_ALIAS);
78+
7879
} catch (Exception e){
7980
throw new RuntimeException("Error getting certificate from keystore: " + e.getMessage());
8081
}

src/main/java/com/microsoft/aad/msal4j/AadInstanceDiscovery.java

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -62,18 +62,21 @@ private static String getInstanceDiscoveryEndpoint(String host) {
6262

6363
private static InstanceDiscoveryResponse sendInstanceDiscoveryRequest
6464
(URL authorityUrl, MsalRequest msalRequest,
65-
ServiceBundle serviceBundle) throws Exception {
65+
ServiceBundle serviceBundle) {
6666

6767
String instanceDiscoveryRequestUrl = getInstanceDiscoveryEndpoint(authorityUrl.getAuthority()) +
6868
INSTANCE_DISCOVERY_REQUEST_PARAMETERS_TEMPLATE.replace("{authorizeEndpoint}",
6969
getAuthorizeEndpoint(authorityUrl.getAuthority(),
7070
Authority.getTenant(authorityUrl, Authority.detectAuthorityType(authorityUrl))));
7171

72-
String json = HttpHelper.executeHttpRequest
73-
(log, HttpMethod.GET, instanceDiscoveryRequestUrl, msalRequest.headers().getReadonlyHeaderMap(),
74-
null, msalRequest.requestContext(), serviceBundle);
72+
HttpRequest httpRequest = new HttpRequest(
73+
HttpMethod.GET,
74+
instanceDiscoveryRequestUrl,
75+
msalRequest.headers().getReadonlyHeaderMap());
7576

76-
return JsonHelper.convertJsonToObject(json, InstanceDiscoveryResponse.class);
77+
IHttpResponse httpResponse= HttpHelper.executeHttpRequest(httpRequest, msalRequest.requestContext(), serviceBundle);
78+
79+
return JsonHelper.convertJsonToObject(httpResponse.body(), InstanceDiscoveryResponse.class);
7780
}
7881

7982
private static void validate(InstanceDiscoveryResponse instanceDiscoveryResponse) {

0 commit comments

Comments
 (0)