Skip to content

Commit e1e376e

Browse files
committed
Split delegated and app-only into separate projects
1 parent 228911e commit e1e376e

28 files changed

+1530
-505
lines changed

.gitattributes

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
# Auto detect text files and perform LF normalization
2+
* text=auto

.vscode/launch.json

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,17 @@
88
"name": "Python: main",
99
"type": "python",
1010
"request": "launch",
11-
"program": "${workspaceFolder}/demo/graphtutorial/main.py",
12-
"cwd": "${workspaceFolder}/demo/graphtutorial",
11+
"program": "${workspaceFolder}/user-auth/graphtutorial/main.py",
12+
"cwd": "${workspaceFolder}/user-auth/graphtutorial",
13+
"console": "integratedTerminal",
14+
"justMyCode": true
15+
},
16+
{
17+
"name": "Python: main (app-only)",
18+
"type": "python",
19+
"request": "launch",
20+
"program": "${workspaceFolder}/app-auth/graphapponlytutorial/main.py",
21+
"cwd": "${workspaceFolder}/app-auth/graphapponlytutorial",
1322
"console": "integratedTerminal",
1423
"justMyCode": true
1524
}

.vscode/settings.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"cSpell.words": [
3+
"graphtutorial",
4+
"Pylint"
5+
]
6+
}

README.md

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,13 @@
22

