Skip to content
This repository was archived by the owner on May 3, 2024. It is now read-only.

Commit 1a22c71

Browse files
committed
responded to comments
1 parent d2c37c1 commit 1a22c71

14 files changed

+195
-285
lines changed

5-AccessControl/1-call-api-roles/API/package-lock.json

-5
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

5-AccessControl/1-call-api-roles/API/package.json

-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@
1313
"express": "^4.14.0",
1414
"lowdb": "^1.0.0",
1515
"morgan": "^1.10.0",
16-
"nanoid": "^3.3.1",
1716
"passport": "^0.6.0",
1817
"passport-azure-ad": "^4.3.3"
1918
},

5-AccessControl/1-call-api-roles/API/utils/guard.js

+39-21
Original file line numberDiff line numberDiff line change
@@ -5,33 +5,51 @@ const routeGuard = (accessMatrix) => {
55
} else {
66
const roles = req.authInfo['roles'];
77

8-
if (req.path.includes(accessMatrix.todolist.path)) {
9-
if (accessMatrix.todolist.methods.includes(req.method)) {
10-
let intersection = accessMatrix.todolist.roles.filter((role) => roles.includes(role));
8+
if (requestHasRequiredAttributes(accessMatrix, req.path, req.method, roles)) {
9+
return res.status(403).json({ error: 'User does not have the role, method or path' });
10+
}
11+
}
12+
next();
13+
};
14+
};
1115

12-
if (intersection.length < 1) {
13-
return res.status(403).json({ error: 'User does not have the role' });
14-
}
15-
} else {
16-
return res.status(403).json({ error: 'Method not allowed' });
17-
}
18-
} else if (req.path.includes(accessMatrix.dashboard.path)) {
19-
if (accessMatrix.dashboard.methods.includes(req.method)) {
20-
let intersection = accessMatrix.dashboard.roles.filter((role) => roles.includes(role));
16+
/**
17+
* This method checks if the request has the correct roles, paths and methods
18+
* @param {Object} accessMatrix
19+
* @param {String} path
20+
* @param {String} method
21+
* @param {Array} roles
22+
* @returns boolean
23+
*/
24+
const requestHasRequiredAttributes = (accessMatrix, path, method, roles) => {
25+
const routes = Object.keys(accessMatrix);
26+
let hasMethod = false;
27+
let hasPath = false;
28+
let hasRoles = false;
29+
routes.forEach((route) => {
30+
if (path.includes(accessMatrix[route].path)) {
31+
hasPath = true;
32+
} else {
33+
hasPath = false;
34+
}
2135

22-
if (intersection.length < 1) {
23-
return res.status(403).json({ error: 'User does not have the role' });
24-
}
25-
} else {
26-
return res.status(403).json({ error: 'Method not allowed' });
27-
}
36+
if (hasPath) {
37+
if (accessMatrix[route].methods.includes(method)) {
38+
hasMethod = true;
2839
} else {
29-
return res.status(403).json({ error: 'Unrecognized path' });
40+
hasMethod = false;
3041
}
3142
}
3243

33-
next();
34-
};
44+
if (hasPath && hasMethod) {
45+
let intersection = accessMatrix[route].roles.filter((role) => roles.includes(role));
46+
if (intersection.length < 1) {
47+
hasRoles = true;
48+
}
49+
}
50+
});
51+
52+
return hasRoles;
3553
};
3654

3755
module.exports = routeGuard;

5-AccessControl/1-call-api-roles/AppCreationScripts/AppCreationScripts.md

+2-3
Original file line numberDiff line numberDiff line change
@@ -139,11 +139,10 @@ The acceptable values for this parameter are:
139139
- AzureCloud
140140
- AzureChinaCloud
141141
- AzureUSGovernment
142-
- AzureGermanyCloud
143142

144143
Example:
145144

146145
```PowerShell
147-
. .\Cleanup.ps1 -AzureEnvironmentName "AzureGermanyCloud"
148-
. .\Configure.ps1 -AzureEnvironmentName "AzureGermanyCloud"
146+
. .\Cleanup.ps1 -AzureEnvironmentName "AzureUSGovernment"
147+
. .\Configure.ps1 -AzureEnvironmentName "AzureUSGovernment"
149148
```

5-AccessControl/1-call-api-roles/AppCreationScripts/Cleanup.ps1

-1
Original file line numberDiff line numberDiff line change
@@ -81,4 +81,3 @@ Cleanup -tenantId $tenantId -environment $azureEnvironmentName
8181

8282
Write-Host "Disconnecting from tenant"
8383
Disconnect-MgGraph
84-

5-AccessControl/1-call-api-roles/AppCreationScripts/CleanupUsersAndAssignRoles.ps1

