Skip to content

Commit fd8ba1a

Browse files
committed
changed to getting Owner as Object Id
1 parent 3b794e6 commit fd8ba1a

File tree

4 files changed

+62
-41
lines changed

4 files changed

+62
-41
lines changed

4-WebApp-your-API/4-1-MyOrg/AppCreationScripts/Configure.ps1

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,14 @@ Function ConfigureApplications
205205
Write-Host "'$($user.UserPrincipalName)' added as an application owner to app '$($serviceServicePrincipal.DisplayName)'"
206206
}
207207

208+
# Add application permissions/user roles
209+
$appRoles = New-Object System.Collections.Generic.List[Microsoft.Graph.PowerShell.Models.MicrosoftGraphAppRole]
210+
$newRole = CreateAppRole -types "Application" -name "ToDoList.Read.All" -description "Application can only read ToDo list"
211+
$appRoles.Add($newRole)
212+
$newRole = CreateAppRole -types "Application" -name "ToDoList.ReadWrite.All" -description "Application can read and write into ToDo list"
213+
$appRoles.Add($newRole)
214+
Update-MgApplication -ApplicationId $serviceAadApplication.Id -AppRoles $appRoles
215+
208216
# rename the user_impersonation scope if it exists to match the readme steps or add a new scope
209217

210218
# delete default scope i.e. User_impersonation
@@ -231,7 +239,7 @@ Function ConfigureApplications
231239
-adminConsentDescription "Allow the app TodoListService-aspnetcore-webapi to [ex, read ToDo list items]"
232240

233241
$scopes.Add($scope)
234-
$scope = CreateScope -value ToDoList.Write `
242+
$scope = CreateScope -value ToDoList.ReadWrite `
235243
-userConsentDisplayName "Access TodoListService-aspnetcore-webapi" `
236244
-userConsentDescription "Allow the application to access TodoListService-aspnetcore-webapi on your behalf." `
237245
-adminConsentDisplayName "Access TodoListService-aspnetcore-webapi" `
@@ -262,6 +270,9 @@ Function ConfigureApplications
262270
RedirectUris = "https://localhost:44321/", "https://localhost:44321/signin-oidc"; `
263271
HomePageUrl = "https://localhost:44321/"; `
264272
LogoutUrl = "https://localhost:44321/signout-oidc"; `
273+
ImplicitGrantSettings = @{ `
274+
EnableAccessTokenIssuance=$true; `
275+
} `
265276
} `
266277
-SignInAudience AzureADMyOrg `
267278
#end of command
@@ -294,7 +305,7 @@ Function ConfigureApplications
294305
# Add Required Resources Access (from 'client' to 'service')
295306
Write-Host "Getting access from 'client' to 'service'"
296307
$requiredPermissions = GetRequiredPermissions -applicationDisplayName "TodoListService-aspnetcore-webapi" `
297-
-requiredDelegatedPermissions "ToDoList.Read|ToDoList.Write" `
308+
-requiredDelegatedPermissions "ToDoList.Read|ToDoList.ReadWrite" `
298309

299310

300311
$requiredResourcesAccess.Add($requiredPermissions)
@@ -311,7 +322,7 @@ Function ConfigureApplications
311322

312323
# Update config file for 'client'
313324
$configFile = $pwd.Path + "\..\Client\appsettings.json"
314-
$dictionary = @{ "Domain" = $tenantName;"TenantId" = $tenantId;"ClientId" = $clientAadApplication.AppId;"ClientSecret" = $pwdCredential.SecretText;"TodoListScopes" = "api://$($serviceAadApplication.AppId)/ToDoList.Read api://$($serviceAadApplication.AppId)/ToDoList.Write";"TodoListBaseAddress" = $serviceAadApplication.Web.HomePageUrl };
325+
$dictionary = @{ "Domain" = $tenantName;"TenantId" = $tenantId;"ClientId" = $clientAadApplication.AppId;"ClientSecret" = $pwdCredential.SecretText;"TodoListScopes" = "api://$($serviceAadApplication.AppId)/ToDoList.Read api://$($serviceAadApplication.AppId)/ToDoList.ReadWrite";"TodoListBaseAddress" = $serviceAadApplication.Web.HomePageUrl };
315326

