Unauthorized access. 'Send' claim(s) are required to perform this operation - Azure Queue Send Message - azure

We have been trying to send a test message to Azure Service Bus Queue from SPFx webpart, however, every time we are seeing --> Unauthorized access. 'Send' claim(s) are required to perform this operation. Resource: 'sb://.servicebus.windows.net/'.
Steps we have followed -
Created a sample SPFx webpart.
Used
{
"resource": "Microsoft.ServiceBus",
"scope": "user_impersonation"
}
inside webApiPermissionRequests of package-solution.json.
Deployed the webpart and approved scopes from Admin center so that an Azure AD App service principal gets created with API Permissions.
Now migrated the Redirect Uris to SPA for PKCE flow (MSAL 2.0).
Set Allow Public Client Flows to "Yes".
Then got the client id and tenant id from AD App and used in our SPFx solution to connect Service Bus Queue through javascript SDK.
Used InteractiveBrowserCredential from #azure/identity and ServiceBusClient from #azure/service-bus to send a message to the Queue. Snippet below -
try{
const credential = new InteractiveBrowserCredential({
tenantId: "<tenant-id>",
clientId: "<SharePoint Online Client Extensibility Web Application Principal client-id>"
});
const fullyQualifiedNamespace = "<servicebus-namespace>.servicebus.windows.net";
const serviceBusClient = new ServiceBusClient(fullyQualifiedNamespace, credential);
const sender = serviceBusClient.createSender("queue-name");
await sender.sendMessages({body: "test"});
console.log("message sent");
}
catch(error){
console.log(error);
}
Provided Owner and Azure Service Bus Data Owner access from IAM to the Service Principal. Both queue and service bus level.
However, every time code block is throwing exception and the message is - Unauthorized access. 'Send' claim(s) are required to perform this operation. Resource: 'sb://.servicebus.windows.net/'.
Any help would be appreciated. Thanks !!

Related

Unauthorized error send message from function app to eventgrid with Role Based Access for Event Grid Send

