Why doesn't Azure REST API to assign user role to a subscription work? - azure

I am trying to add a user role to a subscription in Azure using REST API following this documentation.
I got a bearer token with my login and passed it as a header Authorization parameter.
Gave all the values as described in the doc
PFA REST API call I performed.
API response says below;
{
"error": {
"code": "AuthenticationFailed",
"message": "Authentication failed."
}
}
Please let me know if any one successfully used this API and performed operations. Also is there any Azure .NET API to this operation?
REST API Postman request

The error means your user account does not have the permission to create the role assignment, specifically Microsoft.Authorization/roleAssignments/write.
To solve the issue, you need to ask the admin who is the Owner or User Access Administrator(or custom RBAC role with Microsoft.Authorization/roleAssignments/write permission) of your subscription to assign the Owner or User Access Administrator or custom role with the permission above for you at the subscription scope first, follow this link, then get a new token, you will be able to assign the role to others like the admin assign the role to you i.e. create role assignment.
Update:
If you want to get the access token via your user credential, you could use the auth code flow, please follow the steps below.
1.In your App registration, add the user_impersonation Delegated permission of Azure Service Management API.
2.Hit the URL below in the browser, change the tenant-id, client-id, redirect_uri to yours, login your user account.
https://login.microsoftonline.com/tenant-id/oauth2/v2.0/authorize?
client_id=xxxxxxxx
&response_type=code
&redirect_uri=http://localhost
&response_mode=query
&scope=https://management.azure.com/.default
&state=12345
Then you will get a code like below, copy it.
Don't forget to remove the state and session_state.
3.In the postman, use the query below, then you can get the token.

Related

Microsoft Azure - Assigning Microsoft Graph permissions to a regular user doesn't work

I understand the process of assigning Microsoft Graph permissions to a service principal. I can take the object id of the Microsoft Graph app, then use the https://graph.microsoft.com/v1.0/servicePrincipals/<id>/appRoleAssignedTo MSGraph endpoint, like described here.
My question is: can I do the same with a regular user? That is, when calling appRoleAssignedTo, specify the object id of a user in the principalId field. Can a regular user have application permissions (like MSGraph permissions), and how do I use them afterwards?
I tried to do the above and assign the RoleManagement.ReadWrite.Directory to a user. Then I logged in with az login and ran az account get-access-token --resource-type ms-graph.
With this token I tried to do an operation that requires the RoleManagement.ReadWrite.Directory permission, like assigning a role to another user, but it fails with Insufficient privileges to complete the operation..
Users can request the scope they need when using Connect-MgGraph, for example:
Connect-MgGraph -Scopes "RoleManagement.ReadWrite.Directory"
Which is the recommended approach, as it means that for that session they will only have access to the scopes that are necessary rather than any they've previously requested
I tried to reproduce the same in my environment and got the same error as below:
Note that: Microsoft Graph API permissions can be assigned only to Service principals not users directly.
When I tried to Connect-MgGraph as a normal user, I got the error like below:
Connect-MgGraph -Scopes "RoleManagement.ReadWrite.Directory"
I created an Azure AD Application and granted API permission as below:
I generated access token by using below parameters:
GET https://login.microsoftonline.com/1810a95e-99f3-46e0-84e8-8a2aee05d830/oauth2/v2.0/token
client_id:ClientID
client_secret:*****
scope:RoleManagement.ReadWrite.Directory
grant_type:authorization_code
redirect_uri:RedirectUri
code:code
By using the above access token, I am able to assign directory role to the user successfully as below:
POST https://graph.microsoft.com/v1.0/directoryRoles/roleTemplateId=88d8e3e3-8f55-4a1e-953a-9b9898b8876b/members/$ref
Content-type: application/json
{
"#odata.id": "https://graph.microsoft.com/v1.0/directoryObjects/UserID"
}
Reference:
Add graph api permission to user account by Harpreet Singh Matharoo

Microsoft Azure OAuth Client Credentials Token gets "AuthorizationFailed" response

