1
votes

I need to create topic, subscription and SAS policy for azure service bus namespace using shared access policy connectionstring. for that I have used "Microsoft.Azure.ServiceBus" NuGet package.(I am using this NuGet package because I am using .NET Core 2.1).

Note :- Namespace is already created in azure service bus.

What I have tried :-

Now, I can create topic and subscription using following code as

 public static async Task CreateTopicSubscriptionAndSASPolicy()
    {
        string ServiceBusConnectionString = "Endpoint=sb://servicebusnameone.servicebus.windows.net/;SharedAccessKeyName=xxxxx;xxxxxxxxxxxxxxxxxxxxxxx";
        string topic = "TopicOne";
        string subscriptionName = "SubOne";
        var client = new ManagementClient(ServiceBusConnectionString);

        if (!await client.TopicExistsAsync(topic))
        {
            await client.CreateTopicAsync(topic);
        }
        if (!await client.SubscriptionExistsAsync(topic, subscriptionName))
        {
            await client.CreateSubscriptionAsync(new SubscriptionDescription(topic, subscriptionName));
        }

        IEnumerable<AccessRights> accessRights = new[] { AccessRights.Send };
        SharedAccessAuthorizationRule sharedAccessAuthorizationRule = new SharedAccessAuthorizationRule("SendRule", accessRights);
        //TO DO Create SAS Policy....
    }

Now, I need to create SAS policy at namespace level but I am not sure how can I do it? I have also read following Microsoft documentation and stackoverflow question-answer

  1. https://docs.microsoft.com/en-us/azure/service-bus-messaging/service-bus-sas

  2. https://github.com/Huachao/azure-content/blob/master/articles/service-bus/service-bus-shared-access-signature-authentication.md

  3. Shared Access Policy Programatic Creation for Azure Service Bus

  4. Using SAS Token with Azure ServiceBus

  5. Azure Service Bus Shared Access Signature Generation

Question :-

  1. How can I create SAS policy in azure service bus namespace?
  2. There is any way to configure topic/subscriptions while creating? (because while I create topic using above given code it create topic with Max size 1024 MB but I need to set it 5120 MB)?
  3. Apart from this there is any better way(best practice) to create topic, subscription and SAS policy using connection string in .Net Core 2.1?

Note:- Any working example is very helpful to clear understanding.

1
I have provided some API documentation for reference, if you need code, you can let me know.:) Hope it helps.1_1
@BowmanZhu Thanks! for help. it would be really helpful if you provide code.Harish Shisode
I have updated the answer, If you have time you can check it. Any doubts please let me know.1_1
@BowmanZhu. Thanks for your help. currently I am checking. Once done I will let you know.Harish Shisode

1 Answers

1
votes

Update 2020/12/22

I have checked the source code of all major packages, there is no way to create the access policy based on namespace with those packages, there only can create on entities.

So, let follow a more basic way, use rest API(The underly logic of those packages is also based on this.).

Below is the code and works fine on my side:

using Microsoft.Azure.Services.AppAuthentication;
using System;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApp23
{
    class Program
    {
        static void Main(string[] args)
        {
            CallWebAPIAsync().Wait();
        }

        static async Task CallWebAPIAsync()
        {
            AzureServiceTokenProvider azureServiceTokenProvider = new AzureServiceTokenProvider();
            string accessToken = azureServiceTokenProvider.GetAccessTokenAsync("https://management.azure.com/").Result;
            using (var client = new HttpClient())
            {
                client.DefaultRequestHeaders.Add("Authorization", "Bearer " + accessToken);
                client.BaseAddress = new Uri("https://management.azure.com/");


                client.DefaultRequestHeaders.Accept.Clear();
                client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
                //PUT Method  
                var jsonString = "{ \"properties\": { \"rights\": [ \"Listen\", \"Send\", \"Manage\" ] } }";
                var httpContent = new StringContent(jsonString, Encoding.UTF8, "application/json");
                HttpResponseMessage response = await client.PutAsync("https://management.azure.com/subscriptions/e5b0xxxxxx9f4c68/resourceGroups/0730BowmanWindow/providers/Microsoft.ServiceBus/namespaces/bowman1012/AuthorizationRules/testbowman?api-version=2017-04-01",httpContent);
                if (response.IsSuccessStatusCode)
                {
                    Console.WriteLine(response.Content.ReadAsStringAsync().Result);
                }
                else
                {
                    Console.WriteLine("Internal server Error");
                }
            }
        }
    }
}

It works fine:

enter image description here

Below is the rest API reference, any doubts please let me know.

https://docs.microsoft.com/en-us/rest/api/servicebus/stable/namespaces%20-%20authorization%20rules/createorupdateauthorizationrule