316327
Write-Host "Updating the sample code ($configFile)"
317328

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

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -94,19 +94,19 @@
9494
"SampleSubPath": "4-WebApp-Your-API\\4-1-MyOrg",
9595
"ProjectDirectory": "\\TodoListService"
9696
},
97-
"Scopes": [ "ToDoList.Read", "ToDoList.ReadWrite" ]
98-
//"AppRoles": [
99-
// {
100-
// "Types": [ "Application" ],
101-
// "Name": "ToDoList.Read.All",
102-
// "Description": "Application can only read ToDo list"
103-
// },
104-
// {
105-
// "Types": [ "Application" ],
106-
// "Name": "ToDoList.ReadWrite.All",
107-
// "Description": "Application can read and write into ToDo list"
108-
// }
109-
//]
97+
"Scopes": [ "ToDoList.Read", "ToDoList.ReadWrite" ],
98+
"AppRoles": [
99+
{
100+
"Types": [ "Application" ],
101+
"Name": "ToDoList.Read.All",
102+
"Description": "Application can only read ToDo list"
103+
},
104+
{
105+
"Types": [ "Application" ],
106+
"Name": "ToDoList.ReadWrite.All",
107+
"Description": "Application can read and write into ToDo list"
108+
}
109+
]
110110
},
111111
{
112112
"Id": "client",
@@ -120,7 +120,7 @@
120120
"RequiredResourcesAccess": [
121121
{
122122
"Resource": "service",
123-
"DelegatedPermissions": [ "ToDoList.Read", "ToDoList.Write" ]
123+
"DelegatedPermissions": [ "ToDoList.Read", "ToDoList.ReadWrite" ]
124124
}
125125
],
126126
"ManualSteps": [],

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

Lines changed: 31 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
using Microsoft.AspNetCore.Authorization;
55
using Microsoft.AspNetCore.Http;
66
using Microsoft.AspNetCore.Mvc;
7+
using Microsoft.Identity.Web;
78
using Microsoft.Identity.Web.Resource;
89
using System;
910
using System.Collections.Generic;
@@ -30,8 +31,8 @@ public TodoListController(IHttpContextAccessor contextAccessor)
3031
// Pre-populate with sample data
3132
if (TodoStore.Count == 0)
3233
{
33-
TodoStore.Add(1, new Todo() { Id = 1, Owner = $"{_contextAccessor.HttpContext.User.Identity.Name}", Title = "Pick up groceries" });
34-
TodoStore.Add(2, new Todo() { Id = 2, Owner = $"{_contextAccessor.HttpContext.User.Identity.Name}", Title = "Finish invoice report" });
34+
TodoStore.Add(1, new Todo() { Id = 1, Owner = $"{GetObjectIdClaim(_contextAccessor.HttpContext.User)}", Title = "Pick up groceries" });
35+
TodoStore.Add(2, new Todo() { Id = 2, Owner = $"{GetObjectIdClaim(_contextAccessor.HttpContext.User)}", Title = "Finish invoice report" });
3536
TodoStore.Add(3, new Todo() { Id = 3, Owner = "Other User", Title = "Rent a car" });
3637
TodoStore.Add(4, new Todo() { Id = 4, Owner = "Other User", Title = "Get vaccinated" });
3738
}
@@ -45,11 +46,11 @@ public TodoListController(IHttpContextAccessor contextAccessor)
4546
)]
4647
public IEnumerable<Todo> Get()
4748
{
48-
if (IsInScopes(new string[] { "ToDoList.Read", "ToDoList.ReadWrite" }))
49+
if (HasDelegatedPermissions(new string[] { "ToDoList.Read", "ToDoList.ReadWrite" }))
4950
{
50-
return TodoStore.Values.Where(x => x.Owner == User.Identity.Name);
51+
return TodoStore.Values.Where(x => x.Owner == GetObjectIdClaim(User));
5152
}
52-
else if (IsInPermissions(new string[] { "ToDoList.Read.All", "ToDoList.ReadWrite.All" }))
53+
else if (HasApplicationPermissions(new string[] { "ToDoList.Read.All", "ToDoList.ReadWrite.All" }))
5354
{
5455
return TodoStore.Values;
5556
}
@@ -68,11 +69,11 @@ public Todo Get(int id)
6869
//then it will be t.id==id && x.Owner == owner
6970
//if it has app permissions the it will return t.id==id
7071

71-
if (IsInScopes(new string[] { "ToDoList.Read", "ToDoList.ReadWrite" }))
72+
if (HasDelegatedPermissions(new string[] { "ToDoList.Read", "ToDoList.ReadWrite" }))
7273
{
73-
return TodoStore.Values.FirstOrDefault(t => t.Id == id && t.Owner == User.Identity.Name);
74+
return TodoStore.Values.FirstOrDefault(t => t.Id == id && t.Owner == GetObjectIdClaim(User));
7475
}
75-
else if (IsInPermissions(new string[] { "ToDoList.Read.All", "ToDoList.ReadWrite.All" }))
76+
else if (HasApplicationPermissions(new string[] { "ToDoList.Read.All", "ToDoList.ReadWrite.All" }))
7677
{
7778
return TodoStore.Values.FirstOrDefault(t => t.Id == id);
7879
}
@@ -90,11 +91,11 @@ public void Delete(int id)
9091
if (
9192
(
9293

93-
IsInScopes(new string[] { "ToDoList.ReadWrite" }) && TodoStore.Values.Any(x => x.Id == id && x.Owner == User.Identity.Name))
94+
HasDelegatedPermissions(new string[] { "ToDoList.ReadWrite" }) && TodoStore.Values.Any(x => x.Id == id && x.Owner == GetObjectIdClaim(User)))
9495

9596
||
9697

97-
IsInPermissions(new string[] { "ToDoList.ReadWrite.All" })
98+
HasApplicationPermissions(new string[] { "ToDoList.ReadWrite.All" })
9899
)
99100
{
100101
TodoStore.Remove(id);
@@ -113,9 +114,9 @@ public void Delete(int id)
113114
AcceptedAppPermission = new string[] { "ToDoList.ReadWrite.All" })]
114115
public IActionResult Post([FromBody] Todo todo)
115116
{
116-
var owner = HttpContext.User.Identity.Name;
117+
var owner = GetObjectIdClaim(User);
117118

118-
if (IsInPermissions(new string[] { "ToDoList.ReadWrite.All" }))
119+
if (HasApplicationPermissions(new string[] { "ToDoList.ReadWrite.All" }))
119120
{
120121
//with such a permission any owner name is accepted from UI
121122
owner = todo.Owner;
@@ -141,13 +142,13 @@ public IActionResult Patch(int id, [FromBody] Todo todo)
141142
}
142143

143144
if (
144-
IsInScopes(new string[] { "ToDoList.ReadWrite" })
145-
&& TodoStore.Values.Any(x => x.Id == id && x.Owner == User.Identity.Name)
146-
&& todo.Owner == User.Identity.Name
145+
HasDelegatedPermissions(new string[] { "ToDoList.ReadWrite" })
146+
&& TodoStore.Values.Any(x => x.Id == id && x.Owner == GetObjectIdClaim(User))
147+
&& todo.Owner == GetObjectIdClaim(User)
147148

148149
||
149150

150-
IsInPermissions(new string[] { "ToDoList.ReadWrite.All" })
151+
HasApplicationPermissions(new string[] { "ToDoList.ReadWrite.All" })
151152

152153
)
153154
{
@@ -162,21 +163,29 @@ public IActionResult Patch(int id, [FromBody] Todo todo)
162163
}
163164

164165
//check if the permission is inside claims
165-
private bool IsInPermissions(string[] permissionsNames)
166+
private bool HasApplicationPermissions(string[] permissionsNames)
166167
{
167-
var result = User.Claims.Where(c => c.Type.Equals(ClaimTypes.Role)).FirstOrDefault()?
168-
.Value.Split(' ').Any(v => permissionsNames.Any(p => p.Equals(v)));
168+
var rolesClaim = User.Claims.Where(
169+
c => c.Type == ClaimConstants.Roles || c.Type == ClaimConstants.Role)
170+
.SelectMany(c => c.Value.Split(' '));
169171

170-
return result ?? false;
172+
var result = rolesClaim.Any(v => permissionsNames.Any(p => p.Equals(v)));
173+
174+
return result;
171175
}
172176

173177
//check if the scope is inside claims
174-
private bool IsInScopes(string[] scopesNames)
178+
private bool HasDelegatedPermissions(string[] scopesNames)
175179
{
176-
var result = User.Claims.Where(c => c.Type.Equals(Constants.ScopeClaimType)).FirstOrDefault()?
180+
var result = (User.FindFirst(ClaimConstants.Scp) ?? User.FindFirst(ClaimConstants.Scope))?
177181
.Value.Split(' ').Any(v => scopesNames.Any(s => s.Equals(v)));
178182

179183
return result ?? false;
180184
}
185+
186+
private string GetObjectIdClaim(ClaimsPrincipal user)
187+
{
188+
return (user.FindFirst(ClaimConstants.Oid) ?? user.FindFirst(ClaimConstants.ObjectId))?.Value;
189+
}
181190
}
182191
}

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

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
using Microsoft.Extensions.Configuration;
88
using Microsoft.Extensions.DependencyInjection;
99
using Microsoft.Identity.Web;
10+
using System.IdentityModel.Tokens.Jwt;
1011

1112
namespace TodoListService
1213
{
@@ -26,7 +27,7 @@ public void ConfigureServices(IServiceCollection services)
2627
// By default, the claims mapping will map claim names in the old format to accommodate older SAML applications.
2728
// 'http://schemas.microsoft.com/ws/2008/06/identity/claims/role' instead of 'roles'
2829
// This flag ensures that the ClaimsIdentity claims collection will be built from the claims in the token
29-
// JwtSecurityTokenHandler.DefaultMapInboundClaims = false;
30+
JwtSecurityTokenHandler.DefaultMapInboundClaims = false;
3031

3132
// Adds Microsoft Identity platform (AAD v2.0) support to protect this Api
3233
services.AddMicrosoftIdentityWebApiAuthentication(Configuration);
@@ -51,7 +52,7 @@ public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
5152
}
5253

5354
app.UseHttpsRedirection();
54-
55+
5556
app.UseRouting();
5657
app.UseAuthentication();
5758
app.UseAuthorization();

0 commit comments

Comments
 (0)