Giving limited access to client to Service Bus Queues
-
2012年4月12日 上午 07:55
Hi all,
I'm trying to create a simple application where I can return a SWT with only Listen access to a specific queue to third party clients, which they can then use to check for new messages. The idea is, each client will be connecting to a different queue and they will be unaware from other client's queues.
While working on this I created a sample code, where I try to get a token from ACS with manage access and then use it to create queues:
TokenProvider provider = TokenProvider.CreateSharedSecretTokenProvider(IssuerName, IssuerKey); Uri serviceUri = ServiceBusEnvironment.CreateServiceUri("sb", ServiceNamespace, string.Empty); var result = provider.BeginGetWebToken(serviceUri.AbsoluteUri, "Manage", false, new TimeSpan(0, 10, 0), null, null); string token = provider.EndGetWebToken(result); token = token.Replace("WRAP access_token=\"", string.Empty).Replace("\"", string.Empty); TokenProvider credentials = TokenProvider.CreateSimpleWebTokenProvider(token); NamespaceManager namespaceClient = new NamespaceManager(serviceUri, credentials); namespaceClient.QueueExists(Sender.QueueName);
This code part throws the exception, 401 with subcode T2002, Detail:Audience not valid.
The Audience is supposedly the same as the base serviceUri. So I'm a little bit lost as to where the problem lies.
Any ideas why this is failing, or how I can accomplish what I'm trying to do?
Thanks!
所有回覆
-
2012年4月13日 上午 03:49版主
Hi,
Just for doubt, the sample code you've mentioned is the ACS samples of codeplex?
TrustAudience means the Realm property in the ACS, if you have ever configure the ACS relying party application and service Identities OK in ACS management portal.
cPlease check it.
Please mark the replies as answers if they help or unmark if not. If you have any feedback about my replies, please contact msdnmg@microsoft.com Microsoft One Code Framework
-
2012年4月13日 上午 04:24
Hi,
Thanks for the response. I started with the MessagingWithQueues example and changed it to test if I can generate web tokens from a shared secret token provider.
As expected, if I just use the SharedSecretTokenProvider as the credentials everything works fine:
const string QueueName = "IssueTrackingQueue"; const string ServiceNamespace = "<MyNameSpace>"; const string IssuerName = "<MyIssuerName>"; const string IssuerKey = "<MyIssuerKey>"; static void Main(string[] args) { TokenProvider credentials = TokenProvider.CreateSharedSecretTokenProvider(IssuerName, IssuerKey); Uri serviceUri = ServiceBusEnvironment.CreateServiceUri("sb", ServiceNamespace, string.Empty); NamespaceManager namespaceClient = new NamespaceManager(serviceUri, credentials); namespaceClient.QueueExists(QueueName); }
What I'm trying to achieve is, to connect to ACS using a service identity (just like it's used in the aove code) and then generate a simple web token with limited access to a specific Queue for a limited duration. Then I want to return this SWT as string to a client application. The idea is the client will use this SWT to connect to the queue and poll for messages.
The reason why I'm trying to do it like this is, our platform already has an authentication system where the clients authenticate themselves against the hosted application. As they are already authenticated, I only need the clients to make a call to hosted application to retrieve a SWT and connect to a specified queue.
I tried creating the following code to achieve this, and that's when I get that error:
const string QueueName = "IssueTrackingQueue"; const string ServiceNamespace = "<MyNameSpace>"; const string IssuerName = "<MyIssuerName>"; const string IssuerKey = "<MyIssuerKey>"; static void Main(string[] args) { TokenProvider provider = TokenProvider.CreateSharedSecretTokenProvider(IssuerName, IssuerKey); Uri serviceUri = ServiceBusEnvironment.CreateServiceUri("sb", ServiceNamespace, string.Empty); var result = provider.BeginGetWebToken(serviceUri.AbsoluteUri, "Manage", false, new TimeSpan(0, 10, 0), null, null); string token = provider.EndGetWebToken(result); token = token.Replace("WRAP access_token=\"", string.Empty).Replace("\"", string.Empty); TokenProvider credentials = TokenProvider.CreateSimpleWebTokenProvider(token); NamespaceManager namespaceClient = new NamespaceManager(serviceUri, credentials); namespaceClient.QueueExists(QueueName); }
Thanks
-
2012年4月13日 上午 04:26Just to clarify, everything in the ACS is set, that's what I meant when I said, everything works correctly if I use the SharedSecretTokenProvider generated on the first line of code directly.
-
2012年4月13日 上午 06:50版主
Hi,
Please following the below code to see if works (Works fine at my side.)
c
TokenProvider provider = TokenProvider.CreateSimpleWebTokenProvider(ComputeSimpleWebTokenString(IssuerName, IssuerKey)); NamespaceManager namespaceClient = new NamespaceManager(serviceUri, provider); // Returns the string in the following format: Issuer=...&HMACSHA256=... static string ComputeSimpleWebTokenString(string issuerName, string issuerSecret) { string issuer = string.Format("{0}={1}", TokenConstants.TokenIssuer, HttpUtility.UrlEncode(issuerName)); string signature = null; // Compute the signature using (HMACSHA256 sha256 = new HMACSHA256(Convert.FromBase64String(issuerSecret))) { signature = Convert.ToBase64String(sha256.ComputeHash(Encoding.UTF8.GetBytes(issuer))); } StringBuilder sb = new StringBuilder(); sb.Append(issuer); sb.Append(TokenConstants.UrlParameterSeparator); sb.Append(string.Format("{0}={1}", TokenConstants.TokenDigest256, HttpUtility.UrlEncode(signature))); return sb.ToString(); }Hope this helpsPlease mark the replies as answers if they help or unmark if not. If you have any feedback about my replies, please contact msdnmg@microsoft.com Microsoft One Code Framework
-
2012年4月15日 上午 10:33
Hi Arwind,
Thank you for the response. Your code sample works fine for a full access admin token. What I need is to limit the audience and action types such as:
only valid on: http://mynamespace.servicebus.windows.net/customerNo
and only valid with Listen permissions. I want to return this token to a client application, so that they can listen for messages on that queue, but cannot listen on any other clients's queue, and can't delete/create other queues.
Would you have any idea how to implement this, maybe using
TokenConstants.TokenAudience
The reason why I used provider.BeginGetWebToken(serviceUri.AbsoluteUri, "Manage", false, new TimeSpan(0, 10, 0), null, null); was because that function takes audience and action as an input parameter.
Kind Regards,
Murat
-
2012年4月15日 下午 01:50版主
Hi,
As ServiceBus use its own Authentication defaulty, so the the application can not recognize the custom token.
Try to change the RelayClientAuthenticationType to close default authentication, and use your own ACS as a STS to protect your service. More details please refer to:
Please mark the replies as answers if they help or unmark if not. If you have any feedback about my replies, please contact msdnmg@microsoft.com Microsoft One Code Framework
-
2012年4月15日 下午 10:56
Hi Arwind,
Thanks again but that's not really what I'm looking for. Especially in the example I mentioned above, I'm trying to give a token to a client so that they can connect to Service Bus queue, not a web service, which means I can't put custom code on top of it.
Is there no way to generate a SWT for service bus queues, that will be specific to an audience, time limited and only limited to, for example, listen action?
Are there any other forums that I can ask this question?
Kind Regards
-
2012年4月18日 上午 05:37
See if this helps http://convective.wordpress.com/2011/10/13/on-not-using-owner-with-the-azure-appfabric-service-bus/
-Sachin Sancheti
- 已提議為解答 Sachin Sancheti 2012年4月19日 上午 04:22
-
2012年4月18日 下午 11:57
Hi Sachin,
Thanks for the post, I was hoping to generate tokens for each connecting client without actually having to create new service identities, but I already confirmed that it makes more sense to generate a service identity for each client application, limit them to realms, and generate tokens from those identities for each client.
Thanks
-
2012年4月19日 下午 11:04The URI must be 'http' for the audience when you get the web token.

