I am updating a Powershell script to replace use of Azure CLI calls with PowerShell commands. The Powershell script creates a number of App Registrations in an Azure tenant, adds permissions to them, and then grants access to those permissions.
I am finding it difficult to replace the CLI calls granting access. Typically these calls grant a service principal access with a scope or scopes, e.g.
az ad app permission grant --id $app.appId --api 00000003-0000-0000-c000-000000000000 --scope "offline_access openid"
I see no way to do this with the Cmdlets in the Azure Resources Module, and have not been to find a direct equivalent in the Azure Graph API. The nearest thing I have found in the Graph API is an endpoint for granting an App Role Assignment (https://learn.microsoft.com/en-us/graph/api/serviceprincipal-post-approleassignedto?view=graph-rest-1.0&tabs=powershell) but that addresses a different problem, assigning roles rather than scopes.
I'm pretty new to Azure development, but I've been knocking my head off this one for a few days now, so any advice would be appreciated!
Edit: Adding an example of a permission I'd like to be able to grant where Admin Consent is not required.
We have tested this in our local environment it is working fine. Below statements are based on our analysis.
You can use the below PowerShell cmdlet to add a permission to the app registration.
Add-AzADAppPermission -ObjectId "<objectID>" -ApiId "00000003-0000-0000-c000-000000000000" -PermissionId "<PermissionId>" -Type "<role(ApplicationPermissions),Scope(DelagatedPermissions)"
Here is the sample Output screenshot for reference:
As per the Current documentation, User needs to grant consent via Azure Portal if the permission requires admin consent because Azure PowerShell doesn't support it yet.
Note :
Application permissions under the appRoles property correspond to Role in -Type. Delegated permissions under the oauth2Permissions property correspond to Scope in -Type.
Related
We have an Azure PowerShell script to automate the provisioning of resources in our customers' subscription. As part of the process we deploy a VM based off a custom image hosted in our own image gallery. In order to do so we require our customers to grant access (user consent) to our enterprise application in their tenants.
As of now we achieve that through an OAuth2 link that we ask them to edit with their own tenant ID and open in browser:
https://login.microsoftonline.com/<customer-tenant-id>/oauth2/authorize?client_id=cd3df191-153a-4ae1-9766-5fe7a7f3032e&response_type=code&redirect_uri=https%3A%2F%2Fwww.microsoft.com
This link authenticates them and asks for the requested permissions to be accepted:
After that, our enterprise application should be listed in their subscriptions with the following permissions:
We would like for this pre-requisite to be addressed programmatically by our deployment script. Is there any way we can achieve that via Azure PowerShell?
To no avail, I've checked quite a few pages online and several similar questions here on SO. They are different in the sense that they are requesting Admin Consent rather than User Consent (mind that ours only require User Consent, see screenshot below). Also, some questions are specific to Azure CLI or simply Azure Portal (not an option for us as we are working with Azure PowerShell).
PS: Sorry in advance for my lack of knowledge in regards to Azure AD and the Consent Framework in general.
Consent can be used to grant app roles (application permissions) and delegated permissions.
What you're trying to do here is to create a delegated permission grant. Specifically, you're trying to grant a delegated permission on behalf of an individual user (instead of on behalf of all users).
You can't do this with Azure PowerShell.
You can, however, do this with Microsoft Graph PowerShell. The cmdlet you use, will be New-MgOauth2PermissionGrant. This cmdlet calls the Microsoft Graph API to create a delegated permission grant. The PowerShell cmdlet requires the following parameters:
ClientId - The object ID of the client app's service principal. This is the service principal which will be gaining privileges.
ConsentType - In this case, this should be "Principal", indicating you want to grant this delegated permission on behalf of a single principal (a user).
PrincipalId - This is the object ID of the user on behalf of who the client app will be able to act.
ResourceId - The object ID of the API's service principal. This is the service principal representing the API that exposes the delegated permissions you want to grant.
Scope - The space-separated list of permissions to grant.
So, for example, if we wanted to grant the Microsoft Graph delegated permission User.Read, on behalf of user with user principal name bob#example.com, we could do the following:
$userUpn = "bob#example.com"
$clientAppId = "738a2731-dd81-4263-824b-74cf6dee9da0"
$resourceSpn = "https://graph.microsoft.com"
$scope = "User.Read"
# Retrieve the user, and the client and resource service principals
$user = Get-MgUser -Filter "userPrincipalName eq '$userUpn'"
$client = Get-MgServicePrincipal -Filter "appId eq '$clientAppId'"
$resource = Get-MgServicePrincipal -Filter "servicePrincipalNames/any(n:n eq '$resourceSpn')"
# Grant the delegated permissions for Microsoft Graph to the client, on behalf of the user
$grant = New-MgOAuth2PermissionGrant `
-ClientId $client.Id `
-ConsentType "Principal" `
-PrincipalId $user.Id `
-ResourceId $resource.Id `
-Scope $scope
I need to register an application in Azure AD using PowerShell. I plan to use the New-AzADApplication cmdlet. The cmdlet documentation states the following:
Below are the permissions needed to create an application:
Azure Active Directory Graph
Application.ReadWrite.OwnedBy
Microsoft Graph
Directory.AccessAsUser.All
Directory.ReadWrite.All
I've learned that these permissions are scopes, which is a new concept to me and something I don't know how to deal with in Azure. I found this short demo, which shows these scopes can be managed as API permissions from the Azure App registration context. However, that demo shows the scopes being managed after the application has already been created. How can I establish the proper scopes before the application is created?
Or, more generally, how can I ensure that I have the appropriate permissions to execute the New-AzADApplication cmdlet?
The application that needs those permissions is Azure AD PowerShell in this case. If it didn't have a service principal in your AAD tenant yet, you would be asked for consent to those scopes on first login when using the Connect-AzureAD cmdlet.
In my experience, the service principal that it uses already exists in your tenant. So it already has the needed permissions. But what will also matter is your user permissions. Since it uses delegated permissions, it is acting on behalf of your user. In order for it to be able to create the app, it needs to have the necessary scope/delegated permission and your user must be able to create applications.
The cmdlets do also support acting as a service principal/app, in which case application permissions given to the app used to authenticate would apply, not delegated permissions. But that's another case that I don't think you are asking about.
Applications are able to note which permissions they require (both delegated and application) in the app registration portal. This allows use of the /.default scope and the Azure portal's "Grant admin consent" option.
You can follow this process:
1.Go to your application in the Azure portal – App registrations experience, or create an app if you haven't already.
2.Locate the API Permissions section, and within the API permissions
click Add a permission.
3.Select Microsoft Graph from the list of available APIs and then add
the permissions that your app requires.
4.Save the app registration.
We have Azure AD app configured to access to multiple organization resources (hidden with mask) (custom resources, like Contoso Service).
We would like to add one more resource to be part of this setup.
Can anyone please guide me or share link to documentation: how this custom permission should be configured to appear in the list in Azure AD configuration dashboard?
When you go through the experience to add a new required permission, the portal is looking at all the ServicePrincipal objects in your Azure AD tenant. For each ServicePrincipal object, it then looks at the AppRoles and OAuth2Permissions attributes, to see if the application represented by that ServicePrincipal object is publishing any application permissions or delegated permissions, respectively.
So, in order to see a resource in the list of available resources (i.e. APIs), you first need to ensure there exists a ServicePrincipal object for that resource, in your Azure AD tenant (i.e. in the Azure AD tenant where you are creating the client app's app registration).
A ServicePrincipal object for an app will usually be created in your Azure AD tenant when you (or someone else in your tenant) signs in to and consents to the permissions being requested by the app. If the ServicePrincipal object doesn't exist in your tenant, you can create it manually by referencing the resource app's AppId.
With Azure AD PowerShell:
New-AzureADServicePrincipal -AppId "{app-id}"
With Azure CLI:
az ad sp create --id "{app-id}"
Directly with Azure AD Graph (e.g. with Azure AD Graph Explorer):
POST https://graph.windows.net/myorganization/servicePrincipals
{ "appId": "{app-id}" }
Directly with Microsoft Graph (beta) (e.g. with Microsoft Graph Explorer):
POST https://graph.microsoft.com/beta/servicePrincipals
{ "appId": "{app-id}" }
Once the ServicePrincipal object has been created in your tenant, if it publishes AppRoles or OAuth2Permissions, you should see it listed in the app registration experience, when choosing which permission your app requires.
Note 1: Some of the behavior described differs for ServicePrincipal objects referrencing Microsoft apps and service.
Note 2: Once a ServicePrincipal object exists in your Azure AD tenant, it is possible for whoever owns the backing app registration to authenticate (as the app) in your tenant and obtain an access token. This in itself does not grant the app access to anything (at least not for Microsoft services), but it is easier at this point for a user to accidentally (or intentionally) grant that app access to your organization's resources (e.g. in Azure, for example, the app will show up in the list of users, groups or apps which can be granted access to a subscription's resources).
My requirement is simple. I want to login to Azure through my shell script in non-interactive mode, but "az login -u username -p password" command gives the following error:
Get Token request returned http error: 400 and server response: {"error":"invalid_grant","error_description":"AADSTS70002: Error validating credentials. : SAML token is invalid. : The element with ID 'xxxxxx' was either unsigned or the signature was invalid.
Some site told me to create a service principal. Now my question is, what is a service principal, and how do I create a service principal so that I can execute my commands (for creating different resources like app gateway) from my shell script?
Please refer to this official document.
An Azure service principal is a security identity used by user-created
apps, services, and automation tools to access specific Azure
resources. Think of it as a 'user identity' (login and password or
certificate) with a specific role, and tightly controlled permissions
to access your resources. It only needs to be able to do specific
things, unlike a general user identity. It improves security if you
only grant it the minimum permissions level needed to perform its
management tasks.
If you want to create a new service principal(sp) with Azure CLi 2.0. You could login with your Azure AD user. Then execute following command.
az ad sp create-for-rbac --name {appId} --password "{strong password}"
The result like below:
{
"appId": "a487e0c1-82af-47d9-9a0b-af184eb87646d",
"displayName": "MyDemoWebApp",
"name": "http://MyDemoWebApp",
"password": {strong password},
"tenant": "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"
}
appId is your login user, password is login password.
After the sp is created, you also need give it Contributor role, then you could manage your Azure resource.
az role assignment create --assignee <objectID> --role Contributor
Now, you could login in non interctive mode with following command.
az login --service-principal -u <appid> --password {password-or-path-to-cert} --tenant {tenant}
Service principal just work as an impersonation for user in Azure AD. Refer - https://sanganakauthority.blogspot.com/2019/04/how-to-create-service-principal-or-app.html
Using this you can perform any type of management task against Azure using REST APIs. This way you avoid need of providing credentials in pop up and hence help to automate things in Azure using REST APIs.
Here your go: Use portal to create an Azure Active Directory application and service principal that can access resources.
When you have an application that needs to access or modify resources, you must set up an Azure Active Directory (AD) application and assign the required permissions to it. This approach is preferable to running the app under your own credentials because:
You can assign permissions to the app identity that are different than your own permissions. Typically, these permissions are restricted to exactly what the app needs to do.
You do not have to change the app's credentials if your responsibilities change.
You can use a certificate to automate authentication when executing an unattended script.
So I am trying to set up an application on azure AD that can, among other things delete users.
I have the application registered and use the client id and secert to gain teh access token.
I was able to give the application permissions to create users and that works fine, but when i go to delete over the graph API i get a 403 Insufficient privileges to complete the operation.
I am trying this over the graph rest API. The user that i am attempting to delete was made through the rest call as well. The user is in the same tenant as the application , so i am not trying to delete users from multiple tenants.
It seems what i need to do is give the application either Global admin or Company admin rights, but i am spinning wheels on where and or how to do this.
Any help would be appreciated.
Take a look at my answer here.
You can elevate the level of access an Application has in your tenant
by adding the service principal of that application to the Company Administrator Directory Role. This will give the Application the same
level of permissions as the Company Administrator, who can do
anything. You can follow these same instructions for any type of
Directory Role depending on the level of access you want to give to
this application.
Note that this will only affect the access your app has in your tenant.
Also you must already be a Company Administrator of the tenant to follow these instructions.
In order to make the change, you will need to install the Azure
Active Directory PowerShell
Module.
Once you have the module installed, authenticate to your tenant with
your Administrator Account:
Connect-MSOLService
Then we need to get the Object ID of both the Service Principal we
want to elevate, and the Company Administrator Role for your tenant.
Search for Service Principal by App ID GUID:
$sp = Get-MsolServicePrincipal -AppPrincipalId <App ID GUID>
Search for Directory Role by Name
$role = Get-MsolRole -RoleName "Company Administrator"
Now we can use the Add-MsolRoleMember command to add this role to
the service principal.
Add-MsolRoleMember -RoleObjectId $role.ObjectId -RoleMemberType ServicePrincipal -RoleMemberObjectId $sp.ObjectId
To check everything is working, lets get back all the members of the
Company Administrator role:
Get-MsolRoleMember -RoleObjectId $role.ObjectId
You should see your application in that list, where RoleMemberType
is ServicePrincipal and DisplayName is the name of your
application.
Now your application should be able to perform any Graph API calls
that the Company Administrator could do, all without a user signed-in,
using the Client Credential Flow.
Let me know if this helps!
UPDATE:
The answer above has been updated to use Azure Active Directory V2 PowerShell
If you don't have the AzureAD module already installed you will need to install it. See Azure Active Directory PowerShell Module Version for Graph for Azure AD administrative tasks for more info about the module or simply run:
Install-Module AzureAD
Once you have the module installed, authenticate to your tenant with your Administrator Account:
Connect-AzureAD
Then we need to get the Service Principal we want to elevate, and the Company Administrator Role for your tenant.
$sp = Get-AzureRmADServicePrincipal | Where DisplayName -eq '<service-principal-name>'
Search for Directory Role by Name
$role = Get-AzureADDirectoryRole | Where DisplayName -eq 'Company Administrator'
Now we can use the Add-AzureADDirectoryRoleMember command to add this role to the service principal.
Add-AzureADDirectoryRoleMember -ObjectId $role.ObjectId -RefObjectId $sp.Id
To check everything is working, lets get back all the members of the Company Administrator role:
Get-AzureADDirectoryRoleMember -ObjectId $role.ObjectId
You should see your application in that list, where DisplayName is the name of your application.
Now your application should be able to perform any Graph API calls that the Company Administrator could do, all without a user signed-in, using the Client Credential Flow.