+9-14
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,11 @@ param(
77
[string] $azureEnvironmentName
88
)
99

10-
1110
Function RemoveUser([string]$userPrincipal)
1211
{
1312
Remove-MgUser -UserId $userPrincipal
1413
}
1514

16-
1715
Function CleanupRolesUsersAndRoleAssignments
1816
{
1917
if (!$azureEnvironmentName)
@@ -25,12 +23,12 @@ Function CleanupRolesUsersAndRoleAssignments
2523

2624
if ($tenantId -eq "")
2725
{
28-
Connect-MgGraph -Scopes "Application.ReadWrite.All" -Environment $azureEnvironmentName
26+
Connect-MgGraph -Scopes "Application.ReadWrite.All User.ReadWrite.All" -Environment $azureEnvironmentName
2927
$tenantId = (Get-MgContext).TenantId
3028
}
3129
else
3230
{
33-
Connect-MgGraph -TenantId $tenantId -Scopes "Application.ReadWrite.All" -Environment $azureEnvironmentName
31+
Connect-MgGraph -TenantId $tenantId -Scopes "Application.ReadWrite.All User.ReadWrite.All" -Environment $azureEnvironmentName
3432
}
3533

3634

@@ -42,28 +40,25 @@ Function CleanupRolesUsersAndRoleAssignments
4240
if ($app)
4341
{
4442
$appName = $app.DisplayName
45-
4643
$userEmail = $appName +"-" + "TaskAdmin" + "@" + $tenantName
4744
RemoveUser -userPrincipal $userEmail
4845
Write-Host "user name ($userEmail)"
49-
50-
5146
$userEmail = $appName +"-" + "TaskUser" + "@" + $tenantName
5247
RemoveUser -userPrincipal $userEmail
5348
Write-Host "user name ($userEmail)"
54-
55-
5649
}
57-
58-
59-
60-
6150
}
6251

52+
if ($null -eq (Get-Module -ListAvailable -Name "Microsoft.Graph.Applications")) {
53+
Install-Module "Microsoft.Graph.Applications" -Scope CurrentUser
54+
}
6355

56+
Import-Module Microsoft.Graph.Applications
6457

58+
if ($null -eq (Get-Module -ListAvailable -Name "Microsoft.Graph.Users")) {
59+
Install-Module "Microsoft.Graph.Users" -Scope CurrentUser
60+
}
6561

66-
Import-Module Microsoft.Graph.Applications
6762
Import-Module Microsoft.Graph.Users
6863

6964
# Run interactively (will ask you for the tenant ID)

5-AccessControl/1-call-api-roles/AppCreationScripts/Configure.ps1

+4-44
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
1+
22
[CmdletBinding()]
33
param(
44
[Parameter(Mandatory=$False, HelpMessage='Tenant ID (This is a GUID which represents the "Directory ID" of the AzureAD tenant into which you want to create the apps')]
@@ -171,22 +171,11 @@ Function CreateAppRole([string] $types, [string] $name, [string] $description)
171171
$appRole.Value = $name;
172172
return $appRole
173173
}
174-
Function CreateOptionalClaim([string] $name)
175-
{
176-
<#.Description
177-
This function creates a new Azure AD optional claims with default and provided values
178-
#>
179-
180-
$appClaim = New-Object Microsoft.Graph.PowerShell.Models.MicrosoftGraphOptionalClaim
181-
$appClaim.AdditionalProperties = New-Object System.Collections.Generic.List[string]
182-
$appClaim.Source = $null
183-
$appClaim.Essential = $false
184-
$appClaim.Name = $name
185-
return $appClaim
186-
}
187174

