Skip to content

Commit e34d164

Browse files
committed
Adding application creation scripts which create the Azure AD applications, and update the config files in the C# projects to match the application coordinates.
1 parent 6dbff12 commit e34d164

File tree

3 files changed

+306
-0
lines changed

3 files changed

+306
-0
lines changed

AppCreationScripts/Cleanup.ps1

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
param([Parameter(Mandatory=$false)][PSCredential]$Credential=$null, [Parameter(Mandatory=$false)][string]$TenantId)
2+
Import-Module AzureAD
3+
$ErrorActionPreference = 'Stop'
4+
5+
Function Cleanup
6+
{
7+
<#
8+
.Description
9+
This function removes the Azure AD applications for the sample. These applications were created by the Configure.ps1 script
10+
#>
11+
[CmdletBinding()]
12+
param(
13+
[Parameter(HelpMessage='Tenant ID (This is a GUID which represents the "Directory ID" of the AzureAD tenant into which you want to create the apps')]
14+
[PSCredential] $Credential,
15+
[string] $tenantId
16+
)
17+
18+
process
19+
{
20+
# $tenantId is the Active Directory Tenant. This is a GUID which represents the "Directory ID" of the AzureAD tenant
21+
# into which you want to create the apps. Look it up in the Azure portal in the "Properties" of the Azure AD.
22+
23+
# Login to Azure PowerShell (interactive if credentials are not already provided:
24+
# you'll need to sign-in with creds enabling your to create apps in the tenant)
25+
if (!$Credential -and $TenantId)
26+
{
27+
$creds = Connect-AzureAD -TenantId $tenantId
28+
}
29+
else
30+
{
31+
if (!$TenantId)
32+
{
33+
$creds = Connect-AzureAD -Credential $Credential
34+
}
35+
else
36+
{
37+
$creds = Connect-AzureAD -TenantId $tenantId -Credential $Credential
38+
}
39+
}
40+
41+
if (!$tenantId)
42+
{
43+
$tenantId = $creds.Tenant.Id
44+
}
45+
$tenant = Get-AzureADTenantDetail
46+
$tenantName = ($tenant.VerifiedDomains | Where { $_._Default -eq $True }).Name
47+
48+
# Removes the applications
49+
Write-Host "Cleaning-up applications from tenant '$tenantName'"
50+
51+
Write-Host "Removing 'service' (TodoListService-ManualJwt) if needed"
52+
$app=Get-AzureADApplication -Filter "identifierUris/any(uri:uri eq 'https://$tenantName/TodoListService-ManualJwt')"
53+
if ($app)
54+
{
55+
Remove-AzureADApplication -ObjectId $app.ObjectId
56+
Write-Host "Removed."
57+
}
58+
59+
Write-Host "Removing 'client' (TodoListClient-ManualJwt) if needed"
60+
$app=Get-AzureADApplication -Filter "DisplayName eq 'TodoListClient-ManualJwt'"
61+
if ($app)
62+
{
63+
Remove-AzureADApplication -ObjectId $app.ObjectId
64+
Write-Host "Removed."
65+
}
66+
67+
}
68+
}
69+
70+
Cleanup -Credential $Credential -tenantId $TenantId

AppCreationScripts/Configure.ps1