I have a function app with a function that sends message to event grid. A function in this same function app is subscribed to this event grid topic. I get unauthorized access to send message despite function app has set role based access for Event Grid Send.
I have set the function app Identity to System Assigned ON:
I also set the function app Assigned Role to Event Grid Sender at Subscription level (within which the event grid topic also sits):
The event grid sender role assigned is confirmed at IAM Role Assignments of the Event Grid Topic:
When I execute the function app to send data to event grid I get unauthorized error:
//Name of the endpoint of Event grid topic
string topicEndpoint = transformAlgoSendRMessage_TopicEP;
//Creating client to publish events to eventgrid topic
EventGridPublisherClient client = new EventGridPublisherClient(new Uri(topicEndpoint), new DefaultAzureCredential());
//Creating a sample event with Subject, Eventtype, dataVersion and data
EventGridEvent egEvent = new EventGridEvent("TransformTelemetry", "TransformAlgorithm.broadcastTransform", "1.0", machinePartTransformTelemetry);
// Send the event
try
{
await client.SendEventAsync(egEvent);
if (b_debug_contractor)
log.LogInformation("SendRTransformMessage sent transformdata - PosX:" + machinePartTransformTelemetry[1]);
}
catch (Exception e)
{
log.LogError("Failed to send SendRTransformMessage. " + e.Message);
}
Unauthorized Error:
[2022-11-25T08:00:45.646Z] Failed to send SendRTransformMessage. The principal associated with access token presented with the incoming request does not have permission to send data to /subscriptions/MySubscriptionID/resourceGroups/myresourcegroup/providers/Microsoft.EventGrid/topics/functionappname. Report 'e9595a36-8420-4466-b91a-801fbfcf605d:4:11/25/2022 8:00:48 AM (UTC)' to our forums for assistance or raise a support ticket.
[2022-11-25T08:00:45.646Z] Status: 401 (The principal associated with access token presented with the incoming request does not have permission to send data to /subscriptions/mySubscriptionID/resourceGroups/myresourcegroup/providers/Microsoft.EventGrid/topics/myfunctionappname. Report 'e9595a36-8420-4466-b91a-801fbfcf605d:4:11/25/2022 8:00:48 AM (UTC)' to our forums for assistance or raise a support ticket.)
[2022-11-25T08:00:45.647Z] ErrorCode: Unauthorized
[2022-11-25T08:00:45.647Z]
[2022-11-25T08:00:45.647Z] Content:
[2022-11-25T08:00:45.648Z] {
[2022-11-25T08:00:45.648Z] "error": {
[2022-11-25T08:00:45.649Z] "code": "Unauthorized",
[2022-11-25T08:00:45.649Z] "message": "The principal associated with access token presented with the incoming request does not have permission to send data to /subscriptions/mySubscriptionID/resourceGroups/myresourcegroup/providers/Microsoft.EventGrid/topics/myfunctionappname. Report 'e9595a36-8420-4466-b91a-801fbfcf605d:4:11/25/2022 8:00:48 AM (UTC)' to our forums for assistance or raise a support ticket.",
[2022-11-25T08:00:45.650Z] "details": [{
[2022-11-25T08:00:45.650Z] "code": "Unauthorized",
[2022-11-25T08:00:45.650Z] "message": "The principal associated with access token presented with the incoming request does not have permission to send data to /subscriptions/mySubscriptionID/resourceGroups/myresourcegroup/providers/Microsoft.EventGrid/topics/myfunctionappname. Report 'e9595a36-8420-4466-b91a-801fbfcf605d:4:11/25/2022 8:00:48 AM (UTC)' to our forums for assistance or raise a support ticket."
I note I tried with key credentials but the Azure would not recognize the key.
I tried to reproduce the same in my environment and got below results
I created one function app and enabled system assigned identity as below:
Add role assignment to the Event grid like below: Go to Azure Portal -> Event grid Topics -> Your Topic -> Access control (IAM)
The error 401 Unauthorized may occur if you selected service principal instead of managed identity where 'Type' is App not Function App while assigning role like below:
To resolve the error, make sure to select Managed Identity as Function App while assigning role to Event grid like below:
Select Review+assign to assign the role as below:
Role EventGrid Data Sender got assigned successfully to the Event grid like below:
This will automatically reflect in the function app too and no need to assign this role separately to function app identity.
To confirm that, Go to Azure Portal -> Your Function App -> Identity -> Azure role assignments
Now restart the function app and execute the function again. If the issue still persists, raise a support ticket.
Reference:
Send Events To Event Grid Topic Using Managed Service Identity by Rittik Basu

Azure B2C client credentials flow throws invalid_grant AADB2C90085

I followed this resource: https://icareb2cdev.b2clogin.com/icareb2cdev.onmicrosoft.com/B2C_1A_DEMO_CLIENTCREDENTIALSFLOW/oauth2/v2.0/token
Azure B2C App registrations:
Protected web api
Expose an api
App ID URI = https://{my tenant name}.onmicrosoft.com/{protected web api client id}/.default
Daemon console app
API Permissions
API = protected web api
Permission = access_as_application
Type = Application
Admin consent requested = Yes
I acquire a token using the OAuth client credentials flow:
POST https://{my tenant name}.b2clogin.com/{my tenant name}.onmicrosoft.com/{a basic user flow SUSI policy}/oauth2/v2.0/token
scope=https://icareb2cdev.onmicrosoft.com/{protected web api client id}/.default&
grant_type=client_credentials&
client_id={daemon console app client id}&
client_secret={daemon console app client secret}
Error response:
{
"error": "invalid_grant",
"error_description": "AADB2C90085: The service has encountered an internal error. Please reauthenticate and try again.\r\nCorrelation ID: REDACTED\r\nTimestamp: REDACTED\r\n"
}
I ran into the same issue, please double check your Manifest and make sure that "signInAudience": "AzureADandPersonalMicrosoftAccount" and not your organization only. Do also ensure you followed the steps same as other answer.

What Permission Scopes required for Google Cloud Platform Channel API - customers.create

Overview
I am getting an error insufficient permission scopes when running customers.create GCP Channel API, but I can't tell what extra permissions/scopes I need to grant my service account.
I have a node.js provisioning some GCP Resources, where one of the main goals is to automatically create a new Billing Subaccount in GCP.
The latest documenation for this suggests creating a customer, them creating entitlements from there. (A customer is passed into the "create entitlements" method).
Expected Results
Execution of the create customer method should have a successful out of a customer object.
Actual Results
When I implement the create customer I get an error:
UnhandledPromiseRejectionWarning: Error: 7 PERMISSION_DENIED: Request had insufficient authentication scopes.
at Object.callErrorFromStatus ...
My implementation
Authentication : service account credential file
I have a service account with an exported key/credential file I use to successfully authenticate other GCP API calls in my application such as projects.create() and projects.serviceAccounts.create() - so I am confident that my service account authentication is set up correctly as far as the node application goes.
Service account authentication in code:
const auth = new google.auth.GoogleAuth({
keyFile: 'MyServiceAccountKey.json',
scopes: [
'https://www.googleapis.com/auth/cloud-platform',
'https://www.googleapis.com/auth/apps.order',
'https://www.googleapis.com/auth/cloud-billing'
],
});
Service Account Permissions (Granted at folder level)
Permissions contained within the "Customer Billing Admin" Role:
Channel API Method Execution :
const {CloudChannelServiceClient} = require('#google-cloud/channel').v1;
async function CreateCustomer(options){
const channelClient = new CloudChannelServiceClient();
const authClient = await auth.getClient();
const request = {
parent : "accounts/XXXXX-XXXXX-MYACCOUNT",
customer : {
"name": "Customer Test 1",
},
}
const response = await channelClient.createCustomer(request);
console.log(response);
}
Resolution thoughts
Using the GCP APIs I've found that sometimes I just need to add additional permissions to my service account in the IAM page on the GPC console, and other time I needed to include more scopes in the authentication object in my code. This refercence for the accounts.customers.create says the required scope for this api is https://www.googleapis.com/auth/apps.order, which I have included in my code - so I am at a loss as to what permissions/scopes I am missing. From what I can tell, service account authorization should work with this API.

Azure AD, Multi-tenant, App Roles Assignment for users from another tenant

I'm working on web application that contains client side (SPA, angular 9) and backend (WebAPI, ASP.NET Core 3.0). Decided to use Application Roles feature to authorize users in our application. And i have requirement to be able to manage Application role assignments for users from our application UI via MSFT Graph API.
I registered MyAuthApp application in Azure AD TenantA. And created several App Roles there.
Authentication works fine. Client side gets token and attaches it to http requests to backend. Authorization also works fine i can extract app roles from the token and validate them.
Problem with adding Application role assignments for users from other AzureAD tenant -- TenantB. Seems that problem in GraphServiceClient configuration due to GraphApiAuth registered in TenantA.
Question: is this possible to add application role assignment for user from TenantB using GraphServiceClient authorized by Client Credentials in TenantA?
Right now when i do add role assignment i'm getting exception like resource with some Guid not found. This resource is a user (from TenantB).
This is a piece of code that adds user app role assignment. I see possible problem in GetGraphServiceClient function. It uses as authority URL with TenantA Id.
public async Task<AppRoleAssignment> AssignAppRoleToUser(Guid userId, Guid appRoleId)
{
var graphClient = await this.graphClientProvider.GetGraphServiceClient();
return await graphClient.Users[userId.ToString()].AppRoleAssignments.Request().AddAsync(
new AppRoleAssignment()
{
PrincipalId = userId,
AppRoleId = appRoleId,
ResourceId = this.graphAppSettingsProvider.GetAppRoleResourceIdAsGuid()
});
}
df0b3e71-fd2d-41a4-bfa9-0310b31395ae is Id of user from tenantB.
UPDATE:After further investigation i was able to assign App role for user from TenantB. But i had to change settings in the code that returns GraphServiceClient and provide TenantB Id and Application Service Principal Id from TenantB (instead of values from TenantA). But that's a problem. We would like to be able to assign application roles for users from any tenant and it will be not doable if we will have to provide TenantId and Service Principal Id for each tenant separately.
Is it possible to do this some how with some common settings?
This is how i get GraphServiceClient:
public async Task<GraphServiceClient> GetGraphServiceClient()
{
var clientId = this.graphAppSettingsProvider.GetClientId();
var clientSecret = this.graphAppSettingsProvider.GetClientSecret();
var tenantId = this.graphAppSettingsProvider.GetTenant();
var app = ConfidentialClientApplicationBuilder.Create(clientId)
.WithClientSecret(clientSecret)
.WithTenantId(tenantId)
.Build();
string[] scopes = {"https://graph.microsoft.com/.default"};
return new GraphServiceClient(
"https://graph.microsoft.com/v1.0",
new DelegateAuthenticationProvider((requestMessage) =>
{
var ar = app.AcquireTokenForClient(scopes).ExecuteAsync();
requestMessage.Headers.Authorization = new AuthenticationHeaderValue("bearer", ar.Result.AccessToken);
return Task.FromResult(0);
}));
}
UPDATE 2
Changed a little requirements and now we just need to manage App Roles list for users from current user tenant. So, we changed permissions type from Application to Delegated to be behalf of authenticated user.
As i said earlier we have Angular app in pair with ASP.NET Core WebAPI backend. Angular app gets access token and sends it to backend in Authorizaiton header. When i attach with access token to GraphServiceClient request (header) i'm getting error "Access token validation failure. Invalid audience."
Question: is this correct flow to use access token from client for Graph API requests or should i get new access token for Graph API at backend using access token from client?
Any help/ideas appreciated. Thanks in advance!
First, you need to set up the MyAuthApp application as a multi-tenant application.
Next, run admin consent url in the browser, and then you need to log in with another tenant's administrator account and consent. The multi-tenant application will then be added to the target tenant as an enterprise application. https://login.microsoftonline.com/common/adminconsent?client_id={client-id}.
At the same time, the app role you created in tenant A will also be synchronized to the target tenant (for example, tenant B). Next, you only need to grant the app role of MyAuthApp to the users of tenant B through the Azure portal of tenant B or use ms graph api.

OAUTH / Azure Functions: Method to auth AAD user for endpoints that don't support service principals

I've been leveraging Azure Function Apps to automate items in Azure. I currently have working functions that connect to Microsoft Graph, Resource Explorer, KV etc. using service principal / OAUTH client credentials flow (inside the function app). To call my function app, I've implemented implicit flow. While I'm not an expert at OAUTH, I am familiar enough now to get this configured and working.
However, there are Azure endpoints I need to use that don't support using a service principal token, they only support an actual AAD user requesting a token. Here's one that I want to run: Create synchronizationJob
If you look at the permissions section of the above link, you'll see that "application" is not supported. I did test this in a function: I can run these endpoints in Graph Explorer fine (as myself), but they fail in the function when using a token linked to a service principal.
Since this new automation is going to be an Azure Function (and not an interactive user), I can't use the authorization code flow. I need this service account's OAUTH to be non-interactive.
TL;DR
I can run the above endpoint in Azure's Graph Explorer just fine:
Azure Graph Explorer
since I'm authenticating as myself, and have a token generated based on my user ID. But for automating using Azure Functions where I need to use this endpoint (which doesn't support OAUTH using an SP), I need some way to have a back-end AAD user auth and pull a token that can be used to run the endpoint.
Any help is welcome! Feel free to tell me that I'm either missing something very basic, or not understanding a core principal here.
As juunas mentioned no guarantee that will work though, I test in my side and it seems doesn't work although I assigned "Global administrator" role to the service principal.
For your situation, you can request the access token in your function code and then use the access token to request the graph api.
Add the code like below in your function to get access token.
HttpClient client = new HttpClient();
var values = new Dictionary<string, string>
{
{ "client_id", "<your app client id>" },
{ "scope", "<scope>" },
{ "username", "<your user name>" },
{ "password", "<your password>" },
{ "grant_type", "password" },
};
var content = new FormUrlEncodedContent(values);
var response = await client.PostAsync("https://login.microsoftonline.com/<your tenant id>/oauth2/v2.0/token", content);
var responseString = await response.Content.ReadAsStringAsync();
var obj = JObject.Parse(responseString);
var accessToken = (string)obj["access_token"];
And then use the access token got above to request graph api.

Resources