188175
Function ConfigureApplications
189176
{
177+
$isOpenSSl = 'N' #temporary disable open certificate creation
178+
190179
<#.Description
191180
This function creates the Azure AD applications for the sample in the provided Azure AD tenant and updates the
192181
configuration files in the client and service project of the visual studio solution (App.Config and Web.Config)
@@ -238,28 +227,6 @@ Function ConfigureApplications
238227
New-MgApplicationOwnerByRef -ApplicationId $clientAadApplication.Id -BodyParameter = @{"@odata.id" = "htps://graph.microsoft.com/v1.0/directoryObjects/$user.ObjectId"}
239228
Write-Host "'$($user.UserPrincipalName)' added as an application owner to app '$($clientServicePrincipal.DisplayName)'"
240229
}
241-
242-
# Add Claims
243-
244-
$optionalClaims = New-Object Microsoft.Graph.PowerShell.Models.MicrosoftGraphOptionalClaims
245-
$optionalClaims.AccessToken = New-Object System.Collections.Generic.List[Microsoft.Graph.PowerShell.Models.MicrosoftGraphOptionalClaim]
246-
$optionalClaims.IdToken = New-Object System.Collections.Generic.List[Microsoft.Graph.PowerShell.Models.MicrosoftGraphOptionalClaim]
247-
$optionalClaims.Saml2Token = New-Object System.Collections.Generic.List[Microsoft.Graph.PowerShell.Models.MicrosoftGraphOptionalClaim]
248-
249-
250-
# Add Optional Claims
251-
252-
$newClaim = CreateOptionalClaim -name "sid"
253-
$optionalClaims.IdToken += ($newClaim)
254-
$newClaim = CreateOptionalClaim -name "login_hint"
255-
$optionalClaims.IdToken += ($newClaim)
256-
$newClaim = CreateOptionalClaim -name "email"
257-
$optionalClaims.IdToken += ($newClaim)
258-
$newClaim = CreateOptionalClaim -name "upn"
259-
$optionalClaims.IdToken += ($newClaim)
260-
$newClaim = CreateOptionalClaim -name "acct"
261-
$optionalClaims.IdToken += ($newClaim)
262-
Update-MgApplication -ApplicationId $clientAadApplication.Id -OptionalClaims $optionalClaims
263230

264231
# Add application Roles
265232
$appRoles = New-Object System.Collections.Generic.List[Microsoft.Graph.PowerShell.Models.MicrosoftGraphAppRole]
@@ -323,13 +290,6 @@ Function ConfigureApplications
323290
$requiredResourcesAccess.Add($requiredPermissions)
324291
Update-MgApplication -ApplicationId $clientAadApplication.Id -RequiredResourceAccess $requiredResourcesAccess
325292
Write-Host "Granted permissions."
326-
327-
# Configure known client applications for client
328-
Write-Host "Configure known client applications for the 'client'"
329-
$knowApplications = New-Object System.Collections.Generic.List[System.String]
330-
$knowApplications.Add($clientAadApplication.AppId)
331-
Update-MgApplication -ApplicationId $clientAadApplication.Id -Api @{KnownClientApplications = $knowApplications}
332-
Write-Host "Configured."
333293

334294
# Update config file for 'client'
335295
$configFile = $pwd.Path + "\..\API\authConfig.js"
@@ -351,7 +311,7 @@ Function ConfigureApplications
351311
Write-Host "- For client"
352312
Write-Host " - Navigate to $clientPortalUrl"
353313
Write-Host " - To receive the 'roles' claim with the name of the app roles this user is assigned to, make sure that the user accounts you plan to sign-in to this app is assigned to the app roles of this SPA app. The guide, https://aka.ms/userassignmentrequired provides step by step instructions." -ForegroundColor Red
354-
Write-Host " - Or you can run the ..\CreateUsersAndAssignRoles.ps1 command to automatically create a number of users, and assign these users to the app roles of this app." -ForegroundColor Red
314+
Write-Host " - Or you can run the .\CreateUsersAndAssignRoles.ps1 command to automatically create a number of users, and assign these users to the app roles of this app." -ForegroundColor Red
355315
Write-Host " - Application 'client' publishes app roles . Do remember to navigate to the app registration in the app portal and assign users to these app roles" -ForegroundColor Red
356316
Write-Host -ForegroundColor Green "------------------------------------------------------------------------------------------------"
357317
if($isOpenSSL -eq 'Y')

5-AccessControl/1-call-api-roles/AppCreationScripts/CreateUsersAndAssignRoles.ps1

+13-17
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ param(
77
[string] $azureEnvironmentName
88
)
99

10-
1110
Function Get-RandomPassword {
1211
param (
1312
[Parameter(Mandatory)]
@@ -53,7 +52,6 @@ Function Get-RandomPassword {
5352
return $password
5453
}
5554

56-
5755
Function CreateUser([string] $appName, $role, [string] $tenantName)
5856
{
5957
$displayName = $appName +"-" + $role.Value
@@ -65,24 +63,18 @@ Function CreateUser([string] $appName, $role, [string] $tenantName)
6563
Password = $password
6664
}
6765

68-
69-
70-
71-
7266
$user = Get-MgUser -Filter "UserPrincipalName eq '$($userEmail)'"
7367

7468
if(!$user)
7569
{
76-
$user = New-MgUser -DisplayName $displayName -PasswordProfile $PasswordProfile -AccountEnabled -MailNickName $nickName -UserPrincipalName $userEmail
77-
Write-Host "Email: is "($user.UserPrincipalName)" and password is $password"
78-
70+
$user = New-MgUser -DisplayName $displayName -PasswordProfile $PasswordProfile -AccountEnabled -MailNickName $nickName -UserPrincipalName $userEmail
71+
Write-Host "Email: is "($user.UserPrincipalName)" and password is $password"
7972
}
8073
else
8174
{
8275
Write-Host "Email: "($user.UserPrincipalName)" already exists"
8376
}
8477

85-
8678
return $user
8779
}
8880

@@ -94,16 +86,16 @@ Function CreateRolesUsersAndRoleAssignments
9486
$azureEnvironmentName = "Global"
9587
}
9688