I want create APIM subscriptions through rest api, And was able to do it successfully by following this Microsoft doc, https://learn.microsoft.com/en-us/rest/api/apimanagement/current-ga/subscription.
And for Authentication I am generating a bearer token using ROPC grant type(My UserName & Password). Everything works fine with this flow.
But i dont want to configure my username & password in a application to get a bearer token, instead i followed Client-Credentials grant type(get token by client id & secret), i am able to generate token, but when i use that token to create subscription in APIM, i am getting a exception
The client '0--e' with object id '0--e' does not have authorization to perform action 'Microsoft.ApiManagement/service/subscriptions/write'
Is it possible to add a AAD application inside APIM AccessControl(IAM) to grant permission.
Or is this any other way to do this? or ROPC is the only way?
Can someone please help.
Yes, you can grant permission to AAD application (service principal) in APIM Access Control (IAM) by assigning it API Management Service Contributor role.
I tried to reproduce the same in my environment and got the below results:
I have generated one access token using Client-Credentials grant type like below:
When I used the above token to create APIM subscription with below query, I got the same error:
PUT https://management.azure.com/subscriptions/subid/resourceGroups/rg1/providers/Microsoft.ApiManagement/service/apimService1/subscriptions/testsub?api-version=2021-12-01
{
"properties": {
"ownerId": "/subscriptions/subid/resourceGroups/rgname/providers/Microsoft.ApiManagement/service/servicename/users/xxxxxxxxxxx",
"scope": "/subscriptions/subid/resourceGroups/rgname/providers/Microsoft.ApiManagement/service/servicename/products/xxxxxxxxxxx",
"displayName": "testsub"
}
}
Response:
To resolve the error, you need to grant API Management Service Contributor role for that application like below:
Go to Azure Portal -> APIM Services -> Your APIM -> Access control (IAM) -> Add role assignment
After granting the above role, I generated the access token again and ran the same query as below:
PUT https://management.azure.com/subscriptions/subid/resourceGroups/rg1/providers/Microsoft.ApiManagement/service/apimService1/subscriptions/testsub?api-version=2021-12-01
Response:
When I checked the Portal, APIM subscription got created successfully like below:
Reference:
How to use Role-Based Access Control in Azure API Management | Microsoft Docs

Why aren't the application permissions being added to my MS Graph token?

I'm trying to get a subscription created with the callRecord resource (https://learn.microsoft.com/en-us/graph/api/subscription-post-subscriptions?view=graph-rest-beta&tabs=http)
In the app registration section of the Azure portal, I've created a multi-tenant app with a client secret. That app has permissions for application-level "CallRecords.Read.All" as well as the default delegated "User.Read". The statuses also have a green checkbox for being granted against my organization by an admin.
I am able to get an access token with the following HTTP POST request to https://login.microsoftonline.com/common/oauth2/v2.0/token:
grant_type:authorization_code
scope:https://graph.microsoft.com/.default
client_secret:<client_secret>
client_id:<client_id>
code:<code>
redirect_uri:http://localhost:3000
However, that token is not able to generate a subscription to my callRecord resource. I get a response with this message: "Operation: Create; Exception: [Status Code: Forbidden; Reason: The request is not authorized for this user or application.]"
The message suggests that the app has not been granted admin-level authorization, but in fact it has. This used to work for me. I'm wondering if there has been a regression on the MS Graph side.
Further, when I examine the JWT, I see that the scope is "User.Read profile openid email". There is no mention of the application-level permission (specifically, CallRecords.Read.All)
Thanks.
Because when you use the auth code flow, just the Delegated permission will take effect. So even if you grant the Application permission, the token you got will not include the permission.
From the doc, to call this API Get callRecord, just the Application permission is supported.
To get the token which include the permission, your option is to use the client credential flow.
Note: You need to use <tenant-id> instead of common in this flow.
POST https://login.microsoftonline.com/<tenant-id>/oauth2/v2.0/token
client_id=xxxxxxx
&scope=https://graph.microsoft.com/.default
&client_secret=xxxxxxx
&grant_type=client_credentials
Decode the token in https://jwt.io, the roles includes the CallRecords.Read.All permission:

What scope for Azure resource management with the device authorization grant type?

