You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
# Requires non-internal subscription - internal subscriptons doesn't provide permission to correctly configure AAD apps
11
11
---
12
12
13
-
# Tutorial: Authenticate and authorize users end-to-end in Azure App Service to a downstream Azure service
13
+
# Tutorial: Flow authentication from App Service through back-end API to Microsoft Graph
14
14
15
15
Learn how to create and configure a backend App service to accept a frontend app's user credential, then exchange that credential for a downstream Azure service. This allows a user to sign in to a frontend App service, pass their credential to a backend App service, then access an Azure service with the same identity.
16
16
17
17
In this tutorial, you learn how to:
18
18
19
19
> [!div class="checklist"]
20
20
>
21
-
> * Extend the previous tutorial's backend app
22
21
> * Configure the backend authentication app to provide a token scoped for the downstream Azure service
23
-
> * Use JavaScript code to exchange the user's token for a new token for downstream service.
22
+
> * Use JavaScript code to exchange the [signed-in user's access token](configure-authentication-oauth-tokens.md#retrieve-tokens-in-app-code) for a new token for downstream service.
24
23
> * Use JavaScript code to access downstream service.
25
24
26
25
## Prerequisites
27
26
28
-
Complete the [previous tutorial](tutorial-auth-aad.md) before starting this tutorial but don't remove the resources at the end of the tutorial. This tutorial assumes you have the two App services and their corresponding authentication apps.
27
+
Complete the previous tutorial, [Access Microsoft Graph from a secured JavaScript app as the user](tutorial-auth-aad.md), before starting this tutorial but don't remove the resources at the end of the tutorial. This tutorial assumes you have the two App services and their corresponding authentication apps.
29
28
30
29
The previous tutorial used the Azure Cloud Shell as the shell for the Azure CLI. This tutorial continues that usage. In order to add the code to the backend app service to exchange the token, this tutorial uses a version of the _code_ editor. Other editors are available such as nano, vim, and emacs.
31
30
32
31
## Architecture
33
32
34
33
The tutorial shows how to pass the user credential provided by the frontend app to the backend app then on to an Azure service. In this tutorial, the downstream service is Microsoft Graph. The user's credential is used to get their profile from Microsoft Graph.
* Change the frontend app from the previous tutorial.
52
53
* Change the backend authentication app's scope permission because `User.Read` is added by default to all authentication apps.
53
54
54
-
## Understand user consent
55
+
## 1. Configure admin consent for the backend app
55
56
56
57
In the previous tutorial, when the user signed in to the frontend app, a pop-up displayed asking for user consent.
57
58
58
-
:::image type="content" source="./media/tutorial-auth-aad/browser-screenshot-authentication-permission-requested-pop-up.png" alt-text="Screenshot of browser authentication pop-up requesting permissions.":::
59
-
60
-
In this tutorial, the backend needs to exchange the user's token for a new token with an audience for **Microsoft Graph** with a scope of **User.Read** in order to get the user's profile. Because the user isn't directly connected to the backend app, you need to configure the backend authentication app to _not require_ user consent for Microsoft Graph.
61
-
62
-
This is a setting change typically done by an Active Directory administrator. For this tutorial, you change that setting as though you've been assigned that task in your organization. If you don't change this setting, the backend app logs an error such as `AADSTS65001: The user or administrator has not consented to use the application with ID \<backend-authentication-id>. Send an interactive authorization request for this user and resource`. Because the error shows up in the log for the backend app, the frontend application can't tell the user why they didn't see their profile in the frontend app.
63
-
64
-
## 1. Configure backend authentication app with admin consent
65
-
66
-
Configure the [user consent](#understand-user-consent) for the backend app.
59
+
In this tutorial, in order to read user profile from Microsoft Graph, the back-end app needs to exchange the signed-in user's [access token](../active-directory/develop/access-tokens.md) for a new access token with the required permissions for Microsoft Graph. Because the user isn't directly connected to the backend app, they can't access the consent screen interactively. You must work around this by configuring the back-end app's app registration in Azure AD to [grant admin consent](../active-directory/manage-apps/grant-admin-consent.md?pivots=portal). This is a setting change typically done by an Active Directory administrator.
67
60
68
61
1. Open the Azure portal and search for your research for the backend App Service.
69
62
1. Find the **Settings -> Authentication** section.
@@ -74,13 +67,15 @@ Configure the [user consent](#understand-user-consent) for the backend app.
74
67
:::image type="content" source="./media/tutorial-connect-app-app-graph-javascript/azure-portal-authentication-app-api-permission-admin-consent-area.png" alt-text="Screenshot of Azure portal authentication app with admin consent button highlighted.":::
75
68
76
69
1. In the pop-up window, select **Yes** to confirm the consent.
77
-
1. Verify the **Status** column says **Granted for Default Directory**.
70
+
1. Verify the **Status** column says **Granted for Default Directory**. With this setting, the back-end app is no longer required to show a consent screen to the signed-in user and can directly request an access token. The signed-in user will have access to the `User.Read` scope setting because that is the default scope with which the app registration is created.
78
71
79
72
:::image type="content" source="./media/tutorial-connect-app-app-graph-javascript/azure-portal-authentication-app-api-permission-admin-consent-granted.png" alt-text="Screenshot of Azure portal authentication app with admin consent granted in status column.":::
80
73
74
+
75
+
81
76
## 2. Install npm packages
82
77
83
-
In the previous tutorial, the backend app didn't need any npm packages for authentication because the only authentication was provided by configuring the identity provider in the Azure portal. In this tutorial, the user's token for the backend API with `user_impersonation` needs to be exchanged for a Microsoft Graph token. This exchange is completed with two libraries.
78
+
In the previous tutorial, the backend app didn't need any npm packages for authentication because the only authentication was provided by configuring the identity provider in the Azure portal. In this tutorial, the signed-in user's access token for the back-end API must be exchanged for an access token with Microsoft Graph in its scope. This exchange is completed with two libraries because this exchange doesn't use App Service authentication anymore, but Azure Active Directory and MSAL.js directly.
*[@microsoft/microsoft-graph-client](https://www.npmjs.com/package/@microsoft/microsoft-graph-client) - connect to Microsoft Graph
@@ -107,12 +102,6 @@ In the previous tutorial, the backend app didn't need any npm packages for authe
107
102
108
103
The source code to complete this step is provided for you. Use the following steps to include it.
109
104
110
-
1. Use the Cloud Shell to open the backend app with _code_:
111
-
112
-
```azurecli-interactive
113
-
code .
114
-
```
115
-
116
105
1. Open the `./src/server.js` file.
117
106
1. Uncomment the following dependency at the top of the file:
118
107
@@ -156,9 +145,6 @@ The following code is already provided for you in the sample app. You need to un
156
145
Get the current tenant ID from the `WEBSITE_AUTH_OPENID_ISSUER` environment variable. The ID just needs to be parsed out of the variable with a regular expression.
157
146
158
147
```javascript
159
-
// Programmatically get tenant id from env var
160
-
// Env var was set by Easy Auth in App Service
161
-
// env value should look something like: https://sts.windows.net/YOUR-TENANT-ID-AS-GUID/v2.0
@@ -210,10 +196,10 @@ export async function getGraphToken(backEndAccessToken) {
210
196
scopes: ["https://graph.microsoft.com/.default"]
211
197
}
212
198
213
-
// This example has Easy auth validate token in App service runtime
199
+
// This example has App service validate token in runtime
214
200
// from headers that can't be set externally
215
201
216
-
// If you aren't using App service/Easy Auth,
202
+
// If you aren't using App service's authentication,
217
203
// you must validate your access token yourself
218
204
// before calling this code
219
205
try {
@@ -227,6 +213,11 @@ export async function getGraphToken(backEndAccessToken) {
227
213
228
214
## 5. Get the user's profile from Microsoft Graph
229
215
216
+
Before the token exchange, remember that the steps included:
217
+
* Configuration of the Active Directory app registration with an API permission to Microsoft Graph with the scope `User.Read`.
218
+
* Grant admin consent to bypass the user consent screen for the back-end app.
219
+
* Change the application code to convert the access token sent from the front-end app to an access token with the required permission for Microsoft Graph.
220
+
230
221
Now that the code has the correct token for Microsoft Graph, use it to create a client to Microsoft Graph then get the user's profile.
231
222
232
223
The following code is already provided for you in the sample app. You need to understand why it's there and how it works so that you can apply this work to other apps you build that need this same functionality.
@@ -263,7 +254,7 @@ export async function getGraphProfile(accessToken) {
263
254
}
264
255
```
265
256
266
-
## 6. Use frontend app to get your profile from Microsoft Graph
257
+
## 6. Test your changes
267
258
268
259
1. Use the frontend web site in a browser. The URL is in the format of `https://<front-end-app-name>.azurewebsites.net/`. You may need to refresh your token if it's expired.
269
260
1. Select `Get user's profile`. This passes your authentication in the bearer token to the backend.
@@ -278,12 +269,15 @@ export async function getGraphProfile(accessToken) {
278
269
279
270
## Frequently asked questions
280
271
281
-
### I got an error, what does it mean?
272
+
#### I got an error `80049217`, what does it mean?
273
+
274
+
This error, `CompactToken parsing failed with error code: 80049217`, means the backend App service isn't authorized to return the Microsoft Graph token.
275
+
276
+
#### I got an error `AADSTS65001`, what does it mean?
282
277
283
-
*`CompactToken parsing failed with error code: 80049217` means the backend App service isn't authorized to return the Microsoft Graph token.
284
-
*`AADSTS65001: The user or administrator has not consented to use the application with ID \<backend-authentication-id>. Send an interactive authorization request for this user and resource` means the backend authentication app hasn't been configured for Admin consent.
278
+
This error, `AADSTS65001: The user or administrator has not consented to use the application with ID \<backend-authentication-id>. Send an interactive authorization request for this user and resource`, means the backend authentication app hasn't been configured for Admin consent. Because the error shows up in the log for the backend app, the frontend application can't tell the user why they didn't see their profile in the frontend app.
285
279
286
-
##Connect to downstream Azure service as user
280
+
#### How do I connect to a different downstream Azure service as user?
287
281
288
282
This tutorial demonstrates an API app authenticated to **Microsoft Graph**, however, the same general steps can be applied to access any Azure service on behalf of the user.
289
283
@@ -294,4 +288,5 @@ This tutorial demonstrates an API app authenticated to **Microsoft Graph**, howe
294
288
295
289
## Next steps
296
290
291
+
*[Tutorial: Create a secure n-tier app in Azure App Service](tutorial-secure-ntier-app.md)
297
292
*[Deploy a Node.js + MongoDB web app to Azure](tutorial-nodejs-mongodb-app.md)
0 commit comments