Skip to content

Commit 9fa8f01

Browse files
committed
merge
2 parents 164a302 + 49abddc commit 9fa8f01

File tree

19 files changed

+249
-228
lines changed

19 files changed

+249
-228
lines changed

4-WebApp-your-API/4-1-MyOrg/AppCreationScripts/sample.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
"Service": "ASP.NET Core Web API",
88
"RepositoryUrl": "active-directory-aspnetcore-webapp-openidconnect-v2",
99
"Endpoint": "AAD v2.0",
10-
"Description": "This sample demonstrates an ASP.NET Core client Web App calling an ASP.NET Core Web API that is secured using Azure AD.",
10+
"Description": "This sample demonstrates a ASP.NET Core Web App signing-in a user and calling a ASP.NET Core Web API that is secured with Azure AD.",
1111
"Languages": [ "csharp" ],
1212
"Products": [ "aspnet-core", "azure-active-directory" ]
1313
},

4-WebApp-your-API/4-1-MyOrg/Client/Controllers/TodoListController.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
using Microsoft.AspNetCore.Mvc;
33
using Microsoft.Identity.Web;
44
using System.Threading.Tasks;
5-
using TodoListClient.Models;
5+
using TodoListService.Models;
66
using TodoListClient.Services;
77

88
namespace TodoListClient.Controllers

4-WebApp-your-API/4-1-MyOrg/Client/Services/ITodoListService.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
2424

2525
using System.Collections.Generic;
2626
using System.Threading.Tasks;
27-
using TodoListClient.Models;
27+
using TodoListService.Models;
2828