I'm building a CLI app for provisioning Azure resources. Previously I was using the authorization code flow with the resource set to https://management.azure.com/. Now, I would like to switch to using the RFC 8628 device authorization grant type (Azure documentation). I can successfully login with scopes like openid profile. However, when I use a scope like https://management.azure.com I get an error:
{
"error": "invalid_scope",
"error_description": "AADSTS70011: The provided request must include a 'scope' input parameter. The provided value for the input parameter 'scope' is not valid. The scope openid https://management.azure.com/ is not valid. The scope format is invalid. Scope must be in a valid URI form <https://example/scope> or a valid Guid <guid/scope>.\r\n[..]",
"error_codes": [70011],
}
I'm sending a POST request with a body like client_id=<client-id>&scope=openid+https%3A%2F%2Fgraph.microsoft.com%2F.default to https://login.microsoftonline.com/<tenant>/oauth2/v2.0/devicecode. With these scopes, I can login just fine, but any subsequent requests to Azure resource management APIs (for example, to DELETE a resource group) will fail with 401 Unauthorized.
If you want to use the device code flow to access the azure resources, please follow the steps as below.
1.Navigate to your AD App in the Azure Active Directory in the portal -> API permissions -> Add a permission -> select Azure Service Management API -> select the user_impersonation.
2.Navigate to the subscription in the portal -> Access control (IAM), make sure your user account used to login has a role e.g. Contributor in the subscription. If not, please add the user as a role in the subscription, follow this doc.
3.In the postman, use the request below.
Request URL:
POST https://login.microsoftonline.com/<tenant-id>/oauth2/v2.0/devicecode
Request Body:
client_id=<client-id>
scope=https://management.azure.com/user_impersonation
In the browser, navigate to the https://microsoft.com/devicelogin, input the code and login your user account, the app will let you consent the permission, click the Accept.
4.After login successfully, in the postman, use the request below.
Request URL:
POST https://login.microsoftonline.com/<tenant-id>/oauth2/v2.0/token
Request Body:
grant_type: urn:ietf:params:oauth:grant-type:device_code
client_id: <client-id>
device_code: <device_code in the screenshot of step 3>
5.Use the access_token in step 4 to call Azure REST API, e.g. Resource Groups - List, it works fine.
For more details, you could refer to - Microsoft identity platform and the OAuth 2.0 device authorization grant flow.
Besides, to consent the permission successfully in step 3, make sure the setting below( Azure AD -> Enterprise applications -> User settings -> Users can consent to apps accessing company data on their behalf) in your tenant is set to Yes, otherwise, you need to let your admin click the Grant admin consent for xxxx button in step 1.

Authenticate for Azure REST API without login

I have a backend process that doesn't directly interact with the user. I want to access reservations associated with my Azure account but I'm having trouble with the authentication step. I was following the guide here and I managed to get the authentication request to work by calling
https://login.microsoftonline.com/{tenant-ID}/oauth2/token
as a POST with the following x-www-form-urlencoded body:
grant_type=client_credentials&
client_id={client-ID}&
client_secret={client-Secret}&
resource=http://myapp42
However, when I attempt to call:
https://management.azure.com/providers/Microsoft.Capacity/reservationOrders/{order-ID}/reservations/{reservation-ID}?api-version=2019-04-01
with the bearer token I received during the authentication step, I get the following error message:
The access token has been obtained for wrong audience or resource 'http://myapp42'. It should exactly match with one of the allowed audiences 'https://management.core.windows.net/', 'https://management.core.windows.net', 'https://management.azure.com/', 'https://management.azure.com'
However, if I modify the resource on the request to be one of these, http://management.core.windows.net/ for instance, the authentication then fails with:
AADSTS500011: The resource principal named https%3A%2F%2Fmanagement.core.windows.net%2F was not found in the tenant named {tenant-ID}. This can happen if the application has not been installed by the administrator of the tenant or consented to by any user in the tenant. You might have sent your authentication request to the wrong tenant.\r\nTrace ID: b54cedea-3804-41cf-bd27-fcf0ed1c4700\r\nCorrelation ID: 2371d375-6c89-4f05-83c9-c4629b3340a8\r\nTimestamp: 2020-02-05 01:59:57Z
How do I authenticate so that I can then get my reservations without having to login?
Update:
The service principal has both the Owner and Contributor roles assigned.
Update 2:
Thanks to #Jim Xu, I was realized that I needed to refrain from url-encoding the URL. That allowed me to get the access token with a value of https://management.azure.com/ for the resource field. However, at this point, when I attempt to call the REST API with the resulting bearer token, I get the following error:
The client '{Object-ID}' with object id '{Object-ID}' does not have authorization to perform action 'Microsoft.Capacity/reservationOrders/reservations/read' over scope '/providers/Microsoft.Capacity/reservationOrders/{order-ID}/reservations/{reservation-ID}' or the scope is invalid. If access was recently granted, please refresh your credentials
Note: The object ID returned by this error is the one associated with the service principal.
Update 3:
I checked the reservation and it seems that the principal does not have a role in that reservation's access control. However, I also cannot assign the principal a role because it does not show when I search for principals during the role-assigning process.
If you want to call Azure Rest API to get the information of reservation Orders, you need to assign Owner\Contributor for the service principal.(the action needs Microsoft.Capacity/reservationOrders/read permission).
The steps are as below
Get access token
POST : https://login.microsoftonline.com/{tenant-ID}/oauth2/token
Content-Type: application/x-www-form-urlencoded
grant_type=client_credentials&
client_id={client-ID}&
client_secret={client-Secret}&
resource=https://management.azure.com/ or https://management.core.windows.net
Call the api
GET : https://management.azure.com/providers/Microsoft.Capacity/reservationOrders/{order-ID}/reservations/{reservation-ID}?api-version=2019-04-01
Authorization: Bearer <token>
For more details, please refer to the issue and the issue
update
If you have assigned role but you still cannot get access token, please try to encode your url.

Resources