diff --git a/PersonalAccessTokenAPIAppSample/AppCreationScripts/AppCreationScripts.md b/PersonalAccessTokenAPIAppSample/AppCreationScripts/AppCreationScripts.md index b81c211..e35c89a 100644 --- a/PersonalAccessTokenAPIAppSample/AppCreationScripts/AppCreationScripts.md +++ b/PersonalAccessTokenAPIAppSample/AppCreationScripts/AppCreationScripts.md @@ -67,12 +67,12 @@ The scripts install the required PowerShell module (AzureAD) for the current use 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 + Install-Module Microsoft.Graph ``` or if you cannot be administrator on your machine, run: ```PowerShell - Install-Module AzureAD -Scope CurrentUser + Install-Module Microsoft.Graph -Scope CurrentUser ``` ### Run the script and start running @@ -105,20 +105,7 @@ Here are the details on how to do this. Note that the script will choose the tenant in which to create the applications, based on the user. Also to run the `Cleanup.ps1` script, you will need to re-sign-in. -#### Option 2 (non-interactive) - -When you know the indentity and credentials of the user in the name of whom you want to create the applications, you can use the non-interactive approach. It's more adapted to DevOps. Here is an example of script you'd want to run in a PowerShell Window - -```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 -``` - -Of course, in real life, you might already get the password as a `SecureString`. You might also want to get the password from KeyVault. - -#### Option 3 (Interactive, but create apps in a specified tenant) +#### Option 2 (Interactive, but create apps in a specified tenant) if you want to create the apps in a particular tenant, you can use the following option: - open the [Azure portal](https://portal.azure.com) @@ -132,15 +119,3 @@ $tenantId = "yourTenantIdGuid" . .\Cleanup.ps1 -TenantId $tenantId . .\Configure.ps1 -TenantId $tenantId ``` - -#### Option 4 (non-interactive, and create apps in a specified tenant) - -This option combines option 2 and option 3: it creates the application in a specific tenant. See option 3 for the way to get the tenant Id. Then run: - -```PowerShell -$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 -``` diff --git a/PersonalAccessTokenAPIAppSample/AppCreationScripts/Cleanup.ps1 b/PersonalAccessTokenAPIAppSample/AppCreationScripts/Cleanup.ps1 index f6eae05..468aa9e 100644 --- a/PersonalAccessTokenAPIAppSample/AppCreationScripts/Cleanup.ps1 +++ b/PersonalAccessTokenAPIAppSample/AppCreationScripts/Cleanup.ps1 @@ -5,10 +5,10 @@ param( [string] $tenantId ) -if ($null -eq (Get-Module -ListAvailable -Name "AzureAD")) { - Install-Module "AzureAD" -Scope CurrentUser +if ($null -eq (Get-Module -ListAvailable -Name "Microsoft.Graph")) { + Install-Module "Microsoft.Graph" -Scope CurrentUser } -Import-Module AzureAD +Import-Module Microsoft.Graph $ErrorActionPreference = "Stop" Function Cleanup @@ -21,49 +21,42 @@ This function removes the Azure AD applications for the sample. These applicatio # $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. - # Login to Azure PowerShell (interactive if credentials are not already provided: + # Login to Microsoft Graph PowerShell (interactive if credentials are not already provided: # you'll need to sign-in with creds enabling your to create apps in the tenant) - if (!$Credential -and $TenantId) + if ($TenantId) { - $creds = Connect-AzureAD -TenantId $tenantId + $creds = Connect-MgGraph -TenantId $tenantId } else { - if (!$TenantId) - { - $creds = Connect-AzureAD -Credential $Credential - } - else - { - $creds = Connect-AzureAD -TenantId $tenantId -Credential $Credential - } + $creds = Connect-MgGraph } if (!$tenantId) { - $tenantId = $creds.Tenant.Id + $tenantId = (Get-MgOrganization).Id } - $tenant = Get-AzureADTenantDetail - $tenantName = ($tenant.VerifiedDomains | Where-Object { $_._Default -eq $True }).Name + $tenant = Get-MgOrganization + $tenantName = ($tenant.VerifiedDomains | Where-Object { $_.IsDefault -eq $True }).Name # Removes the applications Write-Host "Cleaning-up applications from tenant '$tenantName'" Write-Host "Removing 'pythonwebapp' (python-webapp) if needed" - Get-AzureADApplication -Filter "DisplayName eq 'python-webapp'" | ForEach-Object {Remove-AzureADApplication -ObjectId $_.ObjectId } - $apps = Get-AzureADApplication -Filter "DisplayName eq 'python-webapp'" + Get-MgApplication -Filter "DisplayName eq 'python-webapp'" | ForEach-Object {Remove-MgApplication -ApplicationId $_.Id } + $apps = Get-MgApplication -Filter "DisplayName eq 'python-webapp'" if ($apps) { - Remove-AzureADApplication -ObjectId $apps.ObjectId + Remove-MgApplication -ApplicationId $apps.Id } foreach ($app in $apps) { - Remove-AzureADApplication -ObjectId $app.ObjectId + Remove-MgApplication -ApplicationId $app.Id Write-Host "Removed python-webapp.." } # also remove service principals of this app - Get-AzureADServicePrincipal -filter "DisplayName eq 'python-webapp'" | ForEach-Object {Remove-AzureADServicePrincipal -ObjectId $_.Id -Confirm:$false} + Get-MgServicePrincipal -Filter "DisplayName eq 'python-webapp'" | ForEach-Object {Remove-MgServicePrincipal -ServicePrincipalId $_.Id -Confirm:$false} } diff --git a/PersonalAccessTokenAPIAppSample/AppCreationScripts/Configure.ps1 b/PersonalAccessTokenAPIAppSample/AppCreationScripts/Configure.ps1 index f0934ee..d4af42f 100644 --- a/PersonalAccessTokenAPIAppSample/AppCreationScripts/Configure.ps1 +++ b/PersonalAccessTokenAPIAppSample/AppCreationScripts/Configure.ps1 @@ -5,99 +5,6 @@ param( [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. - - Before running this script you need to install the AzureAD cmdlets as an administrator. - For this: - 1) Run Powershell as an administrator - 2) in the PowerShell window, type: Install-Module AzureAD - - There are four ways to run this script. For more information, read the AppCreationScripts.md file in the same folder as this script. -#> - -# Create a password that can be used as an application key -Function ComputePassword -{ - $aesManaged = New-Object "System.Security.Cryptography.AesManaged" - $aesManaged.Mode = [System.Security.Cryptography.CipherMode]::CBC - $aesManaged.Padding = [System.Security.Cryptography.PaddingMode]::Zeros - $aesManaged.BlockSize = 128 - $aesManaged.KeySize = 256 - $aesManaged.GenerateKey() - return [System.Convert]::ToBase64String($aesManaged.Key) -} - -# Create an application key -# See https://www.sabin.io/blog/adding-an-azure-active-directory-application-and-key-using-powershell/ -Function CreateAppKey([DateTime] $fromDate, [double] $durationInYears, [string]$pw) -{ - $endDate = $fromDate.AddYears($durationInYears) - $keyId = (New-Guid).ToString(); - $key = New-Object Microsoft.Open.AzureAD.Model.PasswordCredential - $key.StartDate = $fromDate - $key.EndDate = $endDate - $key.Value = $pw - $key.KeyId = $keyId - return $key -} - -# 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 AddResourcePermission($requiredAccess, ` - $exposedPermissions, [string]$requiredAccesses, [string]$permissionType) -{ - foreach($permission in $requiredAccesses.Trim().Split("|")) - { - foreach($exposedPermission in $exposedPermissions) - { - if ($exposedPermission.Value -eq $permission) - { - $resourceAccess = New-Object Microsoft.Open.AzureAD.Model.ResourceAccess - $resourceAccess.Type = $permissionType # Scope = Delegated permissions | Role = Application permissions - $resourceAccess.Id = $exposedPermission.Id # Read directory data - $requiredAccess.ResourceAccess.Add($resourceAccess) - } - } - } -} - -# -# Example: GetRequiredPermissions "Microsoft Graph" "Graph.Read|User.Read" -# See also: http://stackoverflow.com/questions/42164581/how-to-configure-a-new-azure-ad-application-through-powershell -Function GetRequiredPermissions([string] $applicationDisplayName, [string] $requiredDelegatedPermissions, [string]$requiredApplicationPermissions, $servicePrincipal) -{ - # If we are passed the service principal we use it directly, otherwise we find it from the display name (which might not be unique) - if ($servicePrincipal) - { - $sp = $servicePrincipal - } - else - { - $sp = Get-AzureADServicePrincipal -Filter "DisplayName eq '$applicationDisplayName'" - } - $appid = $sp.AppId - $requiredAccess = New-Object Microsoft.Open.AzureAD.Model.RequiredResourceAccess - $requiredAccess.ResourceAppId = $appid - $requiredAccess.ResourceAccess = New-Object System.Collections.Generic.List[Microsoft.Open.AzureAD.Model.ResourceAccess] - - # $sp.Oauth2Permissions | Select Id,AdminConsentDisplayName,Value: To see the list of all the Delegated permissions for the application: - if ($requiredDelegatedPermissions) - { - AddResourcePermission $requiredAccess -exposedPermissions $sp.Oauth2Permissions -requiredAccesses $requiredDelegatedPermissions -permissionType "Scope" - } - - # $sp.AppRoles | Select Id,AdminConsentDisplayName,Value: To see the list of all the Application permissions for the application - if ($requiredApplicationPermissions) - { - AddResourcePermission $requiredAccess -exposedPermissions $sp.AppRoles -requiredAccesses $requiredApplicationPermissions -permissionType "Role" - } - return $requiredAccess -} - - Function ReplaceInLine([string] $line, [string] $key, [string] $value) { $index = $line.IndexOf($key) @@ -141,104 +48,100 @@ 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 #> - $commonendpoint = "common" - - # $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. + # $tenantId is the Entra Tenant. This is a GUID which represents the "Directory ID" of the Entra tenant + # into which you want to create the apps. Look it up in the Azure portal in the "Properties" of the Entra. - # Login to Azure PowerShell (interactive if credentials are not already provided: - # you'll need to sign-in with creds enabling your to create apps in the tenant) - if (!$Credential -and $TenantId) - { - $creds = Connect-AzureAD -TenantId $tenantId - } - else - { - if (!$TenantId) + try{ + # Login to Microsoft Graph PowerShell + if ($TenantId) { - $creds = Connect-AzureAD -Credential $Credential + $creds = Connect-MgGraph -TenantId $tenantId } else { - $creds = Connect-AzureAD -TenantId $tenantId -Credential $Credential + $creds = Connect-MgGraph } - } - if (!$tenantId) - { - $tenantId = $creds.Tenant.Id - } + if (!$tenantId) + { + $tenantId = $creds.Tenant.Id + } + + $tenant = Get-MgOrganization + $tenantName = ($tenant.VerifiedDomains | Where { $_.IsDefault -eq $True }).Name + + # Get the user running the script to add the user as the app owner + $user = Get-MgUser -UserId (Get-MgContext).Account - $tenant = Get-AzureADTenantDetail - $tenantName = ($tenant.VerifiedDomains | Where { $_._Default -eq $True }).Name - - # Get the user running the script to add the user as the app owner - $user = Get-AzureADUser -ObjectId $creds.Account.Id - - # Create the pythonwebapp AAD application - Write-Host "Creating the AAD application (python-webapp)" - # Get a 2 years application key for the pythonwebapp Application - $pw = ComputePassword - $fromDate = [DateTime]::Now; - $key = CreateAppKey -fromDate $fromDate -durationInYears 2 -pw $pw - $pythonwebappAppKey = $pw - # create the application - $pythonwebappAadApplication = New-AzureADApplication -DisplayName "python-webapp" ` - -ReplyUrls "http://localhost:5000/getAToken" ` - -IdentifierUris "https://$tenantName/python-webapp" ` - -AvailableToOtherTenants $True ` - -PasswordCredentials $key ` - -Oauth2AllowImplicitFlow $true ` - -PublicClient $False - - # create the service principal of the newly created application - $currentAppId = $pythonwebappAadApplication.AppId - $pythonwebappServicePrincipal = New-AzureADServicePrincipal -AppId $currentAppId -Tags {WindowsAzureActiveDirectoryIntegratedApp} - - # add the user running the script as an app owner if needed - $owner = Get-AzureADApplicationOwner -ObjectId $pythonwebappAadApplication.ObjectId - if ($owner -eq $null) - { - Add-AzureADApplicationOwner -ObjectId $pythonwebappAadApplication.ObjectId -RefObjectId $user.ObjectId - Write-Host "'$($user.UserPrincipalName)' added as an application owner to app '$($pythonwebappServicePrincipal.DisplayName)'" - } - - - Write-Host "Done creating the pythonwebapp application (python-webapp)" - - # URL of the AAD application in the Azure portal - # Future? $pythonwebappPortalUrl = "https://portal.azure.com/#@"+$tenantName+"/blade/Microsoft_AAD_RegisteredApps/ApplicationMenuBlade/Overview/appId/"+$pythonwebappAadApplication.AppId+"/objectId/"+$pythonwebappAadApplication.ObjectId+"/isMSAApp/" - $pythonwebappPortalUrl = "https://portal.azure.com/#blade/Microsoft_AAD_RegisteredApps/ApplicationMenuBlade/CallAnAPI/appId/"+$pythonwebappAadApplication.AppId+"/objectId/"+$pythonwebappAadApplication.ObjectId+"/isMSAApp/" - Add-Content -Value "