Skip to content
This repository was archived by the owner on Nov 16, 2023. It is now read-only.

Commit b1aecf2

Browse files
authored
Merge pull request #20 from irvinesunday/master
Updates to Graph and MSAL libraries and Markdown content updates
2 parents 7112666 + 00c2564 commit b1aecf2

17 files changed

+219
-140
lines changed

README.md

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -29,18 +29,26 @@ To use the Connect sample for Android, you need the following:
2929
<a name="register"></a>
3030
## Register and configure the app
3131

32-
1. Sign into the [App Registration Portal](https://apps.dev.microsoft.com/) using either your personal or work or school account.
33-
2. Add a new **Converged application** by Selecting **Add an app**.
34-
> **Note:** The app registration portal also allows you to create **Azure AD Only** applications. The authentication library used in this sample is not compatible with Azure AD Only applications.
32+
1. Open a browser and navigate to the [Azure Active Directory admin center](https://aad.portal.azure.com). Login using a **Work or School Account**.
3533

36-
3. Enter a name for the app, and select **Create application**.
37-
38-
The registration page displays, listing the properties of your app.
39-
40-
4. Under **Platforms**, select **Add platform**.
41-
5. Select **Mobile application**.
42-
6. Copy the **Application Id**, you'll need it in the next section.
43-
7. Click **Save**.
34+
1. Select **Azure Active Directory** in the left-hand navigation, then select **App registrations (Preview)** under **Manage**.
35+
36+
![A screenshot of the App registrations ](./readme-images/aad-portal-app-registrations.png)
37+
38+
1. Select **New registration**. On the **Register an application** page, set the values as follows.
39+
40+
- Set a preferred **Name** e.g. `AndroidJavaConnect`
41+
- Set **Supported account types** to **Accounts in any organizational directory**.
42+
43+
![A screenshot of the Register an application page](./readme-images/aad-register-an-app.PNG)
44+
45+
1. Choose **Register**. On the **AndroidJavaConnect** app page, select **Overview** and copy the value of the **Application (client) ID** and save it, you will need it in the next step.
46+
47+
![A screenshot of Application Id](./readme-images/aad-application-id.PNG)
48+
49+
1. Still on the app page, select **Authentication**. Locate the section **Redirect URIs**. In the _Suggested Redirect URIs for public clients(mobile,desktop)_, check the second box so that the app can work with the MSAL libraries used in the application. (The box should contain the option _msal<YOUR_CLIENT_ID>://auth_). Choose **Save**.
50+
51+
![A screenshot of Suggested Redirect URIs for Public Client](./readme-images/aad-redirect-uri-public-client.PNG)
4452

4553
To learn about authenticating with MSAL for Android to make calls to Microsoft Graph, see [Call the Microsoft Graph API from an Android app](https://docs.microsoft.com/en-us/azure/active-directory/develop/guidedsetups/active-directory-android).
4654

@@ -91,4 +99,4 @@ This sample just shows the essentials that your apps need to work with Microsoft
9199
* [Snippets sample for Android](../../../android-java-snippets-sample)
92100

93101
## Copyright
94-
Copyright (c) 2016 Microsoft. All rights reserved.
102+
Copyright (c) 2019 Microsoft. All rights reserved.

app/build.gradle

Lines changed: 18 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
11
apply plugin: 'com.android.application'
22

33
android {
4-
compileSdkVersion 25
5-
buildToolsVersion "26.0.2"
4+
compileSdkVersion 27
65
defaultConfig {
76
applicationId "com.microsoft.graph.connect"
87
minSdkVersion 16
9-
targetSdkVersion 25
8+
targetSdkVersion 26
109
versionCode 2
1110
versionName "2.0"
1211
multiDexEnabled true
@@ -34,29 +33,27 @@ android {
3433
packagingOptions {
3534
exclude 'META-INF/maven/com.google.guava/guava/pom.properties'
3635
exclude 'META-INF/maven/com.google.guava/guava/pom.xml'
36+
exclude 'META-INF/jersey-module-version'
3737
}
3838
}
3939

4040
dependencies {
41-
compile fileTree(include: ['*.jar'], dir: 'libs')
42-
testCompile 'junit:junit:4.12'
43-
compile 'com.android.support:appcompat-v7:25.1.0'
44-
45-
compile ('com.microsoft.identity.client:msal:0.1.+') {
46-
exclude group: 'com.android.support', module: 'appcompat-v7'
47-
}
48-
compile 'com.android.volley:volley:1.0.0'
41+
implementation fileTree(include: ['*.jar'], dir: 'libs')
42+
testImplementation 'junit:junit:4.12'
43+
implementation 'com.android.support:appcompat-v7:27.0.0'
44+
implementation 'com.android.volley:volley:1.1.0'
4945
// Include the SDK as a dependency
50-
compile 'com.microsoft.graph:msgraph-sdk-android:1.3.2'
51-
46+
implementation 'com.microsoft.graph:microsoft-graph:1.2.0'
47+
implementation 'com.microsoft.graph:microsoft-graph-android-auth:0.1.0-SNAPSHOT'
5248
// Include GSON as a dependency
53-
compile 'com.google.code.gson:gson:2.6.2'
54-
compile 'commons-io:commons-io:2.0.1'
49+
implementation 'com.google.code.gson:gson:2.6.2'
50+
implementation 'commons-io:commons-io:2.0.1'
5551
// Test libraries
56-
androidTestCompile 'com.android.support:support-annotations:25.3.1'
57-
androidTestCompile 'com.android.support.test:runner:0.5'
58-
androidTestCompile 'com.android.support.test:rules:0.5'
59-
androidTestCompile 'com.android.support.test.espresso:espresso-core:2.2.2'
60-
androidTestCompile 'com.android.support.test.espresso:espresso-intents:2.2.2'
61-
androidTestCompile 'com.android.support.test.espresso:espresso-web:2.2.2'
52+
androidTestImplementation 'com.android.support:support-annotations:25.3.1'
53+
androidTestImplementation 'com.android.support.test:runner:0.5'
54+
androidTestImplementation 'com.android.support.test:rules:0.5'
55+
androidTestImplementation 'com.android.support.test.espresso:espresso-core:2.2.2'
56+
androidTestImplementation 'com.android.support.test.espresso:espresso-intents:2.2.2'
57+
androidTestImplementation 'com.android.support.test.espresso:espresso-web:2.2.2'
58+
6259
}

app/src/main/java/com/microsoft/graph/connect/AuthenticationManager.java

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,13 @@
1010
import android.content.Context;
1111
import android.util.Log;
1212

13+
import com.microsoft.graph.connect.util.IManifestReader;
14+
import com.microsoft.graph.connect.util.ManifestReader;
1315
import com.microsoft.identity.client.AuthenticationCallback;
1416
import com.microsoft.identity.client.AuthenticationResult;
15-
import com.microsoft.identity.client.MsalException;
17+
import com.microsoft.identity.client.IAccount;
18+
import com.microsoft.identity.client.exception.MsalException;
1619
import com.microsoft.identity.client.PublicClientApplication;
17-
import com.microsoft.identity.client.User;
1820

1921
import java.io.IOException;
2022

@@ -33,8 +35,12 @@ private AuthenticationManager() {
3335
public static synchronized AuthenticationManager getInstance() {
3436
if (INSTANCE == null) {
3537
INSTANCE = new AuthenticationManager();
38+
39+
IManifestReader metaDataReader = new ManifestReader();
40+
String clientID = metaDataReader.getApplicationMetadataValueString("com.microsoft.identity.client.ClientId");
41+
3642
if (mPublicClientApplication == null) {
37-
mPublicClientApplication = new PublicClientApplication(Connect.getInstance());
43+
mPublicClientApplication = new PublicClientApplication(Connect.getInstance(), clientID);
3844
}
3945
}
4046
return INSTANCE;
@@ -44,7 +50,6 @@ public static synchronized void resetInstance() {
4450
INSTANCE = null;
4551
}
4652

47-
4853
/**
4954
* Returns the access token obtained in authentication
5055
*
@@ -63,7 +68,7 @@ public PublicClientApplication getPublicClient(){
6368
* to null, and removing the user id from shred preferences.
6469
*/
6570
public void disconnect() {
66-
mPublicClientApplication.remove(mAuthResult.getUser());
71+
mPublicClientApplication.removeAccount(mAuthResult.getAccount());
6772
// Reset the AuthenticationManager object
6873
AuthenticationManager.resetInstance();
6974
}
@@ -79,9 +84,9 @@ public void callAcquireToken(Activity activity, final MSALAuthenticationCallback
7984
mPublicClientApplication.acquireToken(
8085
activity, Constants.SCOPES, getAuthInteractiveCallback());
8186
}
82-
public void callAcquireTokenSilent(User user, boolean forceRefresh, MSALAuthenticationCallback msalAuthenticationCallback) {
87+
public void callAcquireTokenSilent(IAccount account, boolean forceRefresh, MSALAuthenticationCallback msalAuthenticationCallback) {
8388
mActivityCallback = msalAuthenticationCallback;
84-
mPublicClientApplication.acquireTokenSilentAsync(Constants.SCOPES, user, null, forceRefresh, getAuthSilentCallback());
89+
mPublicClientApplication.acquireTokenSilentAsync(Constants.SCOPES, account, null, forceRefresh, getAuthSilentCallback());
8590
}
8691
//
8792
// App callbacks for MSAL

app/src/main/java/com/microsoft/graph/connect/ConnectActivity.java

Lines changed: 18 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,13 @@
1717

1818
import com.microsoft.identity.client.AuthenticationResult;
1919
import com.microsoft.identity.client.Logger;
20-
import com.microsoft.identity.client.MsalClientException;
21-
import com.microsoft.identity.client.MsalException;
22-
import com.microsoft.identity.client.MsalServiceException;
23-
import com.microsoft.identity.client.MsalUiRequiredException;
24-
import com.microsoft.identity.client.User;
20+
import com.microsoft.identity.client.exception.MsalException;
21+
import com.microsoft.identity.client.exception.MsalClientException;
22+
import com.microsoft.identity.client.exception.MsalServiceException;
23+
import com.microsoft.identity.client.exception.MsalUiRequiredException;
24+
import com.microsoft.identity.client.IAccount;
2525

2626
import java.util.List;
27-
import java.util.concurrent.ExecutionException;
2827

2928
/**
3029
* Starting Activity of the app. Handles the connection to Office 365.
@@ -33,12 +32,14 @@
3332
* If there are cached tokens, the app tries to reuse them.
3433
* The activity redirects the user to the SendMailActivity upon successful connection.
3534
*/
36-
public class ConnectActivity extends AppCompatActivity implements MSALAuthenticationCallback {
35+
public class ConnectActivity
36+
extends AppCompatActivity
37+
implements MSALAuthenticationCallback {
3738

3839
private static final String TAG = "ConnectActivity";
3940

4041
private boolean mEnablePiiLogging = false;
41-
private User mUser;
42+
private IAccount mAccount;
4243
private Handler mHandler;
4344

4445
private Button mConnectButton;
@@ -71,7 +72,6 @@ public void onClick(View v) {
7172
connect();
7273
}
7374
});
74-
7575
}
7676

7777
private void connect() {
@@ -89,16 +89,16 @@ private void connect() {
8989
/* Attempt to get a user and acquireTokenSilent
9090
* If this fails we do an interactive request
9191
*/
92-
List<User> users = null;
92+
List<IAccount> accounts = null;
9393

9494
try {
95-
users = mgr.getPublicClient().getUsers();
95+
accounts = mgr.getPublicClient().getAccounts();
9696

97-
if (users != null && users.size() == 1) {
97+
if (accounts != null && accounts.size() == 1) {
9898
/* We have 1 user */
99-
mUser = users.get(0);
99+
mAccount = accounts.get(0);
100100
mgr.callAcquireTokenSilent(
101-
mUser,
101+
mAccount,
102102
true,
103103
this);
104104
} else {
@@ -109,12 +109,7 @@ private void connect() {
109109
this,
110110
this);
111111
}
112-
} catch (MsalClientException e) {
113-
Log.d(TAG, "MSAL Exception Generated while getting users: " + e.toString());
114-
showConnectErrorUI(e.getMessage());
115-
116-
117-
} catch (IndexOutOfBoundsException e) {
112+
}catch (IndexOutOfBoundsException e) {
118113
Log.d(TAG, "User at this position does not exist: " + e.toString());
119114
showConnectErrorUI(e.getMessage());
120115

@@ -209,15 +204,15 @@ private Handler getHandler() {
209204

210205
@Override
211206
public void onSuccess(AuthenticationResult authenticationResult) {
212-
mUser = authenticationResult.getUser();
207+
mAccount = authenticationResult.getAccount();
213208

214209
String name = "";
215210
String preferredUsername = "";
216211

217212
try {
218213
// get the user info from the id token
219-
name = authenticationResult.getUser().getName();
220-
preferredUsername = authenticationResult.getUser().getDisplayableId();
214+
name = authenticationResult.getAccount().getUsername();
215+
preferredUsername = authenticationResult.getAccount().getUsername();
221216

222217
AuthenticationManager mgr = AuthenticationManager.getInstance();
223218

@@ -270,7 +265,6 @@ public void onError(MsalException exception) {
270265

271266
mgr.callAcquireToken(ConnectActivity.this, this);
272267
}
273-
274268
}
275269

276270
@Override
@@ -283,8 +277,5 @@ public void onError(Exception exception) {
283277
public void onCancel() {
284278
showMessage("User cancelled the flow.");
285279
showConnectErrorUI("User cancelled the flow.");
286-
287280
}
288-
289-
290281
}

app/src/main/java/com/microsoft/graph/connect/GraphServiceClientManager.java

Lines changed: 34 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,14 @@
66

77
import android.accounts.AuthenticatorException;
88
import android.accounts.OperationCanceledException;
9+
import android.app.Activity;
10+
import android.app.Application;
911
import android.util.Log;
1012

1113
import com.microsoft.graph.authentication.IAuthenticationProvider;
12-
import com.microsoft.graph.core.DefaultClientConfig;
13-
import com.microsoft.graph.core.IClientConfig;
14-
import com.microsoft.graph.extensions.GraphServiceClient;
15-
import com.microsoft.graph.extensions.IGraphServiceClient;
14+
import com.microsoft.graph.authentication.MSALAuthenticationProvider;
15+
import com.microsoft.graph.requests.extensions.GraphServiceClient;
16+
import com.microsoft.graph.models.extensions.IGraphServiceClient;
1617
import com.microsoft.graph.http.IHttpRequest;
1718

1819
import java.io.IOException;
@@ -21,11 +22,23 @@
2122
* Singleton class that manages a GraphServiceClient object.
2223
* It implements IAuthentication provider to authenticate requests using an access token.
2324
*/
24-
public class GraphServiceClientManager implements IAuthenticationProvider {
25+
public class GraphServiceClientManager extends Application implements IAuthenticationProvider {
2526
private IGraphServiceClient mGraphServiceClient;
2627
private static GraphServiceClientManager INSTANCE;
28+
private AuthenticationManager mAuthenticationManager;
29+
private static Activity connectActivity;
30+
private MSALAuthenticationProvider msalAuthenticationProvider;
31+
private IGraphServiceClient graphClient;
2732

28-
private GraphServiceClientManager() {}
33+
34+
public static GraphServiceClientManager getApp() {
35+
return INSTANCE;
36+
}
37+
public static Activity getAppActivity() {return connectActivity;}
38+
39+
private GraphServiceClientManager() {
40+
mAuthenticationManager = AuthenticationManager.getInstance();
41+
}
2942

3043
/**
3144
* Appends an access token obtained from the {@link AuthenticationManager} class to the
@@ -67,12 +80,22 @@ public synchronized IGraphServiceClient getGraphServiceClient() {
6780

6881
public synchronized IGraphServiceClient getGraphServiceClient(IAuthenticationProvider authenticationProvider) {
6982
if (mGraphServiceClient == null) {
70-
IClientConfig clientConfig = DefaultClientConfig.createWithAuthenticationProvider(
71-
authenticationProvider
72-
);
73-
mGraphServiceClient = new GraphServiceClient.Builder().fromConfig(clientConfig).buildClient();
83+
if(msalAuthenticationProvider == null){
84+
msalAuthenticationProvider = new MSALAuthenticationProvider(
85+
getAppActivity(),
86+
GraphServiceClientManager.getApp(),
87+
mAuthenticationManager.getPublicClient(),
88+
Constants.SCOPES);
89+
}
90+
if(graphClient == null){
91+
graphClient =
92+
GraphServiceClient
93+
.builder()
94+
.authenticationProvider(msalAuthenticationProvider)
95+
.buildClient();
96+
}
97+
return graphClient;
7498
}
75-
7699
return mGraphServiceClient;
77100
}
78101
}

0 commit comments

Comments
 (0)