Skip to content

Commit 3660aab

Browse files
authored
Merge pull request #215173 from derisen/update-node-desktop-articles
update msal node electron articles
2 parents 9ad7006 + 7458c5e commit 3660aab

File tree

3 files changed

+39
-116
lines changed

3 files changed

+39
-116
lines changed

articles/active-directory/develop/includes/desktop-app/quickstart-nodejs-electron.md

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ To register your application and add the app's registration information to your
3838
1. Select **Register** to create the application.
3939
1. Under **Manage**, select **Authentication**.
4040
1. Select **Add a platform** > **Mobile and desktop applications**.
41-
1. In the **Redirect URIs** section, enter the redirect URI suggested by the app registration portal, e.g. `msalfa29b4c9-7675-4b61-8a0a-bf7b2b4fda91://auth`.
41+
1. In the **Redirect URIs** section, enter `http://localhost`.
4242
1. Select **Configure**.
4343

4444
#### Step 2: Download the Electron sample project
@@ -62,7 +62,7 @@ Your file should look similar to below:
6262

6363
```javascript
6464
const AAD_ENDPOINT_HOST = "https://login.microsoftonline.com/"; // include the trailing slash
65-
const REDIRECT_URI = "msalfa29b4c9-7675-4b61-8a0a-bf7b2b4fda91://auth";
65+
6666
const msalConfig = {
6767
auth: {
6868
clientId: "fa29b4c9-7675-4b61-8a0a-bf7b2b4fda91",
@@ -80,14 +80,11 @@ Your file should look similar to below:
8080
}
8181

8282
const GRAPH_ENDPOINT_HOST = "https://graph.microsoft.com/"; // include the trailing slash
83+
8384
const protectedResources = {
8485
graphMe: {
8586
endpoint: `${GRAPH_ENDPOINT_HOST}v1.0/me`,
8687
scopes: ["User.Read"],
87-
},
88-
graphMessages: {
89-
endpoint: `${GRAPH_ENDPOINT_HOST}v1.0/me/messages`,
90-
scopes: ["Mail.Read"],
9188
}
9289
};
9390

@@ -121,7 +118,7 @@ Your file should look similar to below:
121118

122119
### How the sample works
123120

124-
When a user selects the **Sign In** button for the first time, get `getTokenInteractive` method of *AuthProvider.js* is called. This method redirects the user to sign-in with the *Microsoft identity platform endpoint* and validate the user's credentials, and then obtains an **authorization code**. This code is then exchanged for an access token using the `acquireTokenByCode` method of MSAL Node.
121+
When a user selects the **Sign In** button for the first time, `acquireTokenInteractive` method of MSAL Node is called. This method redirects the user to sign-in with the *Microsoft identity platform endpoint*, obtains an **authorization code**, and then exchanges it for an access token.
125122

126123
### MSAL Node
127124

articles/active-directory/develop/quickstart-v2-nodejs-desktop.md

Lines changed: 19 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -108,94 +108,29 @@ ms.custom: mode-api
108108
>
109109
> ### Requesting tokens
110110
>
111-
> In the first leg of authorization code flow with PKCE, prepare and send an authorization code request with the appropriate parameters. Then, in the second leg of the flow, listen for the authorization code response. Once the code is obtained, exchange it to obtain a token.
111+
> You can use MSAL Node's acquireTokenInteractive public API to acquire tokens via an external user-agent such as the default system browser.
112112
>
113113
> ```javascript
114-
> // The redirect URI you setup during app registration with a custom file protocol "msal"
115-
> const redirectUri = "msal://redirect";
116-
>
117-
> const cryptoProvider = new CryptoProvider();
118-
>
119-
> const pkceCodes = {
120-
> challengeMethod: "S256", // Use SHA256 Algorithm
121-
> verifier: "", // Generate a code verifier for the Auth Code Request first
122-
> challenge: "" // Generate a code challenge from the previously generated code verifier
123-
> };
124-
>
125-
> /**
126-
> * Starts an interactive token request
127-
> * @param {object} authWindow: Electron window object
128-
> * @param {object} tokenRequest: token request object with scopes
129-
> */
130-
> async function getTokenInteractive(authWindow, tokenRequest) {
131-
>
132-
> /**
133-
> * Proof Key for Code Exchange (PKCE) Setup
134-
> *
135-
> * MSAL enables PKCE in the Authorization Code Grant Flow by including the codeChallenge and codeChallengeMethod
136-
> * parameters in the request passed into getAuthCodeUrl() API, as well as the codeVerifier parameter in the
137-
> * second leg (acquireTokenByCode() API).
138-
> */
139-
>
140-
> const {verifier, challenge} = await cryptoProvider.generatePkceCodes();
141-
>
142-
> pkceCodes.verifier = verifier;
143-
> pkceCodes.challenge = challenge;
144-
>
145-
> const authCodeUrlParams = {
146-
> redirectUri: redirectUri
147-
> scopes: tokenRequest.scopes,
148-
> codeChallenge: pkceCodes.challenge, // PKCE Code Challenge
149-
> codeChallengeMethod: pkceCodes.challengeMethod // PKCE Code Challenge Method
150-
> };
151-
>
152-
> const authCodeUrl = await pca.getAuthCodeUrl(authCodeUrlParams);
153-
>
154-
> // register the custom file protocol in redirect URI
155-
> protocol.registerFileProtocol(redirectUri.split(":")[0], (req, callback) => {
156-
> const requestUrl = url.parse(req.url, true);
157-
> callback(path.normalize(`${__dirname}/${requestUrl.path}`));
158-
> });
159-
>
160-
> const authCode = await listenForAuthCode(authCodeUrl, authWindow); // see below
161-
>
162-
> const authResponse = await pca.acquireTokenByCode({
163-
> redirectUri: redirectUri,
164-
> scopes: tokenRequest.scopes,
165-
> code: authCode,
166-
> codeVerifier: pkceCodes.verifier // PKCE Code Verifier
167-
> });
168-
>
169-
> return authResponse;
170-
> }
171-
>
172-
> /**
173-
> * Listens for auth code response from Azure AD
174-
> * @param {string} navigateUrl: URL where auth code response is parsed
175-
> * @param {object} authWindow: Electron window object
176-
> */
177-
> async function listenForAuthCode(navigateUrl, authWindow) {
178-
>
179-
> authWindow.loadURL(navigateUrl);
180-
>
181-
> return new Promise((resolve, reject) => {
182-
> authWindow.webContents.on('will-redirect', (event, responseUrl) => {
183-
> try {
184-
> const parsedUrl = new URL(responseUrl);
185-
> const authCode = parsedUrl.searchParams.get('code');
186-
> resolve(authCode);
187-
> } catch (err) {
188-
> reject(err);
189-
> }
190-
> });
191-
> });
114+
> const { shell } = require('electron');
115+
>
116+
> try {
117+
> const openBrowser = async (url) => {
118+
> await shell.openExternal(url);
119+
> };
120+
>
121+
> const authResponse = await pca.acquireTokenInteractive({
122+
> scopes: ["User.Read"],
123+
> openBrowser,
124+
> successTemplate: '<h1>Successfully signed in!</h1> <p>You can close this window now.</p>',
125+
> failureTemplate: '<h1>Oops! Something went wrong</h1> <p>Check the console for more information.</p>',
126+
> });
127+
>
128+
> return authResponse;
129+
> } catch (error) {
130+
> throw error;
192131
> }
193132
> ```
194-
>
195-
> > |Where:| Description |
196-
> > |---------|---------|
197-
> > | `authWindow` | Current Electron window in process. |
198-
> > | `tokenRequest` | Contains the scopes being requested, such as `"User.Read"` for Microsoft Graph or `"api://<Application ID>/access_as_user"` for custom web APIs. |
133+
>
199134
>
200135
> ## Next steps
201136
>

articles/active-directory/develop/tutorial-v2-nodejs-desktop.md

Lines changed: 16 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -40,9 +40,9 @@ First, complete the steps in [Register an application with the Microsoft identit
4040
Use the following settings for your app registration:
4141

4242
- Name: `ElectronDesktopApp` (suggested)
43-
- Supported account types: **Accounts in any organizational directory (Any Azure AD directory - Multitenant) and personal Microsoft accounts (e.g. Skype, Xbox)**
43+
- Supported account types: **Accounts in my organizational directory only (single tenant)**
4444
- Platform type: **Mobile and desktop applications**
45-
- Redirect URI: `msal{Your_Application/Client_Id}://auth`
45+
- Redirect URI: `http://localhost`
4646

4747
## Create the project
4848

@@ -52,8 +52,8 @@ Create a folder to host your application, for example *ElectronDesktopApp*.
5252

5353
```console
5454
npm init -y
55-
npm install --save @azure/msal-node axios bootstrap dotenv jquery popper.js
56-
npm install --save-dev babel electron@18.2.3 webpack
55+
npm install --save @azure/msal-node @microsoft/microsoft-graph-sdk isomorphic-fetch bootstrap jquery popper.js
56+
npm install --save-dev electron@20.0.0
5757
```
5858

5959
2. Then, create a folder named *App*. Inside this folder, create a file named *index.html* that will serve as UI. Add the following code there:
@@ -76,9 +76,7 @@ The renderer methods are exposed by the preload script found in the *preload.js*
7676

7777
:::code language="js" source="~/ms-identity-JavaScript-nodejs-desktop/App/preload.js":::
7878

79-
This preload script exposes a renderer methods to give the renderer process controlled access to some `Node APIs` by applying IPC channels that have been configured for communication between the main and renderer processes.
80-
81-
*CustomProtocolListener* class can be instantiated in order to register and unregister a custom typed protocol on which MSAL Node can listen for Auth Code responses.
79+
This preload script exposes a renderer API to give the renderer process controlled access to some `Node APIs` by applying IPC channels that have been configured for communication between the main and renderer processes.
8280

8381
6. Finally, create a file named *constants.js* that will store the strings constants for describing the application **events**:
8482

@@ -91,13 +89,11 @@ ElectronDesktopApp/
9189
├── App
9290
│   ├── AuthProvider.js
9391
│   ├── constants.js
94-
│   ├── CustomProtocolListener.js
95-
│   ├── fetch.js
92+
│   ├── graph.js
9693
│   ├── index.html
9794
| ├── main.js
9895
| ├── preload.js
9996
| ├── renderer.js
100-
│   ├── UIManager.js
10197
│   ├── authConfig.js
10298
├── package.json
10399
```
@@ -108,11 +104,17 @@ In *App* folder, create a file named *AuthProvider.js*. The *AuthProvider.js* fi
108104
109105
:::code language="js" source="~/ms-identity-JavaScript-nodejs-desktop/App/AuthProvider.js":::
110106
111-
In the code snippet above, we first initialized MSAL Node `PublicClientApplication` by passing a configuration object (`msalConfig`). We then exposed `login`, `logout` and `getToken` methods to be called by main module (*main.js*). In `login` and `getToken`, we acquire ID and access tokens, respectively, by first requesting an authorization code and then exchanging this with a token using MSAL Node `acquireTokenByCode` public API.
107+
In the code snippet above, we first initialized MSAL Node `PublicClientApplication` by passing a configuration object (`msalConfig`). We then exposed `login`, `logout` and `getToken` methods to be called by main module (*main.js*). In `login` and `getToken`, we acquire ID and access tokens using MSAL Node `acquireTokenInteractive` public API.
108+
109+
## Add Microsoft Graph SDK
110+
111+
Create a file named *graph.js*. The *graph.js* file will contain an instance of the Microsoft Graph SDK Client to facilitate accessing data on the Microsoft Graph API, using the access token obtained by MSAL Node:
112+
113+
:::code language="js" source="~/ms-identity-JavaScript-nodejs-desktop/App/graph.js":::
112114
113115
## Add app registration details
114116
115-
Finally, create an environment file to store the app registration details that will be used when acquiring tokens. To do so, create a file named *authConfig.js* inside the root folder of the sample (*ElectronDesktopApp*), and add the following code:
117+
Create an environment file to store the app registration details that will be used when acquiring tokens. To do so, create a file named *authConfig.js* inside the root folder of the sample (*ElectronDesktopApp*), and add the following code:
116118
117119
:::code language="js" source="~/ms-identity-JavaScript-nodejs-desktop/App/authConfig.js":::
118120
@@ -127,7 +129,6 @@ Fill in these details with the values you obtain from Azure app registration por
127129
- `Enter_the_Cloud_Instance_Id_Here`: The Azure cloud instance in which your application is registered.
128130
- For the main (or *global*) Azure cloud, enter `https://login.microsoftonline.com/`.
129131
- For **national** clouds (for example, China), you can find appropriate values in [National clouds](authentication-national-cloud.md).
130-
- `Enter_the_Redirect_Uri_Here`: The Redirect Uri of the application you registered `msal{Your_Application/Client_Id}:///auth`.
131132
- `Enter_the_Graph_Endpoint_Here` is the instance of the Microsoft Graph API the application should communicate with.
132133
- For the **global** Microsoft Graph API endpoint, replace both instances of this string with `https://graph.microsoft.com/`.
133134
- For endpoints in **national** cloud deployments, see [National cloud deployments](/graph/deployments) in the Microsoft Graph documentation.
@@ -156,23 +157,13 @@ If you consent to the requested permissions, the web applications displays your
156157

157158
## Test web API call
158159

159-
After you sign in, select **See Profile** to view the user profile information returned in the response from the call to the Microsoft Graph API:
160+
After you sign in, select **See Profile** to view the user profile information returned in the response from the call to the Microsoft Graph API. After consent, you'll view the profile information returned in the response:
160161

161162
:::image type="content" source="media/tutorial-v2-nodejs-desktop/desktop-04-profile.png" alt-text="profile information from Microsoft Graph":::
162163

163-
Select **Read Mails** to view the messages in user's account. You'll be presented with a consent screen:
164-
165-
:::image type="content" source="media/tutorial-v2-nodejs-desktop/desktop-05-consent-mail.png" alt-text="consent screen for read.mail permission":::
166-
167-
After consent, you'll view the messages returned in the response from the call to the Microsoft Graph API:
168-
169-
:::image type="content" source="media/tutorial-v2-nodejs-desktop/desktop-06-mails.png" alt-text="mail information from Microsoft Graph":::
170-
171164
## How the application works
172165

173-
When a user selects the **Sign In** button for the first time, get `getTokenInteractive` method of *AuthProvider.js* is called. This method redirects the user to sign-in with the Microsoft identity platform endpoint and validates the user's credentials, and then obtains an **authorization code**. This code is then exchanged for an access token using `acquireTokenByCode` public API of MSAL Node.
174-
175-
At this point, a PKCE-protected authorization code is sent to the CORS-protected token endpoint and is exchanged for tokens. An ID token, access token, and refresh token are received by your application and processed by MSAL Node, and the information contained in the tokens is cached.
166+
When a user selects the **Sign In** button for the first time, the `acquireTokenInteractive` method of MSAL Node. This method redirects the user to sign-in with the Microsoft identity platform endpoint and validates the user's credentials, obtains an **authorization code** and then exchanges that code for an ID token, access token, and refresh token. MSAL Node also caches these tokens for future use.
176167

177168
The ID token contains basic information about the user, like their display name. The access token has a limited lifetime and expires after 24 hours. If you plan to use these tokens for accessing protected resource, your back-end server *must* validate it to guarantee the token was issued to a valid user for your application.
178169

0 commit comments

Comments
 (0)