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
Copy file name to clipboardExpand all lines: 4-WebApp-your-API/4-3-AnyOrg/Readme.md
+46-22Lines changed: 46 additions & 22 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -66,10 +66,6 @@ The Web API:
66
66
### Pre-requisites
67
67
68
68
-[Visual Studio 2019](https://aka.ms/vsdownload) or just the [.NET Core SDK](https://www.microsoft.com/net/learn/get-started)
69
-
- An Internet connection
70
-
- A Windows machine (necessary if you want to run the app on Windows)
71
-
- An OS X machine (necessary if you want to run the app on Mac)
72
-
- A Linux machine (necessary if you want to run the app on Linux)
73
69
- An Azure Active Directory (Azure AD) tenant. For more information on how to get an Azure AD tenant, see [How to get an Azure AD tenant](https://azure.microsoft.com/documentation/articles/active-directory-howto-tenant/)
74
70
- A user account in your Azure AD tenant. This sample will not work with a Microsoft account (formerly Windows Live account). Therefore, if you signed in to the [Azure portal](https://portal.azure.com) with a Microsoft account and have never created a user account in your directory before, you need to do that now.
75
71
@@ -228,6 +224,43 @@ Open the project in your IDE (like Visual Studio) to configure the code.
228
224
1. Find the app key `AdminConsentRedirectApi` and replace the existing value with the Redirect URI for WebApi-MultiTenant-v2 app. For example, `https://localhost:44351/api/Home` .
229
225
### Step 3: Run the sample
230
226
227
+
#### Using a command line interface such as VS Code integrated terminal, follow the steps below:
228
+
229
+
##### Step 1. Install .NET Core dependencies
230
+
231
+
```console
232
+
cd TodoListAPI
233
+
dotnet restore
234
+
```
235
+
Then:
236
+
In a separate console window, execute the following commands
237
+
238
+
```console
239
+
cd ../
240
+
cd ToDoListClient
241
+
dotnet restore
242
+
```
243
+
244
+
##### Step 2. Trust development certificates
245
+
246
+
```console
247
+
dotnet dev-certs https --clean
248
+
dotnet dev-certs https --trust
249
+
```
250
+
251
+
Learn more about [HTTPS in .NET Core](https://docs.microsoft.com/aspnet/core/security/enforcing-ssl).
252
+
253
+
##### Step 3. Run the applications
254
+
255
+
In both the windows execute the below command:
256
+
257
+
```console
258
+
dotnet run
259
+
```
260
+
Open your browser and navigate to `https://localhost:44321`.
261
+
262
+
#### Run the sample using Visual Studio:
263
+
231
264
Clean the solution, rebuild the solution, and run it. You might want to go into the solution properties and set both projects as startup projects, with the service project starting first.
232
265
233
266
When you start the Web API from Visual Studio, depending on the browser you use, you'll get:
@@ -237,33 +270,25 @@ When you start the Web API from Visual Studio, depending on the browser you use,
237
270
238
271
This behavior is expected as you are not authenticated. The client application will be authenticated, so it will be able to access the Web API.
239
272
273
+
## Explore the sample
274
+
240
275
Explore the sample by signing in into the TodoList client, adding items to the To Do list and assigning them to users. If you stop the application without signing out, the next time you run the application, you won't be prompted to sign in again.
241
276
242
-
To make the sample work for guest tenant, you need to provision service principal for that tenant. It can be done by clicking on `Admin Consent` link that is present on home page of Web App. The link provides consent screen that is used to create service principal by admin of the guest tenant.
277
+
For Home Tenant, admin needs to sign-in first as `User.Read.All` permission requires admin consent for the organization.
278
+
279
+
For guest tenant, you need to provision service principal for that tenant. It can be done by clicking on `Admin Consent` link that is present on home page of Web App. The link provides consent screen that is used to create service principal by admin of the guest tenant.
243
280
244
281
> NOTE: Remember, the To-Do list is stored in memory in this `TodoListService` app. Each time you run the projects, your To-Do list will get emptied.
245
282
246
283
> Did the sample not work for you as expected? Did you encounter issues trying this sample? Then please reach out to us using the [GitHub Issues](../../../../issues) page.
247
284
248
285
## About the code
249
286
250
-
### Consenting to Applications with Distributed Topology
251
-
252
-
Consider the application suite in this chapter: **TodoListAPI** and **TodoListSPA**. From one perspective, they are two different applications (two different projects), each represented with their own **app registration** on Azure AD, but from another perspective, they really constitute one application together i.e. a todo list application. In practice, an application can have a many such components: one component for the front-end, another for a REST API, another for a database and etc. While these components should have their own separate representation on Azure AD, they should also somehow know one another.
253
-
254
-
From the perspective of **multi-tenancy**, the main challenge with such topologies is with providing admin-consent. This is due to the fact that some of their components, such as a web API or a background micro-service, do not have a front-end, and as such, has no user-interaction capability. The solution for this is to allow the user (in this case, an admin-user) to consent to web API at the same time they consent to the front-end application i.e. give a **combined consent**. In **Chapter 1**, we have seen that the `/.default` scope can be used to this effect, allowing you to consent to many different scopes at one step. However, unlike **Chapter 1**, our application suite here also has a back-end/web API component. But how could the web API know that the consent comes from a recognized front-end application, as opposed to some foreign application? The answer is to use the **KnownClientApplications** feature.
255
-
256
-
> #### KnownClientApplications
257
-
>
258
-
> **KnownClientApplications** is an attribute in **application manifest**. It is used for bundling consent if you have a solution that contains two (or more) parts: a client app and a custom web API. If you enter the `appID` (clientID) of the client app into this array, the user will only have to consent only once to the client app. Azure AD will know that consenting to the client means implicitly consenting to the web API. It will automatically provision service principals for both the client and web API at the same time. Both the client and the web API app must be registered in the same tenant.
259
-
260
-
If you remember the last step of the registration for the client app (TodoListSPA), you were instructed to find the `KnownClientApplications` in application manifest, and add the Application (client) ID of the `TodoListSPA` application `KnownClient witApplications: ["your-client-id-for-TodoListSPA"]`. Once you do that, your web API will be able to correctly identify your front-end and the combined consent will be successfully carried out.
261
-
262
287
### Provisioning your Multi-tenant Apps in another Azure AD Tenant
263
288
264
-
Often the user-based consent will be disabled in an Azure AD tenant or your application will be requesting permissions that requires a tenant-admin consent. In these scenarios, your application will need to utilize the `/adminconsent` endpoint to provision both the **TodoListSPA** and the **TodoListAPI** before the users from that tenant are able to sign-in to your app.
289
+
Often the user-based consent will be disabled in an Azure AD tenant or your application will be requesting permissions that requires a tenant-admin consent. In these scenarios, your application will need to utilize the `/adminconsent` endpoint to provision both the **ToDoListClient** and the **TodoListAPI** before the users from that tenant are able to sign-in to your app.
265
290
266
-
When provisioning, you have to take care of the dependency in the topology where the **TodoListSPA** is dependent on **TodoListAPI**. So in such a case, you would provision the **TodoListAPI** before the **TodoListSPA**.
291
+
When provisioning, you have to take care of the dependency in the topology where the **ToDoListClient** is dependent on **TodoListAPI**. So in such a case, you would provision the **TodoListAPI** before the **ToDoListClient**.
Copy file name to clipboardExpand all lines: 4-WebApp-your-API/4-3-AnyOrg/ToDoListClient/appsettings.json
+1-1Lines changed: 1 addition & 1 deletion
Original file line number
Diff line number
Diff line change
@@ -2,7 +2,7 @@
2
2
"AzureAd": {
3
3
"Instance": "https://login.microsoftonline.com/",
4
4
"Domain": "[Enter the domain of your tenant, e.g. contoso.onmicrosoft.com]",
5
-
"TenantId": "[Enter 'common', or 'organizations' or the Tenant Id (Obtained from the Azure portal. Select 'Endpoints' from the 'App registrations' blade and use the GUID in any of the URLs), e.g. da41245a5-11b3-996c-00a8-4d99re19f292]",
5
+
"TenantId": "common",
6
6
"ClientId": "[Enter the Client Id (Application ID obtained from the Azure portal), e.g. ba74781c2-53c2-442a-97c2-3d60re42f403]",
7
7
"ClientSecret": "[Copy the client secret added to the app from the Azure portal]",
Copy file name to clipboardExpand all lines: 4-WebApp-your-API/4-3-AnyOrg/TodoListService/appsettings.json
+2-2Lines changed: 2 additions & 2 deletions
Original file line number
Diff line number
Diff line change
@@ -2,15 +2,15 @@
2
2
"AzureAd": {
3
3
"Instance": "https://login.microsoftonline.com/",
4
4
"Domain": "[Enter the domain of your tenant, e.g. contoso.onmicrosoft.com]",
5
-
"TenantId": "[Enter 'common', or 'organizations' or the Tenant Id (Obtained from the Azure portal. Select 'Endpoints' from the 'App registrations' blade and use the GUID in any of the URLs), e.g. da41245a5-11b3-996c-00a8-4d99re19f292]",
5
+
"TenantId": "common",
6
6
"ClientId": "[Enter the Client Id (Application ID obtained from the Azure portal), e.g. ba74781c2-53c2-442a-97c2-3d60re42f403]",
7
7
"ClientSecret": "[Copy the client secret added to the app from the Azure portal]",
0 commit comments