Skip to content
This repository has been archived by the owner on Nov 15, 2019. It is now read-only.

Commit

Permalink
- Added AppRoles to protect API
Browse files Browse the repository at this point in the history
- Updated README
- Updated Configure.ps1
  • Loading branch information
Tiago Brenck committed Jun 6, 2019
1 parent eda76aa commit 254bc10
Show file tree
Hide file tree
Showing 8 changed files with 365 additions and 109 deletions.
62 changes: 49 additions & 13 deletions AppCreationScripts/AppCreationScripts.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,32 @@
# Registering the Azure Active Directory applications and updating the configuration files for this sample using PowerShell scripts

## Overview

### Quick summary

1. On Windows run PowerShell and navigate to the root of the cloned directory
1. In PowerShell run:
```PowerShell
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope Process -Force
```
1. Run the script to create your Azure AD application and configure the code of the sample application accordinly. (Other ways of running the scripts are described below)
```PowerShell
.\AppCreationScripts\Configure.ps1
```
1. Open the Visual Studio solution and click start

### More details

The following paragraphs:

- [Present the scripts](#presentation-of-the-scripts) and explain their [usage patterns](#usage-pattern-for-tests-and-devops-scenarios) for test and DevOps scenarios.
- Explain the [pre-requisites](#pre-requisites)
- Explain [four ways of running the scripts](#four-ways-to-run-the-script):
- [Interactively](#option-1-interactive) to create the app in your home tenant
- [Passing credentials](#option-2-non-interactive) to create the app in your home tenant
- [Interactively in a specific tenant](#option-3-interactive-but-create-apps-in-a-specified-tenant)
- [Passing credentials in a specific tenant](#option-4-non-interactive-and-create-apps-in-a-specified-tenant)

## Goal of the scripts

### Presentation of the scripts
Expand All @@ -26,21 +53,30 @@ The `Configure.ps1` will stop if it tries to create an Azure AD application whic

### Pre-requisites

To use the app creation scripts:

1. Open PowerShell (On Windows, press `Windows-R` and type `PowerShell` in the search window)
2. Navigate to the root directory of the project.
3. Until you change it, the default Execution Policy for scripts is usually `Restricted`. In order to run the PowerShell script you need to set the Execution Policy to `Unrestricted`. You can set this just for the current PowerShell process by running the command:
3. Until you change it, the default [Execution Policy](https:/go.microsoft.com/fwlink/?LinkID=135170) for scripts is usually `Restricted`. In order to run the PowerShell script you need to set the Execution Policy to `RemoteSigned`. You can set this just for the current PowerShell process by running the command:
```PowerShell
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope Process
```
### (Optionally) install AzureAD PowerShell modules
The scripts install the required PowerShell module (AzureAD) for the current user if needed. However, if you want to install if for all users on the machine, you can follow the following steps:
4. If you have never done it already, in the PowerShell window, install the AzureAD PowerShell modules. For this:
1. Open PowerShell as admin (On Windows, Search Powershell in the search bar, right click on it and select Run as administrator).
2. Type:
```PowerShell
Install-Module AzureAD
```
```PowerShell
Install-Module AzureAD
```
or if you cannot be administrator on your machine, run:
```PowerShell
Install-Module AzureAD -Scope CurrentUser
```
### Run the script and start running
5. Go to the `AppCreationScripts` sub-folder. From the folder where you cloned the repo,
```PowerShell
cd AppCreationScripts
Expand All @@ -57,7 +93,7 @@ We advise four ways of running the script:
- Interactive: you will be prompted for credentials, and the scripts decide in which tenant to create the objects,
- non-interactive: you will provide credentials, and the scripts decide in which tenant to create the objects,
- Interactive in specific tenant: you will provide tenant in which you want to create the objects and then you will be prompted for credentials, and the scripts will create the objects,
- Interactive in specific tenant: you will provide the tenant in which you want to create the objects and then you will be prompted for credentials, and the scripts will create the objects,
- non-interactive in specific tenant: you will provide tenant in which you want to create the objects and credentials, and the scripts will create the objects.
Here are the details on how to do this.
Expand All @@ -76,8 +112,8 @@ When you know the indentity and credentials of the user in the name of whom you
```PowerShell
$secpasswd = ConvertTo-SecureString "[Password here]" -AsPlainText -Force
$mycreds = New-Object System.Management.Automation.PSCredential ("[login@tenantName here]", $secpasswd)
.\Cleanup.ps1 -Credential $mycreds
.\Configure.ps1 -Credential $mycreds
. .\Cleanup.ps1 -Credential $mycreds
. .\Configure.ps1 -Credential $mycreds
```

Of course, in real life, you might already get the password as a `SecureString`. You might also want to get the password from KeyVault.
Expand All @@ -93,8 +129,8 @@ Of course, in real life, you might already get the password as a `SecureString`.

```PowerShell
$tenantId = "yourTenantIdGuid"
.\Cleanup.ps1 -TenantId $tenantId
.\Configure.ps1 -TenantId $tenantId
. .\Cleanup.ps1 -TenantId $tenantId
. .\Configure.ps1 -TenantId $tenantId
```

#### Option 4 (non-interactive, and create apps in a specified tenant)
Expand All @@ -105,6 +141,6 @@ This option combines option 2 and option 3: it creates the application in a spec
$secpasswd = ConvertTo-SecureString "[Password here]" -AsPlainText -Force
$mycreds = New-Object System.Management.Automation.PSCredential ("[login@tenantName here]", $secpasswd)
$tenantId = "yourTenantIdGuid"
.\Cleanup.ps1 -Credential $mycreds -TenantId $tenantId
.\Configure.ps1 -Credential $mycreds -TenantId $tenantId
. .\Cleanup.ps1 -Credential $mycreds -TenantId $tenantId
. .\Configure.ps1 -Credential $mycreds -TenantId $tenantId
```
30 changes: 16 additions & 14 deletions AppCreationScripts/Cleanup.ps1
Original file line number Diff line number Diff line change
@@ -1,4 +1,13 @@
param([Parameter(Mandatory=$false)][PSCredential]$Credential=$null, [Parameter(Mandatory=$false)][string]$TenantId)
[CmdletBinding()]
param(
[PSCredential] $Credential,
[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')]
[string] $tenantId
)

if ((Get-Module -ListAvailable -Name "AzureAD") -eq $null) {
Install-Module "AzureAD" -Scope CurrentUser
}
Import-Module AzureAD
$ErrorActionPreference = 'Stop'

Expand All @@ -8,15 +17,7 @@ Function Cleanup
.Description
This function removes the Azure AD applications for the sample. These applications were created by the Configure.ps1 script
#>
[CmdletBinding()]
param(
[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')]
[PSCredential] $Credential,
[string] $tenantId
)

process
{
# $tenantId is the Active Directory Tenant. This is a GUID which represents the "Directory ID" of the AzureAD tenant
# into which you want to create the apps. Look it up in the Azure portal in the "Properties" of the Azure AD.

Expand Down Expand Up @@ -48,23 +49,24 @@ This function removes the Azure AD applications for the sample. These applicatio
# Removes the applications
Write-Host "Cleaning-up applications from tenant '$tenantName'"

Write-Host "Removing 'service' (TodoListService) if needed"
$app=Get-AzureADApplication -Filter "identifierUris/any(uri:uri eq 'https://$tenantName/TodoListService')"
Write-Host "Removing 'service' (TodoListService-Core-Cert) if needed"
$app=Get-AzureADApplication -Filter "DisplayName eq 'TodoListService-Core-Cert'"

if ($app)
{
Remove-AzureADApplication -ObjectId $app.ObjectId
Write-Host "Removed."
}

Write-Host "Removing 'client' (TodoListDaemon) if needed"
$app=Get-AzureADApplication -Filter "identifierUris/any(uri:uri eq 'https://$tenantName/TodoListDaemon')"
Write-Host "Removing 'client' (TodoListDaemon-Core-Cert) if needed"
$app=Get-AzureADApplication -Filter "DisplayName eq 'TodoListDaemon-Core-Cert'"

if ($app)
{
Remove-AzureADApplication -ObjectId $app.ObjectId
Write-Host "Removed."
}

}
}

Cleanup -Credential $Credential -tenantId $TenantId
124 changes: 94 additions & 30 deletions AppCreationScripts/Configure.ps1
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
[CmdletBinding()]
param(
[PSCredential] $Credential,
[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')]
[string] $tenantId
)

<#
This script creates the Azure AD applications needed for this sample and updates the configuration files
for the visual Studio projects from the data in the Azure AD applications.
Expand All @@ -13,6 +20,19 @@
# Adds the requiredAccesses (expressed as a pipe separated string) to the requiredAccess structure
# The exposed permissions are in the $exposedPermissions collection, and the type of permission (Scope | Role) is
# described in $permissionType
Function CreateAppRole([string] $Name, [string] $Description)
{
$appRole = New-Object Microsoft.Open.AzureAD.Model.AppRole
$appRole.AllowedMemberTypes = New-Object System.Collections.Generic.List[string]
$appRole.AllowedMemberTypes.Add("Application");
$appRole.DisplayName = $Name
$appRole.Id = New-Guid
$appRole.IsEnabled = $true
$appRole.Description = $Description
$appRole.Value = $Name;
return $appRole
}

Function AddResourcePermission($requiredAccess, `
$exposedPermissions, [string]$requiredAccesses, [string]$permissionType)
{
Expand Down Expand Up @@ -111,15 +131,7 @@ Function ConfigureApplications
configuration files in the client and service project of the visual studio solution (App.Config and Web.Config)
so that they are consistent with the Applications parameters
#>
[CmdletBinding()]
param(
[PSCredential] $Credential,
[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')]
[string] $tenantId
)

process
{

# $tenantId is the Active Directory Tenant. This is a GUID which represents the "Directory ID" of the AzureAD tenant
# into which you want to create the apps. Look it up in the Azure portal in the "Properties" of the Azure AD.

Expand All @@ -145,33 +157,55 @@ Function ConfigureApplications
{
$tenantId = $creds.Tenant.Id
}

$tenant = Get-AzureADTenantDetail
$tenantName = ($tenant.VerifiedDomains | Where { $_._Default -eq $True }).Name

# Get the user running the script
$user = Get-AzureADUser -ObjectId $creds.Account.Id

$accessasadminrole = CreateAppRole -Name "access_as_application" -Description "Accesses the TodoListService-Core-Cert as an application."

$appRoles = New-Object System.Collections.Generic.List[Microsoft.Open.AzureAD.Model.AppRole]
$appRoles.Add($accessasadminrole)

# Create the service AAD application
Write-Host "Creating the AAD appplication (TodoListService)"
$serviceAadApplication = New-AzureADApplication -DisplayName "TodoListService" `
Write-Host "Creating the AAD application (TodoListService-Core-Cert)"
$serviceAadApplication = New-AzureADApplication -DisplayName "TodoListService-Core-Cert" `
-HomePage "https://localhost:44351/" `
-IdentifierUris "https://$tenantName/TodoListService" `
-PublicClient $False
-AvailableToOtherTenants $True `
-PublicClient $False `
-AppRoles $appRoles

$serviceIdentifierUri = 'api://'+$serviceAadApplication.AppId
Set-AzureADApplication -ObjectId $serviceAadApplication.ObjectId -IdentifierUris $serviceIdentifierUri

$currentAppId = $serviceAadApplication.AppId
$serviceServicePrincipal = New-AzureADServicePrincipal -AppId $currentAppId -Tags {WindowsAzureActiveDirectoryIntegratedApp}
Write-Host "Done."

# add the user running the script as an app owner if needed
$owner = Get-AzureADApplicationOwner -ObjectId $serviceAadApplication.ObjectId
if ($owner -eq $null)
{
Add-AzureADApplicationOwner -ObjectId $serviceAadApplication.ObjectId -RefObjectId $user.ObjectId
Write-Host "'$($user.UserPrincipalName)' added as an application owner to app '$($serviceServicePrincipal.DisplayName)'"
}

Write-Host "Done creating the service application (TodoListService-Core-Cert)"

# URL of the AAD application in the Azure portal
$servicePortalUrl = "https://portal.azure.com/#@"+$tenantName+"/blade/Microsoft_AAD_IAM/ApplicationBlade/appId/"+$serviceAadApplication.AppId+"/objectId/"+$serviceAadApplication.ObjectId
Add-Content -Value "<tr><td>service</td><td>$currentAppId</td><td><a href='$servicePortalUrl'>TodoListService</a></td></tr>" -Path createdApps.html
# Future? $servicePortalUrl = "https://portal.azure.com/#@"+$tenantName+"/blade/Microsoft_AAD_RegisteredApps/ApplicationMenuBlade/Overview/appId/"+$serviceAadApplication.AppId+"/objectId/"+$serviceAadApplication.ObjectId+"/isMSAApp/"
$servicePortalUrl = "https://portal.azure.com/#blade/Microsoft_AAD_RegisteredApps/ApplicationMenuBlade/CallAnAPI/appId/"+$serviceAadApplication.AppId+"/objectId/"+$serviceAadApplication.ObjectId+"/isMSAApp/"
Add-Content -Value "<tr><td>service</td><td>$currentAppId</td><td><a href='$servicePortalUrl'>TodoListService-Core-Cert</a></td></tr>" -Path createdApps.html

# Create the client AAD application
Write-Host "Creating the AAD appplication (TodoListDaemon)"
$clientAadApplication = New-AzureADApplication -DisplayName "TodoListDaemon" `
-IdentifierUris "https://$tenantName/TodoListDaemon" `
Write-Host "Creating the AAD application (TodoListDaemon-Core-Cert)"
$clientAadApplication = New-AzureADApplication -DisplayName "TodoListDaemon-Core-Cert" `
-IdentifierUris "https://$tenantName/TodoListDaemon-Core-Cert" `
-PublicClient $False

# Generate a certificate
Write-Host "Creating the client appplication (TodoListDaemon)"
Write-Host "Creating the client application (TodoListDaemon-Core-Cert)"
$certificate=New-SelfSignedCertificate -Subject CN=TodoListDaemonWithCert `
-CertStoreLocation "Cert:\CurrentUser\My" `
-KeyExportPolicy Exportable `
Expand All @@ -189,23 +223,36 @@ Function ConfigureApplications
-StartDate $certificate.NotBefore `
-EndDate $certificate.NotAfter


$currentAppId = $clientAadApplication.AppId
$clientServicePrincipal = New-AzureADServicePrincipal -AppId $currentAppId -Tags {WindowsAzureActiveDirectoryIntegratedApp}
Write-Host "Done."

# add the user running the script as an app owner if needed
$owner = Get-AzureADApplicationOwner -ObjectId $clientAadApplication.ObjectId
if ($owner -eq $null)
{
Add-AzureADApplicationOwner -ObjectId $clientAadApplication.ObjectId -RefObjectId $user.ObjectId
Write-Host "'$($user.UserPrincipalName)' added as an application owner to app '$($clientServicePrincipal.DisplayName)'"
}

Write-Host "Done creating the client application (TodoListDaemon-Core-Cert)"

# URL of the AAD application in the Azure portal
$clientPortalUrl = "https://portal.azure.com/#@"+$tenantName+"/blade/Microsoft_AAD_IAM/ApplicationBlade/appId/"+$clientAadApplication.AppId+"/objectId/"+$clientAadApplication.ObjectId
Add-Content -Value "<tr><td>client</td><td>$currentAppId</td><td><a href='$clientPortalUrl'>TodoListDaemon</a></td></tr>" -Path createdApps.html
# Future? $clientPortalUrl = "https://portal.azure.com/#@"+$tenantName+"/blade/Microsoft_AAD_RegisteredApps/ApplicationMenuBlade/Overview/appId/"+$clientAadApplication.AppId+"/objectId/"+$clientAadApplication.ObjectId+"/isMSAApp/"
$clientPortalUrl = "https://portal.azure.com/#blade/Microsoft_AAD_RegisteredApps/ApplicationMenuBlade/CallAnAPI/appId/"+$clientAadApplication.AppId+"/objectId/"+$clientAadApplication.ObjectId+"/isMSAApp/"
Add-Content -Value "<tr><td>client</td><td>$currentAppId</td><td><a href='$clientPortalUrl'>TodoListDaemon-Core-Cert</a></td></tr>" -Path createdApps.html

$requiredResourcesAccess = New-Object System.Collections.Generic.List[Microsoft.Open.AzureAD.Model.RequiredResourceAccess]

# Add Required Resources Access (from 'client' to 'service')
Write-Host "Getting access from 'client' to 'service'"
$requiredPermissions = GetRequiredPermissions -applicationDisplayName "TodoListService" `
-requiredDelegatedPermissions "user_impersonation";
$requiredPermissions = GetRequiredPermissions -applicationDisplayName "TodoListService-Core-Cert" `
-requiredApplicationPermissions "access_as_application" `

$requiredResourcesAccess.Add($requiredPermissions)


Set-AzureADApplication -ObjectId $clientAadApplication.ObjectId -RequiredResourceAccess $requiredResourcesAccess
Write-Host "Granted."
Write-Host "Granted permissions."

# Update config file for 'service'
$configFile = $pwd.Path + "\..\TodoListService\appsettings.json"
Expand All @@ -216,13 +263,30 @@ Function ConfigureApplications
# Update config file for 'client'
$configFile = $pwd.Path + "\..\TodoListDaemonWithCert-Core\appsettings.json"
Write-Host "Updating the sample code ($configFile)"
$dictionary = @{ "Tenant" = $tenantName;"ClientId" = $clientAadApplication.AppId;"CertName" = "CN=TodoListDaemonWithCert";"TodoListResourceId" = $serviceAadApplication.AppId;"TodoListBaseAddress" = $serviceAadApplication.HomePage };
$dictionary = @{ "Tenant" = $tenantName; "ClientId" = $clientAadApplication.AppId; "CertName" = "CN=TodoListDaemonWithCert"; "TodoListResourceId" = $serviceAadApplication.AppId;"TodoListBaseAddress" = $serviceAadApplication.HomePage };
UpdateTextFile -configFilePath $configFile -dictionary $dictionary
Add-Content -Value "</tbody></table></body></html>" -Path createdApps.html

}
$servicePropertyBladeUrl = "https://portal.azure.com/#blade/Microsoft_AAD_IAM/ManagedAppMenuBlade/Properties/objectId/"+$serviceServicePrincipal.ObjectId+"/appId/"+$serviceAadApplication.AppId

Write-Host ""
Write-Host -ForegroundColor Green "------------------------------------------------------------------------------------------------"
Write-Host -ForegroundColor Yellow "IMPORTANT: Please follow the instructions below to complete a few manual step(s) in the Azure portal":
Write-Host "- For 'TodoListService-Core-Cert'"
Write-Host " - Navigate to Properties tab: '$servicePropertyBladeUrl'"
Write-Host " - Set 'User assignment required' to 'Yes'"
Write-Host "- For 'TodoListService-Core-Cert'"
Write-Host " - Navigate to API Permisions: '$clientPortalUrl'"
Write-Host " - Click on 'Grant admin consent for (your tenant)'."
Write-Host -ForegroundColor Green "------------------------------------------------------------------------------------------------"

Add-Content -Value "</tbody></table></body></html>" -Path createdApps.html
}

# Pre-requisites
if ((Get-Module -ListAvailable -Name "AzureAD") -eq $null) {
Install-Module "AzureAD" -Scope CurrentUser
}
Import-Module AzureAD

# Run interactively (will ask you for the tenant ID)
ConfigureApplications -Credential $Credential -tenantId $TenantId
Loading

0 comments on commit 254bc10

Please sign in to comment.