Lines changed: 160 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,160 @@
1+
# Adds the requiredAccesses (expressed as a pipe separated string) to the requiredAccess structure
2+
# The exposed permissions are in the $exposedPermissions collection, and the type of permission (Scope | Role) is
3+
# described in $permissionType
4+
Function AddResourcePermission($requiredAccess, `
5+
$exposedPermissions, [string]$requiredAccesses, [string]$permissionType)
6+
{
7+
foreach($permission in $requiredAccesses.Trim().Split("|"))
8+
{
9+
foreach($exposedPermission in $exposedPermissions)
10+
{
11+
if ($exposedPermission.Value -eq $permission)
12+
{
13+
$resourceAccess = New-Object Microsoft.Open.AzureAD.Model.ResourceAccess
14+
$resourceAccess.Type = $permissionType # Scope = Delegated permissions | Role = Application permissions
15+
$resourceAccess.Id = $exposedPermission.Id # Read directory data
16+
$requiredAccess.ResourceAccess.Add($resourceAccess)
17+
}
18+
}
19+
}
20+
}
21+
22+
#
23+
# Exemple: GetRequiredPermissions "Microsoft Graph" "Graph.Read|User.Read"
24+
# See also: http://stackoverflow.com/questions/42164581/how-to-configure-a-new-azure-ad-application-through-powershell
25+
Function GetRequiredPermissions([string] $applicationDisplayName, [string] $requiredDelegatedPermissions, [string]$requiredApplicationPermissions, $servicePrincipal)
26+
{
27+
# If we are passed the service principal we use it directly, otherwise we find it from the display name (which might not be unique)
28+
if ($servicePrincipal)
29+
{
30+
$sp = $servicePrincipal
31+
}
32+
else
33+
{
34+
$sp = Get-AzureADServicePrincipal -Filter "DisplayName eq '$applicationDisplayName'"
35+
}
36+
$appid = $sp.AppId
37+
$requiredAccess = New-Object Microsoft.Open.AzureAD.Model.RequiredResourceAccess
38+
$requiredAccess.ResourceAppId = $appid
39+
$requiredAccess.ResourceAccess = New-Object System.Collections.Generic.List[Microsoft.Open.AzureAD.Model.ResourceAccess]
40+
41+
# $sp.Oauth2Permissions | Select Id,AdminConsentDisplayName,Value: To see the list of all the Delegated permissions for the application:
42+
if ($requiredDelegatedPermissions)
43+
{
44+
AddResourcePermission $requiredAccess -exposedPermissions $sp.Oauth2Permissions -requiredAccesses $requiredDelegatedPermissions -permissionType "Scope"
45+
}
46+
47+
# $sp.AppRoles | Select Id,AdminConsentDisplayName,Value: To see the list of all the Application permissions for the application
48+
if ($requiredDelegatedPermissions)
49+
{
50+
AddResourcePermission $requiredAccess -exposedPermissions $sp.AppRoles -requiredAccesses $requiredApplicationPermissions -permissionType "Role"
51+
}
52+
return $requiredAccess
53+
}
54+
55+
# Replace the value of an appsettings of a given key in an XML App.Config file.
56+
Function ReplaceSetting([string] $configFilePath, [string] $key, [string] $newValue)
57+
{
58+
[xml] $content = Get-Content $configFilePath
59+
$appSettings = $content.configuration.appSettings;
60+
$keyValuePair = $appSettings.SelectSingleNode("descendant::add[@key='$key']")
61+
if ($keyValuePair)
62+
{
63+
$keyValuePair.value = $newValue;
64+
}
65+
else
66+
{
67+
Throw "Key '$key' not found in file '$configFilePath'"
68+
}
69+
$content.save($configFilePath)
70+
}
71+
72+
Function ConfigureApplications
73+
{
74+
<#.Description
75+
This function creates the Azure AD applications for the sample in the provided Azure AD tenant and updates the
76+
configuration files in the client and service project of the visual studio solution (App.Config and Web.Config)
77+
so that they are consistent with the Applications parameters
78+
#>
79+
[CmdletBinding()]
80+
param(
81+
[PSCredential] $Credential,
82+
[Parameter(HelpMessage='Tenant ID (This is a GUID which represents the "Directory ID" of the AzureAD tenant into which you want to create the apps')]
83+
[string] $tenantId
84+
)
85+
86+
process
87+
{
88+
# $tenantId is the Active Directory Tenant. This is a GUID which represents the "Directory ID" of the AzureAD tenant
89+
# into which you want to create the apps. Look it up in the Azure portal in the "Properties" of the Azure AD.
90+
91+
# Login to Azure PowerShell (interactive if credentials are not already provided:
92+
# you'll need to sign-in with creds enabling your to create apps in the tenant)
93+
if (!$Credential -and $TenantId)
94+
{
95+
$creds = Connect-AzureAD -TenantId $tenantId
96+
}
97+
else
98+
{
99+
if (!$TenantId)
100+
{
101+
$creds = Connect-AzureAD -Credential $Credential
102+
}
103+
else
104+
{
105+
$creds = Connect-AzureAD -TenantId $tenantId -Credential $Credential
106+
}
107+
}
108+
109+
if (!$tenantId)
110+
{
111+
$tenantId = $creds.Tenant.Id
112+
}
113+
$tenant = Get-AzureADTenantDetail
114+
$tenantName = ($tenant.VerifiedDomains | Where { $_._Default -eq $True }).Name
115+
116+
# Create the service AAD application
117+
Write-Host "Creating the AAD appplication (TodoListService-ManualJwt)"
118+
$serviceAadApplication = New-AzureADApplication -DisplayName "TodoListService-ManualJwt" `
119+
-HomePage "https://localhost:44324" `
120+
-IdentifierUris "https://$tenantName/TodoListService-ManualJwt" `
121+
-PublicClient $False
122+
$serviceServicePrincipal = New-AzureADServicePrincipal -AppId $serviceAadApplication.AppId -Tags {WindowsAzureActiveDirectoryIntegratedApp}
123+
Write-Host "Done."
124+
125+
# Create the client AAD application
126+
Write-Host "Creating the AAD appplication (TodoListClient-ManualJwt)"
127+
$clientAadApplication = New-AzureADApplication -DisplayName "TodoListClient-ManualJwt" `
128+
-ReplyUrls "https://TodoListClient-ManualJwt" `
129+
-PublicClient $True
130+
$clientServicePrincipal = New-AzureADServicePrincipal -AppId $clientAadApplication.AppId -Tags {WindowsAzureActiveDirectoryIntegratedApp}
131+
Write-Host "Done."
132+
133+
# Add Required Resources Access (from 'client' to 'service')
134+
Write-Host "Getting access from 'client' to 'service'"
135+
$requiredResourcesAccess = New-Object System.Collections.Generic.List[Microsoft.Open.AzureAD.Model.RequiredResourceAccess]
136+
$requiredPermissions = GetRequiredPermissions -applicationDisplayName "TodoListService-ManualJwt" `
137+
-requiredDelegatedPermissions "user_impersonation";
138+
$requiredResourcesAccess.Add($requiredPermissions)
139+
Set-AzureADApplication -ObjectId $clientAadApplication.ObjectId -RequiredResourceAccess $requiredResourcesAccess
140+
Write-Host "Granted."
141+
142+
# Update config file for 'service'
143+
$configFile = $pwd.Path + "\..\TodoListService-ManualJwt\Web.Config"
144+
Write-Host "Updating the sample code ($configFile)"
145+
ReplaceSetting -configFilePath $configFile -key "ida:Tenant" -newValue $tenantName
146+
ReplaceSetting -configFilePath $configFile -key "ida:Audience" -newValue $serviceAadApplication.IdentifierUris
147+
148+
# Update config file for 'client'
149+
$configFile = $pwd.Path + "\..\TodoListClient\App.Config"
150+
Write-Host "Updating the sample code ($configFile)"
151+
ReplaceSetting -configFilePath $configFile -key "ida:Tenant" -newValue $tenantName
152+
ReplaceSetting -configFilePath $configFile -key "ida:ClientId" -newValue $clientAadApplication.AppId
153+
ReplaceSetting -configFilePath $configFile -key "ida:RedirectUri" -newValue $clientAadApplication.ReplyUrls
154+
ReplaceSetting -configFilePath $configFile -key "todo:TodoListResourceId" -newValue $serviceAadApplication.IdentifierUris
155+
ReplaceSetting -configFilePath $configFile -key "todo:TodoListBaseAddress" -newValue $serviceAadApplication.HomePage
156+
}
157+
}
158+
159+
# Run interactively (will ask you for the tenant ID)
160+
ConfigureApplications -Credential $Credential -tenantId $TenantId

AppCreationScripts/apps.json

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
{
2+
/*
3+
This section describes the Azure AD Applications to configure, and their dependencies
4+
*/
5+
"AADApps": [
6+
{
7+
"Id": "service",
8+
"Name": "TodoListService-ManualJwt",
9+
"IsPublicClient": false,
10+
"HomePage": "https://localhost:44324"
11+
},
12+
{
13+
"Id": "client",
14+
"Name": "TodoListClient-ManualJwt",
15+
"IsPublicClient": true,
16+
"RequiredResourcesAccess": [
17+
{
18+
"Resource": "service",
19+
"DelegatedPermissions": [ "user_impersonation" ]
20+
}
21+
]
22+
}
23+
],
24+
25+
/*
26+
This section describes how to update the code in configuration files from the apps coordinates, once the apps
27+
are created in Azure AD.
28+
Each section describes a configuration file, for one of the apps, it's type (XML, JSon, plain text), its location
29+
with respect to the root of the sample, and the mappping (which string in the config file is mapped to which value
30+
*/
31+
"CodeConfiguration": [
32+
{
33+
"App": "service",
34+
"SettingKind": "XML",
35+
"SettingFile": "\\..\\TodoListService-ManualJwt\\Web.Config",
36+
"Mappings": [
37+
{
38+
"key": "ida:Tenant",
39+
"value": "$tenantName"
40+
},
41+
{
42+
"key": "ida:Audience",
43+
"value": "service.IdentifierUris"
44+
}
45+
]
46+
},
47+
48+
{
49+
"App": "client",
50+
"SettingKind": "XML",
51+
"SettingFile": "\\..\\TodoListClient\\App.Config",
52+
"Mappings": [
53+
{
54+
"key": "ida:Tenant",
55+
"value": "$tenantName"
56+
},
57+
{
58+
"key": "ida:ClientId",
59+
"value": ".AppId"
60+
},
61+
{
62+
"key": "ida:RedirectUri",
63+
"value": ".ReplyUrls"
64+
},
65+
{
66+
"key": "todo:TodoListResourceId",
67+
"value": "service.IdentifierUris"
68+
},
69+
{
70+
"key": "todo:TodoListBaseAddress",
71+
"value": "service.HomePage"
72+
}
73+
]
74+
}
75+
]
76+
}

0 commit comments

Comments
 (0)