33
[![Pylint](https://github.com/microsoftgraph/msgraph-training-python/actions/workflows/pylint.yml/badge.svg)](https://github.com/microsoftgraph/msgraph-training-python/actions/workflows/pylint.yml)
44

5-
This sample will introduce you to working with the Microsoft Graph SDK to access data in Microsoft 365 from Python applications. This code is the result of completing the [Python Microsoft Graph tutorial](https://docs.microsoft.com/graph/tutorials/python).
5+
This sample will introduce you to working with the Microsoft Graph SDK to access data in Microsoft 365 from Python applications. This code is the result of completing the [Python Microsoft Graph tutorial](https://docs.microsoft.com/graph/tutorials/python) and the [Python Microsoft Graph app-only tutorial](https://docs.microsoft.com/graph/tutorials/python-app-only).
66

77
## Running the sample
88

9-
The code for this sample is in the [demo](demo) folder. Instructions to configure and run the sample can be found in the [README](demo/README.md) in that folder.
9+
The code for the delegated user authentication sample is in the [user-auth](user-auth) folder. Instructions to configure and run the sample can be found in the [README](user-auth/README.md) in that folder.
10+
11+
The code for the app-only authentication sample is in the [app-auth](app-auth) folder. Instructions to configure and run the sample can be found in the [README](app-auth/README.md) in that folder.
1012

1113
## Code of conduct
1214

@@ -15,4 +17,3 @@ This project has adopted the [Microsoft Open Source Code of Conduct](https://ope
1517
## Disclaimer
1618

1719
**THIS CODE IS PROVIDED _AS IS_ WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.**
18-

app-auth/README.md

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
# How to run the completed project
2+
3+
## Prerequisites
4+
5+
To run the completed project in this folder, you need the following:
6+
7+
- [Python](https://www.python.org/) and [pip](https://pip.pypa.io/en/stable/) installed on your development machine. (**Note:** This tutorial was written with Python version 3.10.4 and pip version 20.0.2. The steps in this guide may work with other versions, but that has not been tested.)
8+
- A Microsoft work or school account with the **Global administrator** role.
9+
10+
If you don't have a Microsoft account, you can [sign up for the Microsoft 365 Developer Program](https://developer.microsoft.com/microsoft-365/dev-program) to get a free Microsoft 365 subscription.
11+
12+
## Register an application
13+
14+
You can register an application using the Azure Active Directory admin center, or by using the [Microsoft Graph PowerShell SDK](https://docs.microsoft.com/graph/powershell/get-started).
15+
16+
### Azure Active Directory admin center
17+
18+
1. Open a browser and navigate to the [Azure Active Directory admin center](https://aad.portal.azure.com) and login using a **personal account** (aka: Microsoft Account) or **Work or School Account**.
19+
20+
1. Select **Azure Active Directory** in the left-hand navigation, then select **App registrations** under **Manage**.
21+
22+
1. Select **New registration**. Enter a name for your application, for example, `Python Graph Tutorial`.
23+
24+
1. Set **Supported account types** to **Accounts in this organizational directory only**.
25+
26+
1. Leave **Redirect URI** empty.
27+
28+
1. Select **Register**. On the application's **Overview** page, copy the value of the **Application (client) ID** and **Directory (tenant) ID** and save them, you will need these values in the next step.
29+
30+
1. Select **API permissions** under **Manage**.
31+
32+
1. Remove the default **User.Read** permission under **Configured permissions** by selecting the ellipses (**...**) in its row and selecting **Remove permission**.
33+
34+
1. Select **Add a permission**, then **Microsoft Graph**.
35+
36+
1. Select **Application permissions**.
37+
38+
1. Select **User.Read.All**, then select **Add permissions**.
39+
40+
1. Select **Grant admin consent for...**, then select **Yes** to provide admin consent for the selected permission.
41+
42+
1. Select **Certificates and secrets** under **Manage**, then select **New client secret**.
43+
44+
1. Enter a description, choose a duration, and select **Add**.
45+
46+
1. Copy the secret from the **Value** column, you will need it in the next steps.
47+
48+
### PowerShell
49+
50+
To use PowerShell, you'll need the Microsoft Graph PowerShell SDK. If you do not have it, see [Install the Microsoft Graph PowerShell SDK](https://docs.microsoft.com/graph/powershell/installation) for installation instructions.
51+
52+
1. Open PowerShell and run the [RegisterAppForAppOnlyAuth.ps1](RegisterAppForAppOnlyAuth.ps1) file with the following command.
53+
54+
```powershell
55+
.\RegisterAppForAppOnlyAuth.ps1 -AppName "Python App-Only Graph Tutorial" -GraphScopes "User.Read.All"
56+
```
57+
58+
1. Copy the **Client ID**, **Tenant ID**, and **Client secret** values from the script output. You will need these values in the next step.
59+
60+
```powershell
61+
SUCCESS
62+
Client ID: ae2386e6-799e-4f75-b191-855d7e691c75
63+
Tenant ID: 5927c10a-91bd-4408-9c70-c50bce922b71
64+
Client secret: ...
65+
Secret expires: 10/28/2024 5:01:45 PM
66+
```
67+
68+
## Configure the sample
69+
70+
1. Update the values in [config.cfg](./graphtutorial/config.cfg) according to the following table.
71+
72+
| Setting | Value |
73+
|---------|-------|
74+
| `clientId` | The client ID of your app registration |
75+
| `clientSecret` | The client secret of your app registration |
76+
| `tenantId` | The tenant ID of your organization |
77+
78+
## Build and run the sample
79+
80+
In your command-line interface (CLI), navigate to the project directory and run the following command.
81+
82+
```Shell
83+
python3 -m pip install -r requirements.txt
84+
python3 main.py
85+
```
Original file line numberDiff line numberDiff line change
@@ -1,98 +1,113 @@
1-
# Copyright (c) Microsoft Corporation. All rights reserved.
2-
# Licensed under the MIT license.
3-
4-
# <ScriptBody>
5-
param(
6-
[Parameter(Mandatory=$true,
7-
HelpMessage="The app ID of the app registration")]
8-
[String]
9-
$AppId,
10-
11-
[Parameter(Mandatory=$true,
12-
HelpMessage="The application permission scopes to configure on the app registration")]
13-
[String[]]
14-
$GraphScopes,
15-
16-
[Parameter(Mandatory=$false)]
17-
[Switch]
18-
$StayConnected = $false
19-
)
20-
21-
$graphAppId = "00000003-0000-0000-c000-000000000000"
22-
23-
# Requires an admin
24-
Connect-MgGraph -Scopes "Application.ReadWrite.All AppRoleAssignment.ReadWrite.All User.Read" `
25-
-UseDeviceAuthentication -ErrorAction Stop
26-
27-
# Get context for access to tenant ID
28-
$context = Get-MgContext -ErrorAction Stop
29-
30-
# Get the application and service principal
31-
$appRegistration = Get-MgApplication -Filter ("appId eq '" + $AppId +"'") -ErrorAction Stop
32-
$appServicePrincipal = Get-MgServicePrincipal -Filter ("appId eq '" + $AppId + "'") -ErrorAction Stop
33-
34-
# Lookup available Graph application permissions
35-
$graphServicePrincipal = Get-MgServicePrincipal -Filter ("appId eq '" + $graphAppId + "'") -ErrorAction Stop
36-
$graphAppPermissions = $graphServicePrincipal.AppRoles
37-
38-
$resourceAccess = @()
39-
40-
foreach($scope in $GraphScopes)
41-
{
42-
$permission = $graphAppPermissions | Where-Object { $_.Value -eq $scope }
43-
if ($permission)
44-
{
45-
$resourceAccess += @{ Id = $permission.Id; Type = "Role"}
46-
}
47-
else
48-
{
49-
Write-Host -ForegroundColor Red "Invalid scope:" $scope
50-
Exit
51-
}
52-
}
53-
54-
# Add the permissions to required resource access
55-
Update-MgApplication -ApplicationId $appRegistration.Id -RequiredResourceAccess `
56-
@{ ResourceAppId = $graphAppId; ResourceAccess = $resourceAccess } -ErrorAction Stop
57-
Write-Host -ForegroundColor Cyan "Added application permissions to app registration"
58-
59-
# Add admin consent
60-
foreach ($appRole in $resourceAccess)
61-
{
62-
New-MgServicePrincipalAppRoleAssignment -ServicePrincipalId $appServicePrincipal.Id `
63-
-PrincipalId $appServicePrincipal.Id -ResourceId $graphServicePrincipal.Id `
64-
-AppRoleId $appRole.Id -ErrorAction SilentlyContinue -ErrorVariable SPError | Out-Null
65-
if ($SPError)
66-
{
67-
Write-Host -ForegroundColor Red "Admin consent for one of the requested scopes could not be added."
68-
Write-Host -ForegroundColor Red $SPError
69-
Exit
70-
}
71-
}
72-
Write-Host -ForegroundColor Cyan "Added admin consent"
73-
74-
# Add a client secret
75-
$clientSecret = Add-MgApplicationPassword -ApplicationId $appRegistration.Id -PasswordCredential `
76-
@{ DisplayName = "Added by PowerShell" } -ErrorAction Stop
77-
78-
Write-Host
79-
Write-Host -ForegroundColor Green "SUCCESS"
80-
Write-Host -ForegroundColor Cyan -NoNewline "Tenant ID: "
81-
Write-Host -ForegroundColor Yellow $context.TenantId
82-
Write-Host -ForegroundColor Cyan -NoNewline "Client secret: "
83-
Write-Host -ForegroundColor Yellow $clientSecret.SecretText
84-
Write-Host -ForegroundColor Cyan -NoNewline "Secret expires: "
85-
Write-Host -ForegroundColor Yellow $clientSecret.EndDateTime
86-
87-
if ($StayConnected -eq $false)
88-
{
89-
Disconnect-MgGraph
90-
Write-Host "Disconnected from Microsoft Graph"
91-
}
92-
else
93-
{
94-
Write-Host
95-
Write-Host -ForegroundColor Yellow `
96-
"The connection to Microsoft Graph is still active. To disconnect, use Disconnect-MgGraph"
97-
}
98-
# </ScriptBody>
1+
# Copyright (c) Microsoft Corporation. All rights reserved.
2+
# Licensed under the MIT license.
3+
4+
# <ScriptBody>
5+
param(
6+
[Parameter(Mandatory=$true,
7+
HelpMessage="The friendly name of the app registration")]
8+
[String]
9+
$AppName,
10+
11+
[Parameter(Mandatory=$true,
12+
HelpMessage="The application permission scopes to configure on the app registration")]
13+
[String[]]
14+
$GraphScopes,
15+
16+
[Parameter(Mandatory=$false)]
17+
[Switch]
18+
$StayConnected = $false
19+
)
20+
21+
$graphAppId = "00000003-0000-0000-c000-000000000000"
22+
23+
# Requires an admin
24+
Connect-MgGraph -Scopes "Application.ReadWrite.All User.Read" -UseDeviceAuthentication -ErrorAction Stop
25+
26+
# Get context for access to tenant ID
27+
$context = Get-MgContext -ErrorAction Stop
28+
$authTenant = $context.TenantId
29+
30+
# Create app registration
31+
$appRegistration = New-MgApplication -DisplayName $AppName -SignInAudience "AzureADMyOrg" -ErrorAction Stop
32+
Write-Host -ForegroundColor Cyan "App registration created with app ID" $appRegistration.AppId
33+
34+
# Create corresponding service principal
35+
$appServicePrincipal = New-MgServicePrincipal -AppId $appRegistration.AppId -ErrorAction SilentlyContinue `
36+
-ErrorVariable SPError
37+
if ($SPError)
38+
{
39+
Write-Host -ForegroundColor Red "A service principal for the app could not be created."
40+
Write-Host -ForegroundColor Red $SPError
41+
Exit
42+
}
43+
44+
Write-Host -ForegroundColor Cyan "Service principal created"
45+
46+
# Lookup available Graph application permissions
47+
$graphServicePrincipal = Get-MgServicePrincipal -Filter ("appId eq '" + $graphAppId + "'") -ErrorAction Stop
48+
$graphAppPermissions = $graphServicePrincipal.AppRoles
49+
50+
$resourceAccess = @()
51+
52+
foreach($scope in $GraphScopes)
53+
{
54+
$permission = $graphAppPermissions | Where-Object { $_.Value -eq $scope }
55+
if ($permission)
56+
{
57+
$resourceAccess += @{ Id = $permission.Id; Type = "Role"}
58+
}
59+
else
60+
{
61+
Write-Host -ForegroundColor Red "Invalid scope:" $scope
62+
Exit
63+
}
64+
}
65+
66+
# Add the permissions to required resource access
67+
Update-MgApplication -ApplicationId $appRegistration.Id -RequiredResourceAccess `
68+
@{ ResourceAppId = $graphAppId; ResourceAccess = $resourceAccess } -ErrorAction Stop
69+
Write-Host -ForegroundColor Cyan "Added application permissions to app registration"
70+
71+
# Add admin consent
72+
foreach ($appRole in $resourceAccess)
73+
{
74+
$appServicePrincipal
75+
New-MgServicePrincipalAppRoleAssignment -ServicePrincipalId $appServicePrincipal.Id `
76+
-PrincipalId $appServicePrincipal.Id -ResourceId $graphServicePrincipal.Id `
77+
-AppRoleId $appRole.Id -ErrorAction SilentlyContinue -ErrorVariable SPError | Out-Null
78+
if ($SPError)
79+
{
80+
Write-Host -ForegroundColor Red "Admin consent for one of the requested scopes could not be added."
81+
Write-Host -ForegroundColor Red $SPError
82+
Exit
83+
}
84+
}
85+
Write-Host -ForegroundColor Cyan "Added admin consent"
86+
87+
# Add a client secret
88+
$clientSecret = Add-MgApplicationPassword -ApplicationId $appRegistration.Id -PasswordCredential `
89+
@{ DisplayName = "Added by PowerShell" } -ErrorAction Stop
90+
91+
Write-Host
92+
Write-Host -ForegroundColor Green "SUCCESS"
93+
Write-Host -ForegroundColor Cyan -NoNewline "Client ID: "
94+
Write-Host -ForegroundColor Yellow $appRegistration.AppId
95+
Write-Host -ForegroundColor Cyan -NoNewline "Tenant ID: "
96+
Write-Host -ForegroundColor Yellow $authTenant
97+
Write-Host -ForegroundColor Cyan -NoNewline "Client secret: "
98+
Write-Host -ForegroundColor Yellow $clientSecret.SecretText
99+
Write-Host -ForegroundColor Cyan -NoNewline "Secret expires: "
100+
Write-Host -ForegroundColor Yellow $clientSecret.EndDateTime
101+
102+
if ($StayConnected -eq $false)
103+
{
104+
Disconnect-MgGraph
105+
Write-Host "Disconnected from Microsoft Graph"
106+
}
107+
else
108+
{
109+
Write-Host
110+
Write-Host -ForegroundColor Yellow `
111+
"The connection to Microsoft Graph is still active. To disconnect, use Disconnect-MgGraph"
112+
}
113+
# </ScriptBody>
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
[azure]
2+
clientId = YOUR_CLIENT_ID_HERE
3+
clientSecret = YOUR_CLIENT_SECRET_HERE
4+
tenantId = YOUR_TENANT_ID_HERE

0 commit comments

Comments
 (0)