Skip to content

Commit 45b1750

Browse files
jmprieurjennyf19
andauthored
Jmprieur/webappwebapib2c (#298)
* Experiment for a B2C Web app calling a B2C Web API. Needs more work. * Test and fix B2C web app calls web api scenario Fix issue in AadIssuerValidator when certains claims are not present (ex. policy) in the token Fix bug w/scopes and scopeKeySection Send "client_info=1" to request to get client info back from AAD B2C Add ClientInfo class + methods to pull out the TenantId from the ClientInfo Add full value to UserFlow as it was not picking up on short version In TokenAcquisition, check first for b2c and then do null tenant and then tenant specific, was using the wrong authority for b2c previously Fix bug in determining audience validation * Fixing missing references * Uncommenting a needed line * Fixing a build break * Fixing the configuration and a problem brought bad a by merge by jmprieur * add uitid to the claims for b2c * moving Web app calling Web API with B2C in own folder * Reading the 4-1-MyOrg folder * Update README.md Co-authored-by: jennyf19 <jeferrie@microsoft.com>
1 parent 075bfc8 commit 45b1750

File tree

100 files changed

+27161
-164
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

100 files changed

+27161
-164
lines changed

.gitignore

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -39,9 +39,6 @@
3939
/2-WebApp-graph-user/2-2-TokenCache/.vs
4040
/2-WebApp-graph-user/2-2-TokenCache/bin
4141
/2-WebApp-graph-user/2-2-TokenCache/obj
42-
/2-WebApp-graph-user/2-3-Best-Practices/.vs
43-
/2-WebApp-graph-user/2-3-Best-Practices/bin
44-
/2-WebApp-graph-user/2-3-Best-Practices/obj
4542
/2-WebApp-graph-user/2-3-Multi-Tenant/.vs
4643
/2-WebApp-graph-user/2-3-Multi-Tenant/bin
4744
/2-WebApp-graph-user/2-3-Multi-Tenant/obj
@@ -121,11 +118,13 @@
121118
/2-WebApp-graph-user/2-4-Sovereign-Call-MSGraph/bin
122119
/2-WebApp-graph-user/2-4-Sovereign-Call-MSGraph/obj
123120
/Microsoft.Identity.Web.Test/obj
124-
/4-WebApp-your-API/4-2-B2C/.vs
125-
/4-WebApp-your-API/4-2-B2C/Client/obj
126-
/4-WebApp-your-API/4-2-B2C/TodoListService/obj
127121
/4-WebApp-your-API/4-1-MyOrg/.vs
128122
/4-WebApp-your-API/4-1-MyOrg/Client/bin
129123
/4-WebApp-your-API/4-1-MyOrg/Client/obj
130124
/4-WebApp-your-API/4-1-MyOrg/TodoListService/bin
131125
/4-WebApp-your-API/4-1-MyOrg/TodoListService/obj
126+
/4-WebApp-your-API/4-2-B2C/.vs
127+
/4-WebApp-your-API/4-2-B2C/Client/obj
128+
/4-WebApp-your-API/4-2-B2C/TodoListService/obj
129+
/4-WebApp-your-API/4-2-B2C/Client/bin
130+
/4-WebApp-your-API/4-2-B2C/TodoListService/bin

2-WebApp-graph-user/2-1-Call-MSGraph/AspnetCoreWebApp-calls-Microsoft-Graph.sln

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,14 +30,14 @@ Global
3030
{E0CEF26A-6CE6-4505-851B-6580D5564752}.Debug|Any CPU.Build.0 = Debug|Any CPU
3131
{E0CEF26A-6CE6-4505-851B-6580D5564752}.Release|Any CPU.ActiveCfg = Release|Any CPU
3232
{E0CEF26A-6CE6-4505-851B-6580D5564752}.Release|Any CPU.Build.0 = Release|Any CPU
33+
{8CCEAE2A-BDF6-470C-B6DE-7FC81A74DBD7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
34+
{8CCEAE2A-BDF6-470C-B6DE-7FC81A74DBD7}.Debug|Any CPU.Build.0 = Debug|Any CPU
35+
{8CCEAE2A-BDF6-470C-B6DE-7FC81A74DBD7}.Release|Any CPU.ActiveCfg = Release|Any CPU
36+
{8CCEAE2A-BDF6-470C-B6DE-7FC81A74DBD7}.Release|Any CPU.Build.0 = Release|Any CPU
3337
{8CC22202-F66C-4332-A4F0-A2C09EBA08EC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
3438
{8CC22202-F66C-4332-A4F0-A2C09EBA08EC}.Debug|Any CPU.Build.0 = Debug|Any CPU
3539
{8CC22202-F66C-4332-A4F0-A2C09EBA08EC}.Release|Any CPU.ActiveCfg = Release|Any CPU
3640
{8CC22202-F66C-4332-A4F0-A2C09EBA08EC}.Release|Any CPU.Build.0 = Release|Any CPU
37-
{0EEC3E2E-69D0-4A7F-98D6-4386330F4965}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
38-
{0EEC3E2E-69D0-4A7F-98D6-4386330F4965}.Debug|Any CPU.Build.0 = Debug|Any CPU
39-
{0EEC3E2E-69D0-4A7F-98D6-4386330F4965}.Release|Any CPU.ActiveCfg = Release|Any CPU
40-
{0EEC3E2E-69D0-4A7F-98D6-4386330F4965}.Release|Any CPU.Build.0 = Release|Any CPU
4141
EndGlobalSection
4242
GlobalSection(SolutionProperties) = preSolution
4343
HideSolutionNode = FALSE

4-WebApp-your-API/4-1-MyOrg/.vs/WebApp-Calls-WebAPI-MyOrg/config/applicationhost.config

Lines changed: 974 additions & 0 deletions
Large diffs are not rendered by default.

4-WebApp-your-API/4-1-MyOrg/Client/Program.cs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
1-
using Microsoft.AspNetCore.Hosting;
1+
// Copyright (c) Microsoft Corporation. All rights reserved.
2+
// Licensed under the MIT License.
3+
4+
using Microsoft.AspNetCore.Hosting;
25
using Microsoft.Extensions.Hosting;
36

47
namespace WebApp_OpenIDConnect_DotNet

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

Lines changed: 15 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,5 @@
1-
/*
2-
The MIT License (MIT)
3-
4-
Copyright (c) 2018 Microsoft Corporation
5-
6-
Permission is hereby granted, free of charge, to any person obtaining a copy
7-
of this software and associated documentation files (the "Software"), to deal
8-
in the Software without restriction, including without limitation the rights
9-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10-
copies of the Software, and to permit persons to whom the Software is
11-
furnished to do so, subject to the following conditions:
12-
13-
The above copyright notice and this permission notice shall be included in all
14-
copies or substantial portions of the Software.
15-
16-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22-
SOFTWARE.
23-
*/
1+
// Copyright (c) Microsoft Corporation. All rights reserved.
2+
// Licensed under the MIT License.
243

254
using Microsoft.AspNetCore.Http;
265
using Microsoft.Extensions.Configuration;
@@ -59,11 +38,11 @@ public class TodoListService : ITodoListService
5938

6039
public TodoListService(ITokenAcquisition tokenAcquisition, HttpClient httpClient, IConfiguration configuration, IHttpContextAccessor contextAccessor)
6140
{
62-
this._httpClient = httpClient;
63-
this._tokenAcquisition = tokenAcquisition;
64-
this._contextAccessor = contextAccessor;
65-
this._TodoListScope = configuration["TodoList:TodoListScope"];
66-
this._TodoListBaseAddress = configuration["TodoList:TodoListBaseAddress"];
41+
_httpClient = httpClient;
42+
_tokenAcquisition = tokenAcquisition;
43+
_contextAccessor = contextAccessor;
44+
_TodoListScope = configuration["TodoList:TodoListScope"];
45+
_TodoListBaseAddress = configuration["TodoList:TodoListBaseAddress"];
6746
}
6847

6948
public async Task<Todo> AddAsync(Todo todo)
@@ -72,8 +51,7 @@ public async Task<Todo> AddAsync(Todo todo)
7251

7352
var jsonRequest = JsonConvert.SerializeObject(todo);
7453
var jsoncontent = new StringContent(jsonRequest, Encoding.UTF8, "application/json");
75-
76-
var response = await this._httpClient.PostAsync($"{this._TodoListBaseAddress}/api/todolist", jsoncontent);
54+
var response = await this._httpClient.PostAsync($"{ _TodoListBaseAddress}/api/todolist", jsoncontent);
7755

7856
if (response.StatusCode == HttpStatusCode.OK)
7957
{
@@ -90,7 +68,7 @@ public async Task DeleteAsync(int id)
9068
{
9169
await PrepareAuthenticatedClient();
9270

93-
var response = await this._httpClient.DeleteAsync($"{this._TodoListBaseAddress}/api/todolist/{id}");
71+
var response = await _httpClient.DeleteAsync($"{ _TodoListBaseAddress}/api/todolist/{id}");
9472

9573
if (response.StatusCode == HttpStatusCode.OK)
9674
{
@@ -106,8 +84,7 @@ public async Task<Todo> EditAsync(Todo todo)
10684

10785
var jsonRequest = JsonConvert.SerializeObject(todo);
10886
var jsoncontent = new StringContent(jsonRequest, Encoding.UTF8, "application/json-patch+json");
109-
110-
var response = await this._httpClient.PatchAsync($"{this._TodoListBaseAddress}/api/todolist/{todo.Id}", jsoncontent);
87+
var response = await _httpClient.PatchAsync($"{ _TodoListBaseAddress}/api/todolist/{todo.Id}", jsoncontent);
11188

11289
if (response.StatusCode == HttpStatusCode.OK)
11390
{
@@ -123,8 +100,7 @@ public async Task<Todo> EditAsync(Todo todo)
123100
public async Task<IEnumerable<Todo>> GetAsync()
124101
{
125102
await PrepareAuthenticatedClient();
126-
127-
var response = await this._httpClient.GetAsync($"{this._TodoListBaseAddress}/api/todolist");
103+
var response = await _httpClient.GetAsync($"{ _TodoListBaseAddress}/api/todolist");
128104
if (response.StatusCode == HttpStatusCode.OK)
129105
{
130106
var content = await response.Content.ReadAsStringAsync();
@@ -138,17 +114,16 @@ public async Task<IEnumerable<Todo>> GetAsync()
138114

139115
private async Task PrepareAuthenticatedClient()
140116
{
141-
var accessToken = await this._tokenAcquisition.GetAccessTokenForUserAsync(new[] { this._TodoListScope });
117+
var accessToken = await _tokenAcquisition.GetAccessTokenForUserAsync(new[] { _TodoListScope });
142118
Debug.WriteLine($"access token-{accessToken}");
143-
this._httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);
144-
this._httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
119+
_httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);
120+
_httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
145121
}
146122

147123
public async Task<Todo> GetAsync(int id)
148124
{
149125
await PrepareAuthenticatedClient();
150-
151-
var response = await this._httpClient.GetAsync($"{this._TodoListBaseAddress}/api/todolist/{id}");
126+
var response = await _httpClient.GetAsync($"{ _TodoListBaseAddress}/api/todolist/{id}");
152127
if (response.StatusCode == HttpStatusCode.OK)
153128
{
154129
var content = await response.Content.ReadAsStringAsync();

4-WebApp-your-API/4-1-MyOrg/Client/Startup.cs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
1-
using Microsoft.AspNetCore.Authorization;
1+
// Copyright (c) Microsoft Corporation. All rights reserved.
2+
// Licensed under the MIT License.
3+
4+
using Microsoft.AspNetCore.Authorization;
25
using Microsoft.AspNetCore.Builder;
36
using Microsoft.AspNetCore.Hosting;
47
using Microsoft.AspNetCore.Http;
@@ -7,7 +10,7 @@
710
using Microsoft.Extensions.DependencyInjection;
811
using Microsoft.Identity.Web;
912
using Microsoft.Identity.Web.TokenCacheProviders.InMemory;
10-
using System.IdentityModel.Tokens.Jwt;
13+
1114
using TodoListClient.Services;
1215
using Microsoft.Extensions.Hosting;
1316
using Microsoft.AspNetCore.Authentication.OpenIdConnect;

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
</ItemGroup>
2323

2424
<ItemGroup>
25+
<PackageReference Include="Microsoft.AspNetCore.DataProtection.Abstractions" Version="3.1.1" />
2526
<PackageReference Include="Microsoft.Graph" Version="1.16.0" />
2627
<PackageReference Include="WindowsAzure.Storage" Version="9.3.3" />
2728
</ItemGroup>

4-WebApp-your-API/4-1-MyOrg/TodoListService/Program.cs

Lines changed: 2 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,5 @@
1-
/*
2-
The MIT License (MIT)
3-
4-
Copyright (c) 2018 Microsoft Corporation
5-
6-
Permission is hereby granted, free of charge, to any person obtaining a copy
7-
of this software and associated documentation files (the "Software"), to deal
8-
in the Software without restriction, including without limitation the rights
9-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10-
copies of the Software, and to permit persons to whom the Software is
11-
furnished to do so, subject to the following conditions:
12-
13-
The above copyright notice and this permission notice shall be included in all
14-
copies or substantial portions of the Software.
15-
16-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22-
SOFTWARE.
23-
*/
1+
// Copyright (c) Microsoft Corporation. All rights reserved.
2+
// Licensed under the MIT License.
243

254
using Microsoft.AspNetCore.Hosting;
265
using Microsoft.Extensions.Hosting;

4-WebApp-your-API/4-1-MyOrg/TodoListService/Startup.cs

Lines changed: 3 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,13 @@
1-
/*
2-
The MIT License (MIT)
3-
4-
Copyright (c) 2018 Microsoft Corporation
5-
6-
Permission is hereby granted, free of charge, to any person obtaining a copy
7-
of this software and associated documentation files (the "Software"), to deal
8-
in the Software without restriction, including without limitation the rights
9-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10-
copies of the Software, and to permit persons to whom the Software is
11-
furnished to do so, subject to the following conditions:
12-
13-
The above copyright notice and this permission notice shall be included in all
14-
copies or substantial portions of the Software.
15-
16-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22-
SOFTWARE.
23-
*/
1+
// Copyright (c) Microsoft Corporation. All rights reserved.
2+
// Licensed under the MIT License.
243

254
using Microsoft.AspNetCore.Builder;
265
using Microsoft.AspNetCore.Hosting;
276
using Microsoft.Extensions.Hosting;
287
using Microsoft.Extensions.Configuration;
298
using Microsoft.Extensions.DependencyInjection;
309
using Microsoft.Identity.Web;
31-
using System.IdentityModel.Tokens.Jwt;
10+
3211
using Microsoft.AspNetCore.Authentication.JwtBearer;
3312

3413
namespace TodoListService
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
using Microsoft.AspNetCore.Authorization;
2+
using Microsoft.AspNetCore.Mvc;
3+
using Microsoft.Identity.Web;
4+
using System.Diagnostics;
5+
using WebApp_OpenIDConnect_DotNet.Models;
6+
7+
namespace WebApp_OpenIDConnect_DotNet.Controllers
8+
{
9+
[Authorize]
10+
public class HomeController : Controller
11+
{
12+
private readonly ITokenAcquisition tokenAcquisition;
13+
14+
public HomeController(ITokenAcquisition tokenAcquisition)
15+
{
16+
this.tokenAcquisition = tokenAcquisition;
17+
}
18+
19+
public IActionResult Index()
20+
{
21+
return View();
22+
}
23+
24+
[AllowAnonymous]
25+
[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
26+
public IActionResult Error()
27+
{
28+
return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });
29+
}
30+
}
31+
}
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
using Microsoft.AspNetCore.Http;
2+
using Microsoft.AspNetCore.Mvc;
3+
using Microsoft.Identity.Web;
4+
using System.Threading.Tasks;
5+
using TodoListClient.Services;
6+
using TodoListService.Models;
7+
8+
namespace TodoListClient.Controllers
9+
{
10+
public class TodoListController : Controller
11+
{
12+
private ITodoListService _todoListService;
13+
14+
public TodoListController(ITodoListService todoListService)
15+
{
16+
_todoListService = todoListService;
17+
}
18+
19+
// GET: TodoList
20+
[AuthorizeForScopes(ScopeKeySection = "TodoList:TodoListScope")]
21+
public async Task<ActionResult> Index()
22+
{
23+
return View(await _todoListService.GetAsync());
24+
}
25+
26+
// GET: TodoList/Details/5
27+
public async Task<ActionResult> Details(int id)
28+
{
29+
return View(await _todoListService.GetAsync(id));
30+
}
31+
32+
// GET: TodoList/Create
33+
public ActionResult Create()
34+
{
35+
Todo todo = new Todo() { Owner = HttpContext.User.Identity.Name };
36+
return View(todo);
37+
}
38+
39+
// POST: TodoList/Create
40+
[HttpPost]
41+
[ValidateAntiForgeryToken]
42+
public async Task<ActionResult> Create([Bind("Title,Owner")] Todo todo)
43+
{
44+
await _todoListService.AddAsync(todo);
45+
return RedirectToAction("Index");
46+
}
47+
48+
// GET: TodoList/Edit/5
49+
public async Task<ActionResult> Edit(int id)
50+
{
51+
Todo todo = await this._todoListService.GetAsync(id);
52+
53+
if (todo == null)
54+
{
55+
return NotFound();
56+
}
57+
58+
return View(todo);
59+
}
60+
61+
// POST: TodoList/Edit/5
62+
[HttpPost]
63+
[ValidateAntiForgeryToken]
64+
public async Task<ActionResult> Edit(int id, [Bind("Id,Title,Owner")] Todo todo)
65+
{
66+
await _todoListService.EditAsync(todo);
67+
return RedirectToAction("Index");
68+
}
69+
70+
// GET: TodoList/Delete/5
71+
public async Task<ActionResult> Delete(int id)
72+
{
73+
Todo todo = await this._todoListService.GetAsync(id);
74+
75+
if (todo == null)
76+
{
77+
return NotFound();
78+
}
79+
80+
return View(todo);
81+
}
82+
83+
// POST: TodoList/Delete/5
84+
[HttpPost]
85+
[ValidateAntiForgeryToken]
86+
public async Task<ActionResult> Delete(int id, [Bind("Id,Title,Owner")] Todo todo)
87+
{
88+
await _todoListService.DeleteAsync(id);
89+
return RedirectToAction("Index");
90+
}
91+
}
92+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
namespace WebApp_OpenIDConnect_DotNet.Infrastructure
2+
{
3+
public static class Constants
4+
{
5+
public const string ScopeUserImpersonation = "user_impersonation";
6+
public const string BearerAuthorizationScheme = "Bearer";
7+
}
8+
}

0 commit comments

Comments
 (0)