Update:

.csproj file

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>netcoreapp2.1</TargetFramework>
  </PropertyGroup>

  <ItemGroup>
   
    <PackageReference Include="Azure.Messaging.ServiceBus" Version="7.0.0" />
   
    <PackageReference Include="Microsoft.Azure.ServiceBus" Version="5.1.0" />
  </ItemGroup>

</Project>

Program.cs

using Microsoft.Azure.ServiceBus;
using Microsoft.Azure.ServiceBus.Primitives;
using Azure.Messaging.ServiceBus.Administration;
using System;
using System.Text;

namespace ConsoleApp15
{
    class Program
    {
        static async System.Threading.Tasks.Task Main(string[] args)
        {
            string keyname = "test";
            string sharedaccesskey = "xxxxxx";
            var validityDuration = TimeSpan.FromHours(24);
            TokenScope tokenScope = TokenScope.Entity;

            //Get the SAS based on the namespace.
            var tokenprovider =(SharedAccessSignatureTokenProvider) TokenProvider.CreateSharedAccessSignatureTokenProvider(keyname,sharedaccesskey,validityDuration,tokenScope);
            var token =await tokenprovider.GetTokenAsync("sb://bowman1012.servicebus.windows.net/", TimeSpan.FromHours(24));

            //Send message to service bus queue based on SAS token.
            ServiceBusConnectionStringBuilder builder = new ServiceBusConnectionStringBuilder {
                Endpoint= "sb://bowman1012.servicebus.windows.net/",
                EntityPath= "testbowman",
                SasToken= token.TokenValue
            };
            QueueClient client = new QueueClient(builder);
            Message mes = new Message();
            mes.Body = Encoding.ASCII.GetBytes("This is a test.20201208");
            await client.SendAsync(mes);

            //Create a topic with 5120MB.
            var client1 = new ServiceBusAdministrationClient("Endpoint=sb://bowman1012.servicebus.windows.net/;SharedAccessKeyName=RootManageSharedAccessKey;SharedAccessKey=xxxxxx");
            var topicOptions = new CreateTopicOptions("20201208")
            {
                AutoDeleteOnIdle = TimeSpan.FromDays(7),
                DefaultMessageTimeToLive = TimeSpan.FromDays(2),
                DuplicateDetectionHistoryTimeWindow = TimeSpan.FromMinutes(1),
                EnableBatchedOperations = true,
                EnablePartitioning = false,
                MaxSizeInMegabytes = 5120,
                RequiresDuplicateDetection = true,
                UserMetadata = "some metadata"
            };
            topicOptions.AuthorizationRules.Add(new SharedAccessAuthorizationRule(
                    "allClaims",
                    new[] { AccessRights.Manage, AccessRights.Send, AccessRights.Listen }));
            await client1.CreateTopicAsync(topicOptions);


            Console.WriteLine("Hello World!" + "\n" + token.TokenValue);
        }
    }
}

And works fine on my side:

enter image description here

enter image description here


Original Answer:

How can I create SAS policy in azure service bus namespace?

You can use SharedSecretTokenProvider.BuildKey(string appliesTo, string action) method to create the SAS.

This is the API reference:

https://docs.microsoft.com/en-us/dotnet/api/microsoft.servicebus.sharedaccesssignaturetokenprovider?view=azure-dotnet

Or you can refer to this doc(some simple code):

https://docs.microsoft.com/en-us/azure/service-bus-messaging/service-bus-sas#use-shared-access-signature-authorization

There is any way to configure topic/subscriptions while creating? (because while I create topic using above given code it create topic with Max size 1024 MB but I need to set it 5120 MB)?

Use NamespaceManager.CreateTopic method, this method returns TopicDescription object, you can set the size by the MaxSizeInMegabytes property(in megabytes).

This is the API reference:

https://docs.microsoft.com/en-us/dotnet/api/microsoft.servicebus.namespacemanager.createtopic?view=azure-dotnet

https://docs.microsoft.com/en-us/dotnet/api/microsoft.servicebus.messaging.topicdescription.maxsizeinmegabytes?view=azure-dotnet#Microsoft_ServiceBus_Messaging_TopicDescription_MaxSizeInMegabytes

Apart from this there is any better way(best practice) to create topic, subscription and SAS policy using connection string in .Net Core 2.1?

I'm not sure what you are worried about on this point, maybe you can explain what you are looking for? This method of obtaining is provided by the above official document.

And the method to create subscription:

https://docs.microsoft.com/en-us/dotnet/api/microsoft.servicebus.namespacemanager.createsubscription?view=azure-dotnet