-
Notifications
You must be signed in to change notification settings - Fork 7
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #211 from microsoftgraph/dkershaw10-new-samples
New quickstart for app config and scope grants
- Loading branch information
Showing
5 changed files
with
219 additions
and
0 deletions.
There are no files selected for viewing
56 changes: 56 additions & 0 deletions
56
quickstart-templates/apps-permissions-and-grants/README.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
# Configure an app with OAuth2.0 scopes to call Microsoft Graph | ||
|
||
This template sample creates a client application and depending on the mode parameter, either: | ||
|
||
1. Sets required resource access on the client application definition, or | ||
2. Grants OAuth2.0 scopes to the client application. | ||
|
||
In either case, the target resource used is Microsoft Graph, and the deployer can select which Microsoft Graph OAuth2.0 scopes are used. | ||
|
||
## Details | ||
|
||
This sample operates in two modes, depending on the `mode` parameter. | ||
|
||
1. `set-required-scopes`: | ||
|
||
- The sample creates a basic client application configuring the `requiredResourceAccess` property with Microsoft Graph Oauth2.0 scopes | ||
- This option uses the appRequiredResourceAccess.bicep module. | ||
- **NOTE:** The `requiredResourceAccess` configures which permissions the client application requires and this drives the **user consent experience** where those permissions can be granted. `requiredResourceAccess` itself does **not** grant any permissions to the client application. | ||
|
||
2. `grant-scopes`: | ||
|
||
- The sample creates a basic client application (and does not configure `requiredResourceAccess`), creates a service principal from the application, and finally grants the desired Microsoft Graph OAuth2.0 scopes to the service principal (using the `Microsoft.Graph/oauth2PermissionGrants` bicep type). | ||
- This option uses the appGrantScopes.bicep module. | ||
- **NOTE:** Setting `requiredResourceAccess` on a client application is **not** required to grant OAuth2.0 scopes to the client application. | ||
|
||
The `appScopes` array parameter allows the deployer to select the Microsoft Graph Oauth2.0 scopes to set for or grant to the client application. The sample validates the set of provided scopes in the array parameter against [Microsoft Graph delegated permission scopes][graph-permissions]. Any invalid scopes provided are ignored. `appScores` should contain a list of scope names (for example *User.Read.All* and *Group.ReadWrite.All*). | ||
|
||
### Prerequisites | ||
|
||
- A valid **Azure subscription**: If you don't own an Azure subscription, [create a free account](https://azure.microsoft.com/free/) before you begin. | ||
- An **Azure resource group** that you own under a valid Azure subscription, or [deploy without an Azure subscription][no-azure-sub]. | ||
- [Bicep tools for authoring and deployment](https://learn.microsoft.com/graph/templates/quickstart-install-bicep-tools). The minimum required Bicep version is v0.30.3. | ||
- Have the requisite **Microsoft Entra roles** to deploy this template: | ||
|
||
- Permissions to create applications. [Users have this permission by default](https://learn.microsoft.com/entra/fundamentals/users-default-permissions#compare-member-and-guest-default-permissions). However, [admins can turn off this default](https://learn.microsoft.com/entra/fundamentals/users-default-permissions#restrict-member-users-default-permissions) in which case you need to be assigned at least the [Application Developer](https://learn.microsoft.com/entra/identity/role-based-access-control/permissions-reference#application-developer) role. | ||
- **Additionally**, if using the `grant-scopes` mode, you'll also need the privileges to grant Microsoft Graph app roles to the application. This requires the [Privileged Role Administrator][priv-role-admin] | ||
|
||
### Deploy the Bicep template | ||
|
||
By default, the Bicep template (main.bicep) will operate in the `set-required-scopes` mode. | ||
|
||
#### Az CLI | ||
|
||
```sh | ||
az deployment group create --resource-group <resource-group> --template-file main.bicep --parameter date='2025-01-24' appScopes="['User.Read','Application.Read.All']" | ||
``` | ||
|
||
#### Az Powershell | ||
|
||
```powershell | ||
New-AzResourceGroupDeployment -ResourceGroupName <resource-group> -TemplateFile .\main.bicep -date "2025-01-24" -appScopes @('User.Read','Application.Read.All') | ||
``` | ||
|
||
[priv-role-admin]:https://learn.microsoft.com/entra/identity/role-based-access-control/permissions-reference#privileged-role-administrator | ||
[graph-permissions]:https://learn.microsoft.com/graph/permissions-reference | ||
[no-azure-sub]:https://learn.microsoft.com/graph/templates/how-to-deploy-without-azure-sub?view=graph-bicep-1.0&tabs=CLI |
48 changes: 48 additions & 0 deletions
48
quickstart-templates/apps-permissions-and-grants/appGrantScopes.bicep
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
extension microsoftGraphV1 | ||
|
||
// TEMPLATE DESCRIPTION | ||
/* Grant OAuth2.0 scopes to a client application definition, | ||
where the target resource used is Microsoft Graph, and the deployer can select which | ||
Microsoft Graph OAuth2.0 scopes are granted on the client app. | ||
NOTE: Setting requiredResourceAccess on a client application is NOT required | ||
to grant OAuth2.0 permissions to the client application. | ||
*/ | ||
|
||
param date string | ||
param displayName string? | ||
param filteredScopes array | ||
param graphSpId string | ||
|
||
var app = 'myApp' | ||
|
||
// convert scopes array into space separate scopes string | ||
var scopeArray = [for (scopeItem,i) in filteredScopes: filteredScopes[i].value] | ||
var scopeString = join(scopeArray, ' ') | ||
|
||
// create basic app | ||
resource myApp 'Microsoft.Graph/[email protected]' = { | ||
displayName: displayName == null ? '${app}-${date}' :'${displayName}-${app}-${date}' | ||
uniqueName: uniqueString(app, date) | ||
} | ||
|
||
// Create service principal for the basic app | ||
resource mySP 'Microsoft.Graph/[email protected]' = { | ||
appId: myApp.appId | ||
} | ||
|
||
// Grant the OAuth2.0 scopes (requested in parameters) to the basic app, | ||
// for all users in the tenant | ||
resource graphScopesAssignment 'Microsoft.Graph/[email protected]' = { | ||
clientId: mySP.id | ||
resourceId: graphSpId | ||
consentType: 'AllPrincipals' | ||
scope: scopeString | ||
} | ||
|
||
// output information | ||
output appName string = myApp.displayName | ||
output appObjectID string = myApp.id | ||
output appID string = myApp.appId | ||
output scopes array = scopeArray | ||
output grantedScopes string = graphScopesAssignment.scope |
42 changes: 42 additions & 0 deletions
42
quickstart-templates/apps-permissions-and-grants/appRequiredResourceAccess.bicep
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
extension microsoftGraphV1 | ||
|
||
// TEMPLATE DESCRIPTION | ||
/* Set the required resource access on a client application definition. | ||
The target resource used is Microsoft Graph, and the deployer can select which | ||
Microsoft Graph OAuth2.0 scopes are configured on the client app. | ||
NOTE: requiredResourceAccess configures which permissions the client application | ||
requires and this drives the user consent experience where permissions are granted. | ||
requiredResourceAccess itself does NOT grant any permissions to the client application. | ||
*/ | ||
|
||
param date string | ||
param displayName string? | ||
param filteredScopes array | ||
|
||
var app = 'myApp' | ||
var graphAppId = '00000003-0000-0000-c000-000000000000' | ||
|
||
// create an application with the requiredResourceAccess property | ||
// creates a resourceAccess scope for each Microsoft Graph scope in filteredScopes | ||
resource myApp 'Microsoft.Graph/[email protected]' = { | ||
displayName: displayName == null ? '${app}-${date}' :'${displayName}-${app}-${date}' | ||
uniqueName: uniqueString(app, date) | ||
requiredResourceAccess: [ | ||
{ | ||
resourceAppId: graphAppId | ||
resourceAccess: [ for (scope, i) in filteredScopes: { | ||
id: filteredScopes[i].id | ||
type: 'Scope' | ||
} | ||
] | ||
} | ||
] | ||
} | ||
|
||
// output information | ||
output appName string = myApp.displayName | ||
output appObjectID string = myApp.id | ||
output appID string = myApp.appId | ||
output scopes array = [for (scopeItem,i) in filteredScopes: filteredScopes[i].value] | ||
output clientAppResourceAccessList array = myApp.requiredResourceAccess[0].resourceAccess |
9 changes: 9 additions & 0 deletions
9
quickstart-templates/apps-permissions-and-grants/bicepconfig.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
{ | ||
"experimentalFeaturesEnabled": { | ||
"extensibility": true | ||
}, | ||
// specify an alias for the version of the v1.0 dynamic types package you want to use | ||
"extensions": { | ||
"microsoftGraphV1": "br:mcr.microsoft.com/bicep/extensions/microsoftgraph/v1.0:0.1.9-preview" | ||
} | ||
} |
64 changes: 64 additions & 0 deletions
64
quickstart-templates/apps-permissions-and-grants/main.bicep
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
extension microsoftGraphV1 | ||
|
||
// TEMPLATE DESCRIPTION | ||
/* Create a client application and depending on the mode parameter, either: | ||
1. Sets required resource access on the client application definition OR | ||
2. Grants OAuth2.0 scopes to the client application | ||
In either case, the target resource used is Microsoft Graph, and the deployer | ||
can select which Microsoft Graph OAuth2.0 scopes are used. | ||
This bicep file utilizes two modules (one for each mode). | ||
*/ | ||
|
||
@description('Supply today\'s date to deploy the template') | ||
param date string | ||
|
||
@description('Provide a friendly display name for the app') | ||
param displayName string? | ||
|
||
@description('Provide an array of Microsoft Graph scopes like "User.Read"') | ||
param appScopes array = ['profile','User.Read'] | ||
|
||
@description('Configure is setting required resource access or granting scopes') | ||
@allowed(['set-required-scopes','grant-scopes']) | ||
param mode string = 'set-required-scopes' | ||
|
||
var graphAppId = '00000003-0000-0000-c000-000000000000' | ||
|
||
// Get the Microsoft Graph service principal so that the scope names | ||
// can be looked up and mapped to a permission ID | ||
resource msGraphSP 'Microsoft.Graph/[email protected]' existing = { | ||
appId: graphAppId | ||
} | ||
|
||
var graphScopes = msGraphSP.oauth2PermissionScopes | ||
var filteredScopes = filter(graphScopes, scope => contains(appScopes, scope.value)) | ||
|
||
|
||
module appCreateRraModule './appRequiredResourceAccess.bicep' = if(mode == 'set-required-scopes'){ | ||
name: 'appRraDeploy' | ||
params: { | ||
filteredScopes: filteredScopes | ||
date: date | ||
displayName: displayName | ||
} | ||
} | ||
|
||
module appCreateGrantScopesModule './appGrantScopes.bicep' = if (mode == 'grant-scopes') { | ||
name: 'appScopeGrantDeploy' | ||
params: { | ||
filteredScopes: filteredScopes | ||
date: date | ||
displayName: displayName | ||
graphSpId: msGraphSP.id | ||
} | ||
} | ||
|
||
// outputs | ||
output appName string = ((mode == 'set-required-scopes') ? appCreateRraModule.outputs.appName : appCreateGrantScopesModule.outputs.appName) | ||
output appObjectID string = ((mode == 'set-required-scopes') ? appCreateRraModule.outputs.appObjectID : appCreateGrantScopesModule.outputs.appObjectID) | ||
output appID string = ((mode == 'set-required-scopes') ? appCreateRraModule.outputs.appID : appCreateGrantScopesModule.outputs.appID) | ||
output foundInputScopes array = ((mode == 'set-required-scopes') ? appCreateRraModule.outputs.scopes: appCreateGrantScopesModule.outputs.scopes) | ||
output clientAppResourceAccessList array = ((mode == 'set-required-scopes') ? appCreateRraModule.outputs.clientAppResourceAccessList : ['Not set']) | ||
output grantedScopes string = ((mode == 'grant-scopes') ? appCreateGrantScopesModule.outputs.grantedScopes : 'Not set') |