Closed VarshaGadekar closed 1 year ago
@VarshaGadekar do you need to create the service bus queue or topic? If not, you could remove the following properties
spring.cloud.azure.profile.subscription-id=<some valid value>
spring.cloud.azure.servicebus.resource.resource-group=<some valid value>
The error is because the service principal isn't authorized to read resources in the given namespace.
I dont want to create queue or topic. The application is either producer or consumer based on business logic for different queues/topics.
spring.cloud.azure.credential.client-id=
When I tried to use without resource-group and subscription-id with only above parameters it gives following error:
{"dd.trace_id":"0", "dd.span_id":"0", "thread_id":"reactor-executor-1", "az.sdk.message":"onLinkRemoteClose","connectionId":"MF_26ff17_1667798177941","errorCondition":"amqp:unauthorized-access","errorDescription":"Unauthorized access. 'Listen' claim(s) are required to perform this operation. Resource: 'sb://
I checked that the client-id, client-secret, tenant-id and namespace are correctly configured and access policy has 'Manage', 'Send', 'Listen' assigned.
Have you assigned the Service Bus Owner/Sender/Receiver role to the service principal https://microsoft.github.io/spring-cloud-azure/current/reference/html/index.html#authorize-access-with-azure-active-directory? @VarshaGadekar
hi @saragluna can you please confirm why Spring Azure Cloud needs to assign above roles with Azure AD? Because if we directly use Azure APIs it does not need these roles. keyvault Endpoint with tenant-id, client-id and client-secret works and provides us the sas token.
@VarshaGadekar are you storing the sas token in Key Vault?
Put KV aside, if you try to access service bus, there are two approaches: one via the connection string (this will give you the sas token), another is via Azure AD service principals or managed identities (this approach requires the roles).
What did you mean by using Azure APIs directly? What are these APIs and how do you call them?
yes we are using key-vault.
following way with Azure API's worked:
String serviceBusSAS = AzureUtils.getServiceBusSAS(clientId, clientSecret, keyvaultUrl, secretName);
com.microsoft.azure.servicebus.QueueClient queueClient = com.microsoft.azure.servicebus.QueueClient(
new com.microsoft.azure.servicebus.primitives.ConnectionStringBuilder(serviceBusSAS + ";EntityPath=my-test-service-bus-queue", "my-test-service-bus-queue"),
ReceiveMode.RECEIVEANDDELETE);
once above queueClient is created as bean we can use as follows
AzureUtils.sendServiceBusMessage(queueClient, objectMapper.writeValueAsString(fileQueueMessage));
AzureUtils.java has following
import java.time.Duration;
import org.springframework.http.MediaType;
import com.azure.messaging.servicebus.ServiceBusMessage;
import com.azure.messaging.servicebus.ServiceBusSenderClient;
import com.microsoft.azure.servicebus.Message;
with method
public static void sendServiceBusMessage(final ServiceBusSenderClient client, final String content) {
final ServiceBusMessage message = new ServiceBusMessage(content);
message.setContentType(MediaType.APPLICATION_JSON_VALUE);
message.setTimeToLive(Duration.ofMinutes(10));
client.sendMessage(message);
}
Ok got it. The serviceBusSAS
is the connection string for the service bus namespace, so in the code you posted the application connects to the service bus using the connection string. The service principal (client id) only needs the role to access the KV.
But if you are connecting to the Service Bus using that service principal, you need to assign it the role I mentioned before.
Another approach is you provide the spring.cloud.azure.servicebus.connection-string
property to your application. The property can be saved to the KV using key spring-cloud-azure-servicebus-connectionstring
.
yes spring.cloud.azure.servicebus.connection-string
is working fine.
However can you please confirm if it is possible for Spring Azure Cloud Stream Binder to not mandate the role Owner/Sender/Receiver with Azure AD?
Can there be some way with spring azure cloud stream binder (may be in future) to use above way which will need only client id?
In my understanding, if you want to connect using an Azure AD user/service principal/managed identity, you need to grant permissions to that identity. Just like how you assign role/access policy to the service principal to access KV.
The request is not coming from the library, it's coming from the Azure Service. Whenever you authenticate the application using an Azure AD identity, the client will request an access token from Azure AD, and then use that token to access the Azure Service. In this process, it reflects how it works with OAuth 2.0, the Azure AD is the authorization server, and the Azure Service is the resource server. The Azure Service's responsibility is to check that the token sent to it has a corresponding role in performing actions.
What do you mean by spring azure cloud stream binder (may be in future) to use above way which will need only client id
?
Thank you for providing all details. I was saying if internally spring azure cloud stream binder can provide some way to use service principal and internally it can generate the spring.cloud.azure.servicebus.connection-string
with service principle and skipping the Azure AD identity route.
@VarshaGadekar yes, we can provide that by requesting Azure Resource Manager (ARM) for the connection string. But this step requires the service principal to have management roles.
ok thank you @saragluna.
I will close this issue now, please reopen it if you have any other questions.
Describe the bug Spring Azure Cloud 4.4.1 Service Bus with stream binder results into AuthorizationFailed Exception or Stack Trace results into following error
NOTE: on different environment different object id is displayed in error
To Reproduce
Code Snippet
Expected behavior
Screenshots
Content (please complete the following information if possible):
Additional context
Information Checklist