2929
namespace TodoListClient.Services
3030
{

4-WebApp-your-API/4-1-MyOrg/Client/Services/TodoListService.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
using System.Net.Http.Headers;
1313
using System.Text;
1414
using System.Threading.Tasks;
15-
using TodoListClient.Models;
15+
using TodoListService.Models;
1616

1717
namespace TodoListClient.Services
1818
{

4-WebApp-your-API/4-1-MyOrg/Client/TodoListClient.csproj

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,4 +23,8 @@
2323
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
2424
</ItemGroup>
2525

26+
<ItemGroup>
27+
<ProjectReference Include="..\TodoListService\TodoListService.csproj" />
28+
</ItemGroup>
29+
2630
</Project>

4-WebApp-your-API/4-1-MyOrg/Client/Views/TodoList/Create.cshtml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
@model TodoListClient.Models.Todo
1+
@model TodoListService.Models.Todo
22
@{
33
ViewData["Title"] = "Create";
44
}

4-WebApp-your-API/4-1-MyOrg/Client/Views/TodoList/Delete.cshtml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
@model TodoListClient.Models.Todo
1+
@model TodoListService.Models.Todo
22

33
@{
44
ViewData["Title"] = "Delete";

4-WebApp-your-API/4-1-MyOrg/Client/Views/TodoList/Details.cshtml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
@model TodoListClient.Models.Todo
1+
@model TodoListService.Models.Todo
22

33
@{
44
ViewData["Title"] = "Details";

4-WebApp-your-API/4-1-MyOrg/Client/Views/TodoList/Edit.cshtml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
@model TodoListClient.Models.Todo
1+
@model TodoListService.Models.Todo
22
@{
33
ViewData["Title"] = "Edit";
44
}

4-WebApp-your-API/4-1-MyOrg/Client/Views/TodoList/Index.cshtml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
@model IEnumerable<TodoListClient.Models.Todo>
1+
@model IEnumerable<TodoListService.Models.Todo>
22

33
@{
44
ViewData["Title"] = "Index";

4-WebApp-your-API/4-1-MyOrg/README-use-certificate.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ This sample was configured to use a client secret, but have an option to use a c
2828
]
2929
```
3030

31-
1. While inside the sample folder, open a Powershell terminal
31+
1. While inside '4-1-MyOrg' folder, open a Powershell terminal
3232

3333
1. Set next execution policy
3434

@@ -76,7 +76,7 @@ AppCreationScripts-withCert/Configure.ps1
7676
]
7777
```
7878

79-
1. While inside the sample folder, open a Powershell terminal
79+
1. While inside '4-1-MyOrg' folder, open a Powershell terminal
8080

8181
1. Set next execution policy
8282

4-WebApp-your-API/4-1-MyOrg/README.md

Lines changed: 94 additions & 113 deletions
Large diffs are not rendered by default.

4-WebApp-your-API/4-1-MyOrg/ReadmeFiles/ReadmeAboutTheCode.md

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,12 @@
2424
* `AddMicrosoftIdentityWebApiAuthentication()` protects the Web API by [validating Access tokens](https://docs.microsoft.com/azure/active-directory/develop/access-tokens#validating-tokens) sent tho this API. Check out [Protected web API: Code configuration](https://docs.microsoft.com/azure/active-directory/develop/scenario-protected-web-api-app-configuration) which explains the inner workings of this method in more detail.
2525
2626
* There is a bit of code (commented) provided under this method that can be used to used do extended token validation and check for additional claims, such as:
27-
* check if the caller's tenant is in the allowed tenants list via the 'tid' claim (for multi-tenant applications)
27+
* check if the client app's appid (azp) is in some sort of an allowed list via the 'azp' claim, in case you wanted to restrict the API to a list of client apps.
2828
* check if the caller's account is homed or guest via the 'acct' optional claim
2929
* check if the caller belongs to right roles or groups via the 'roles' or 'groups' claim, respectively
3030

31-
* Then in the controllers `TodoListController.cs`, the `[Authorize]` added on top of the class to protect this route.
32-
* Further in the controller, the [RequiredScopeOrAppPermission](https://github.com/AzureAD/microsoft-identity-web/wiki/web-apis#checking-for-scopes-or-app-permissions=) is used to list the scopes ([Delegated permissions](https://docs.microsoft.com/azure/active-directory/develop/v2-permissions-and-consent)), that the user should consent for, before the method can be called.
31+
1. Then in the controllers `TodoListController.cs`, the `[Authorize]` added on top of the class to protect this route.
32+
* Further in the controller, the [RequiredScopeOrAppPermission](https://github.com/AzureAD/microsoft-identity-web/wiki/web-apis#checking-for-scopes-or-app-permissions=) is used to list the ([Delegated permissions](https://docs.microsoft.com/azure/active-directory/develop/v2-permissions-and-consent)), that the user should consent for, before the method can be called.
3333
* The delegated permissions are checked inside `TodoListService\Controllers\ToDoListController.cs` in the following manner:
3434

3535
```CSharp
@@ -40,7 +40,7 @@
4040
)]
4141
public IEnumerable<Todo> Get()
4242
{
43-
if (IsUserToken())
43+
if (!IsAppOnlyToken())
4444
{
4545
// this is a request for all ToDo list items of a certain user.
4646
return TodoStore.Values.Where(x => x.Owner == _currentLoggedUser);
@@ -53,10 +53,10 @@
5353
}
5454
```
5555

56-
The code above demonstrates that to be able to reach a GET REST operation, the access token should contain AT LEAST ONE of the scopes listed inside parameter of [RequiredScopeOrAppPermission](https://github.com/AzureAD/microsoft-identity-web/wiki/web-apis#checking-for-scopes-or-app-permissions=) attribute
56+
The code above demonstrates that to be able to reach a GET REST operation, the access token should contain AT LEAST ONE of the scopes (delegated permissions) listed inside parameter of [RequiredScopeOrAppPermission](https://github.com/AzureAD/microsoft-identity-web/wiki/web-apis#checking-for-scopes-or-app-permissions=) attribute
5757
Please note that while in this sample, the client app only works with *Delegated Permissions*, the API's controller is designed to work with both *Delegated* and *Application* permissions.
5858

59-
The **ToDoList.*.All** permissions are **Application Permissions**.
59+
The **ToDoList.<*>.All** permissions are **Application Permissions**.
6060

6161
Here is another example from the same controller:
6262

@@ -67,7 +67,7 @@
6767
AcceptedAppPermission = new string[] { "ToDoList.ReadWrite.All" })]
6868
public void Delete(int id)
6969
{
70-
if (IsUserToken())
70+
if (!IsAppOnlyToken())
7171
{
7272
// only delete if the ToDo list item belonged to this user
7373
if (TodoStore.Values.Any(x => x.Id == id && x.Owner == _currentLoggedUser))
@@ -86,6 +86,18 @@
8686
Also note of how we distinguish the **what** a user can delete. When there is a **ToDoList.ReadWrite.All** permission available, the user can delete **ANY** entity from the database,
8787
but with **ToDoList.ReadWrite**, the user can delete only their own entries.
8888

89+
* The method *IsAppOnlyToken()* is used by controller method to detect presence of an app only token, i.e a token that was issued to an app using the [Client credentials](https://docs.microsoft.com/azure/active-directory/develop/v2-oauth2-client-creds-grant-flow) flow, i.e no users were signed-in by this client app.
90+
91+
```csharp
92+
private bool IsAppOnlyToken()
93+
{
94+
// Add in the optional 'idtyp' claim to check if the access token is coming from an application or user.
95+
//
96+
// See: https://docs.microsoft.com/en-us/azure/active-directory/develop/active-directory-optional-claims
97+
return HttpContext.User.Claims.Any(c => c.Type == "idtyp" && c.Value == "app");
98+
}
99+
```
100+
89101
### Initial scopes
90102

91103
Client [appsettings.json](../4-1-MyOrg/Client/appsettings.json) file contains `ToDoListScopes` key that is used in [startup.cs](../4-1-MyOrg/Client/Startup.cs#L46) to specify which initial scopes should be requested from Web API when refreshing the token:
Lines changed: 59 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,50 @@
1+
12
## How the code was created
23

34
<details>
45
<summary>Expand the section</summary>
56

7+
### Creating the Web API project (TodoListService)
8+
9+
The code for the TodoListService was created in the following way:
10+
11+
#### Step 1: Create the web api using the ASP.NET Core templates
12+
13+
```Text
14+
md TodoListService
15+
cd TodoListService
16+
dotnet new webapi -au=SingleOrg
17+
```
18+
19+
1. Open the generated project (.csproj) in Visual Studio, and save the solution.
20+
21+
#### Add a model (TodoListItem) and modify the controller
22+
23+
In the TodoListService project, add a folder named `Models` and then create a new file named `TodoItem.cs`. Copy the contents of the TodoListService\Models\TodoItem.cs in this file.
24+
25+
### Modify the Program.cs file to validate bearer access tokens received by the Web API
26+
27+
Update `Program.cs` file :
28+
29+
*replace the following code:
30+
31+
```CSharp
32+
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
33+
.AddMicrosoftIdentityWebApi(builder.Configuration.GetSection("AzureAd"));
34+
```
35+
36+
with
37+
38+
```Csharp
39+
services.AddMicrosoftIdentityWebApiAuthentication(Configuration);
40+
```
41+
42+
### Create the TodoListController and associated Models
43+
44+
1. Add a reference to the ToDoListService.
45+
1. Create a new Controller named `TodoListController` and copy and paste the code from the sample (TodoListService\Controllers\TodoListController.cs) to this controller.
46+
1. Open the `appsettings.json` file and copy the keys from the sample's corresponding file under the `AzureAd` and `TodoList` sections.
47+
648
### Creating the client web app (TodoListClient)
749

850
#### Step 1: the sample from the command line
@@ -20,34 +62,27 @@
2062
#### Step 2: Modify the generated code
2163

2264
1. Open the generated project (.csproj) in Visual Studio, and save the solution.
23-
1. Add the `Microsoft.Identity.Web.csproj` project which is located at the root of this sample repo, to your solution (**Add Existing Project ...**). It's used to simplify signing-in and, in the next tutorial phases, to get a token.
24-
1. Add a reference from your newly generated project to `Microsoft.Identity.Web` (right click on the **Dependencies** node under your new project, and choose **Add Reference ...**, and then in the projects tab find the `Microsoft.Identity.Web` project)
25-
26-
1. Open the **Startup.cs** file and:
65+
1. Add the `Microsoft.Identity.Web` via Nuget.
66+
1. Open the **Program.cs** file and:
2767

28-
* at the top of the file, add the following using directive were added:
68+
* Replace the two following lines:
2969

30-
```CSharp
31-
using Microsoft.Identity.Web;
32-
```
33-
34-
* in the `ConfigureServices` method, replace the two following lines:
35-
36-
```CSharp
37-
services.AddAuthentication(AzureADDefaults.AuthenticationScheme)
38-
.AddAzureAD(options => Configuration.Bind("AzureAd", options));
39-
```
70+
```CSharp
71+
services.AddAuthentication(AzureADDefaults.AuthenticationScheme)
72+
.AddAzureAD(options => Configuration.Bind("AzureAd", options));
73+
```
4074

41-
with these lines:
75+
with these lines:
4276

43-
```CSharp
44-
services.AddMicrosoftIdentityWebAppAuthentication(Configuration)
45-
.EnableTokenAcquisitionToCallDownstreamApi(
46-
Configuration.GetSection("TodoList:TodoListScopes").Get<string>().Split(" ", System.StringSplitOptions.RemoveEmptyEntries))
47-
.AddInMemoryTokenCaches();
48-
```
77+
```CSharp
78+
services.AddMicrosoftIdentityWebAppAuthentication(Configuration)
79+
.EnableTokenAcquisitionToCallDownstreamApi(
80+
Configuration.GetSection("TodoList:TodoListScopes").Get<string>().Split(" ", System.StringSplitOptions.RemoveEmptyEntries)
81+
)
82+
.AddInMemoryTokenCaches();
83+
```
4984

50-
This enables your application to use the Microsoft identity platform endpoint. This endpoint is capable of signing-in users both with their Work and School and Microsoft Personal accounts.
85+
* This enables your application to use the Microsoft identity platform endpoint. This endpoint is capable of signing-in users both with their Work and School and Microsoft Personal accounts.
5186

5287
1. Change the `Properties\launchSettings.json` file to ensure that you start your web app from <https://localhost:44321> as registered. For this:
5388
* update the `sslPort` of the `iisSettings` section to be `44321`
@@ -59,7 +94,7 @@
5994
services.AddTodoListService(Configuration);
6095
```
6196

62-
1. Open the `appsettings.json` file and copy the keys from the sample's corresponding file under the `AzureAd` and `TodoList` sections.
97+
2. Open the `appsettings.json` file and copy the keys from the sample's corresponding file under the `AzureAd` and `TodoList` sections.
6398
6499
#### Add a model (TodoListItem) and add the controller and views
65100
@@ -82,67 +117,4 @@
82117
services.AddTodoListService(Configuration);
83118
```
84119
85-
1. Update the `Configure` method to include **app.UseAuthentication();** before **app.UseAuthorization();**
86-
87-
```Csharp
88-
app.UseAuthentication();
89-
app.AddAuthorization();
90-
```
91-
92-
### Creating the Web API project (TodoListService)
93-
94-
The code for the TodoListService was created in the following way:
95-
96-
#### Step 1: Create the web api using the ASP.NET Core templates
97-
98-
```Text
99-
md TodoListService
100-
cd TodoListService
101-
dotnet new webapi -au=SingleOrg
102-
```
103-
104-
1. Open the generated project (.csproj) in Visual Studio, and save the solution.
105-
106-
#### Add a model (TodoListItem) and modify the controller
107-
108-
In the TodoListService project, add a folder named `Models` and then create a new file named `TodoItem.cs`. Copy the contents of the TodoListService\Models\TodoItem.cs in this file.
109-
110-
### Modify the Startup.cs file to validate bearer access tokens received by the Web API
111-
112-
1. Add the `Microsoft.Identity.Web.csproj` project which is located at the root of this sample repo, to your solution (**Add Existing Project ...**).
113-
1. Add a reference from your newly generated project to `Microsoft.Identity.Web` (right click on the **Dependencies** node under your new project, and choose **Add Reference ...**, and then in the projects tab find the `Microsoft.Identity.Web` project)
114-
Update `Startup.cs` file :
115-
116-
*Add the following two using statements
117-
118-
```CSharp
119-
using Microsoft.Identity.Web;
120-
using Microsoft.Identity.Web.Client.TokenCacheProviders;
121-
```
122-
123-
*In the `ConfigureServices` method, replace the following code:
124-
125-
```CSharp
126-
services.AddAuthentication(AzureADDefaults.BearerAuthenticationScheme)
127-
.AddAzureADBearer(options => Configuration.Bind("AzureAd", options));
128-
```
129-
130-
with
131-
132-
```Csharp
133-
services.AddMicrosoftIdentityWebApiAuthentication(Configuration);
134-
```
135-
136-
*Add the method **app.UseAuthentication()** before **app.UseAuthorization()** in the `Configure` method
137-
138-
```Csharp
139-
app.UseAuthentication();
140-
app.UseAuthorization();
141-
```
142-
143-
### Create the TodoListController.cs file
144-
145-
1. Add a folder named `Models` and then create a new file named `TodoItem.cs`. Copy the contents of the TodoListClient\Models\TodoItem.cs in this file.
146-
1. Create a new Controller named `TodoListController` and copy and paste the code from the sample (TodoListService\Controllers\TodoListController.cs) to this controller.
147-
148120
</details>

4-WebApp-your-API/4-1-MyOrg/TodoListService/Controllers/TodoListController.cs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
// Copyright (c) Microsoft Corporation. All rights reserved.
22
// Licensed under the MIT License.
33

4+
using Microsoft.AspNetCore.Authorization;
45
using Microsoft.AspNetCore.Http;
56
using Microsoft.AspNetCore.Mvc;
67
using Microsoft.Identity.Web;
@@ -9,9 +10,7 @@
910
using System.Linq;
1011
using System.Net;
1112
using System.Net.Http;
12-
using Microsoft.AspNetCore.Authorization;
13-
using TodoListClient.Models;
14-
13+
using TodoListService.Models;
1514

1615
namespace TodoListService.Controllers
1716
{

0 commit comments

Comments
 (0)