97-
Write-Host "Connecting to Microsoft Graph"
89+
Write-Host "Connecting to Microsoft Graph"
9890

9991
if ($tenantId -eq "")
10092
{
101-
Connect-MgGraph -Scopes "Application.ReadWrite.All" -Environment $azureEnvironmentName
93+
Connect-MgGraph -Scopes "Application.ReadWrite.All User.ReadWrite.All" -Environment $azureEnvironmentName
10294
$tenantId = (Get-MgContext).TenantId
10395
}
10496
else
10597
{
106-
Connect-MgGraph -TenantId $tenantId -Scopes "Application.ReadWrite.All" -Environment $azureEnvironmentName
98+
Connect-MgGraph -TenantId $tenantId -Scopes "Application.ReadWrite.All User.ReadWrite.All" -Environment $azureEnvironmentName
10799
}
108100

109101
$userAccount = (Get-MgContext).Account
@@ -118,25 +110,29 @@ Function CreateRolesUsersAndRoleAssignments
118110
$servicePrincipal = Get-MgServicePrincipal -Filter "AppId eq '$($app.AppId)'"
119111
$appName = $app.DisplayName
120112

121-
122113
$TaskAdmin = $servicePrincipal.AppRoles | Where-Object { $_.DisplayName -eq "TaskAdmin" }
123114
# Creating a user
124115
$newUser = CreateUser -appName $appName -role $TaskAdmin -tenantName $tenantName
125116
$assignRole = New-MgUserAppRoleAssignment -Userid $newUser.Id -PrincipalId $newUser.Id -ResourceId $servicePrincipal.Id -AppRoleID $TaskAdmin.Id
126117

127-
128118
$TaskUser = $servicePrincipal.AppRoles | Where-Object { $_.DisplayName -eq "TaskUser" }
129119
# Creating a user
130120
$newUser = CreateUser -appName $appName -role $TaskUser -tenantName $tenantName
131121
$assignRole = New-MgUserAppRoleAssignment -Userid $newUser.Id -PrincipalId $newUser.Id -ResourceId $servicePrincipal.Id -AppRoleID $TaskUser.Id
132122

133-
134123
}
124+
}
135125

136-
126+
if ($null -eq (Get-Module -ListAvailable -Name "Microsoft.Graph.Applications")) {
127+
Install-Module "Microsoft.Graph.Applications" -Scope CurrentUser
137128
}
138129

139130
Import-Module Microsoft.Graph.Applications
131+
132+
if ($null -eq (Get-Module -ListAvailable -Name "Microsoft.Graph.Users")) {
133+
Install-Module "Microsoft.Graph.Users" -Scope CurrentUser
134+
}
135+
140136
Import-Module Microsoft.Graph.Users
141137

142138
# Run interactively (will ask you for the tenant ID)

5-AccessControl/1-call-api-roles/AppCreationScripts/sample.json

+2-9
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,7 @@
88
"Endpoint": "AAD v2.0",
99
"Languages": ["JavaScript", "Node"],
1010
"Description": "React single-page application calling a protected web API using App Roles to implement Role-Based Access Control",
11-
"products": ["React", "Express"]
12-
},
13-
"ReadmeScenario": {
14-
"UseNewSetup": "1",
15-
"CertificateOption": "0"
11+
"products": ["React", "Express", "azure-active-directory", "msal-js", "passport-azure-ad"]
1612
},
1713
"AADApps": [
1814
{
@@ -45,15 +41,12 @@
4541
"Description": "Users can read and modify their todo lists"
4642
}
4743
],
48-
"OptionalClaims": {
49-
"IdTokenClaims": ["sid", "login_hint", "email", "upn", "acct"]
50-
},
5144
"ManualSteps": [
5245
{
5346
"Comment": "To receive the 'roles' claim with the name of the app roles this user is assigned to, make sure that the user accounts you plan to sign-in to this app is assigned to the app roles of this SPA app. The guide, https://aka.ms/userassignmentrequired provides step by step instructions."
5447
},
5548
{
56-
"Comment": "Or you can run the ..\\CreateUsersAndAssignRoles.ps1 command to automatically create a number of users, and assign these users to the app roles of this app."
49+
"Comment": "Or you can run the .\\CreateUsersAndAssignRoles.ps1 command to automatically create a number of users, and assign these users to the app roles of this app."
5750
}
5851
]
5952
}

0 commit comments

Comments
 (0)