Service Bus Authentication and Authorization with the Access Control Service
Updated: August 25, 2014
Microsoft Azure Service Bus supports the use of Microsoft Azure Active Directory Access Control (also known as Access Control Service or ACS) for authorization of Service Bus operations.
ACS facilitates authentication, meaning it establishes the identity of a caller. ACS has two means of establishing the caller identity. It either establishes the identity based on a namespace-scoped list of service identities (or accounts) using a classic user name and password scheme, or it delegates establishing the identity to an external identity provider, such as Active Directory Federation Services (ADFS), Windows Live ID, Facebook, Google ID, Yahoo ID, or OpenID.
Once the identity has been established, ACS has (or receives) a number of ‘claims’ about the identity. Those claims make statements about the person (or the non-person account), and they are digitally signed by the identity provider that issued the claims, which provides an assurance to ACS that the claims are correct or at least in compliance with the governance rules of the issuer. In other words, a set of claims stating that the represented identity is “Bill Gates, Chairman, Microsoft Corporation” are likely most trustworthy when issued by the Microsoft ADFS gateway, and less so when issued by a third party. The claims that are consistently available across all identity providers and also for the ACS built-in service identities are the provider claim (identifying the provider itself) and the ‘nameidentifier’ claim, which is a provider-specific and provider-unique identifier for the given identity.
Second, ACS facilitates authorization by allowing the claims issued by identity providers to be mapped to claims that are understood by a ‘relying party’. Service Bus is such a relying party, meaning that it relies on ACS to handle authentication and authorization. The mapping of claims serves two purposes: first, it normalizes the claims from a multitude of different claim ‘lingos’ into a single set of claims understood by the service, and, second, the mapping acts as an authorization rule set. If there’s no mapping for a given identity to a set of claims understood by the service, the identity doesn’t have access to the service.
Authentication and authorization always flows through the client, and the client is the only component requiring direct network visibility to all parties. It is, for example, possible to use an ADFS service that is not exposed outside the corporate firewall in conjunction with ACS since ACS and ADFS never talk to each other directly. Whenever the client wants to perform an operation on a protected resource, such as sending a message to a Service Bus queue, it needs to obtain proof that it is authorized to do so. That proof is acquired, from ACS, in form of a ‘token’. The token is simply a container for a set of claims, and is digitally signed by the issuer. If ACS is configured to establish the identity using an external identity provider such as ADFS, there are at least two tokens in play. The first token is acquired from an identity provider such as ADFS, providing one of many kinds of proof of the user’s identity as input. That token is then handed to ACS, which evaluates it, runs the rules, and emits the token for the relying party.
Service Bus and ACS have a special relationship in that each Service Bus service namespace can be paired with a matching ACS service namespace of the same name, suffixed with “–sb”. The reason for this special relationship is in the way that Service Bus and ACS manage their mutual trust relationship and the associated cryptographic secrets.
Inside the “-sb” ACS service namespace, which you can explore from the Azure Portal by selecting the Service Bus service namespace and then clicking the ACS icon on the ribbon, is a “ServiceBus” relying party definition following the ‘Relying Party Applications’ navigation. The relying party definition has a ‘Realm’ value mapping to the root of the matching Service Bus service namespace (using the ‘http’ scheme), and sets the token type to ‘SWT’ and the expiration time of tokens to 1200 seconds. Furthermore, the signing keys are not manageable or accessible through the portal or the API.
Associated with the “ServiceBus” relying party definition is a “Default Rule Group for Service Bus” containing the basic mapping that enables the ‘owner’ of a service namespace to act as super-user on the service namespace. The rule group contains, by default, three simple rules that map the input ‘nameidentifier’ claim for the “owner” service identity to the three permission claims understood by Service Bus: ‘Send’ for all send operations, ‘Listen’ to open up listeners or receive messages, and ‘Manage’ to observe or manage the state of the Service Bus tenant. Service Bus ignores all other claims contained in tokens issued to it. The “owner” service identity is a regular service identity in the ACS service namespace. It is possible, and advised, to create more. In fact, using the “owner” identity should be restricted to performing administrative tasks.
When a client requests an authorization token for sending a message to a queue residing at, for example, https://tenant.servicebus.windows.net/my/test, the token request will include a normalized form of the target address as the intended target realm. This ‘normalization’ simply uses a common URI scheme across all protocols. Therefore, requesting a token for interacting with a Service Bus entity residing at https://tenant.servicebus.windows.net/my/test or sb://tenant.servicebus.windows.net/my/test will always be done using a Realm URI using the ‘http’ scheme http://tenant.servicebus.windows.net/foo/bar. Consequently, all relying party definitions must also use the ‘normalized’ URI scheme ‘http’ for the Realm URI.
When the request arrives at ACS, ACS matches the realm URI to relying party definitions by means of a ‘longest prefix match’, which means that the relying party whose ‘Realm URI’ address is the longest available prefix of the address that the token is requested for, the relying party definition, and its associated rule definitions are selected and run. The default ‘ServiceBus’ relying party definition is scoped to the entirety of the corresponding Service Bus service namespace, meaning that its Realm URI, corresponding to the Service Bus service namespace root address, is a prefix to all possible addresses on a Service Bus service namespace. As such, the rule definitions enabled on this relying party definition grant full access across the entire Service Bus service namespace.
The way to create a scoped set of authorization rules for a queue residing at, for example, https://tenant.servicebus.windows.net/my/test, is to create a new relying party definition, providing the address of the queue or a prefix of that address as the Realm URI of the new definition, either through the ACS portal or the ACS management API. On the portal, the steps are:
Under Relying Party Applications click Add.
Enter some display name, for example MyTest.
Enter http://tenant.servicebus.windows.net/MyTest as the Realm URI for the scope.
Choose SWT as the token format.
Set Encryption Policy to None.
Set Token lifetime to 1200 seconds.
The result is a relying party definition that is exclusive to this address. Because its Realm URI is a suffix of the built-in ‘ServiceBus’ relying party definition, the definition automatically inherits the correct signing keys so that Service Bus trusts tokens issued based on the new definition. However, since there are no associated rules for new the relying party definition, so far, nobody will be able to access the queue, not even the “owner”, because there is no automatic implicit inheritance of rules between relying party definitions even if they form a hierarchy.
After creating the new definition, there will be a “Default Rule Group for <displayname>” in the Rule Groups section of the ACS portal. This new group is empty by default. In order to permit access to the queue, rules need to be added to the group, which is explained in the following section. Alternatively, an already existing rule group with rules can be enabled for the relying party definition. Each rule group can be seen as a separate access control list that can be enabled anywhere in the relaying party hierarchy. To enable file-system like inheritance, for example to inherit the default rules of the Service Bus service namespace root, the corresponding “Default Rule Group for ServiceBus” and any other rule group can simply be enabled on the relying party definition – which requires checking the right box in the ‘Rule groups’ section of the Relying Party definition on the portal. For cases in which a common set of access rules should be applied across a number of resources, for example common rules for a set of parallel resources such as sibling queues at http://tenant.servicebus.windows.net/my/test and http://tenant.servicebus.windows.net/my/zoo, the relying party definition can also be scoped to the shared service namespace branch, such as http://tenant.servicebus.windows.net/my.
In other cases, scenarios may call for managing access control differently for aspects of the same Service Bus entity, such as different permissions on different subscriptions of a topic. In these cases it is possible to create a relying party definition scoped to a particular subscription name, such as http://tenant.servicebus.windows.net/my/test/subscriptions/sub1/, and have that definition hold the rules applying only to the particular named subscription.
Rules are defined in rule groups and generally map an input claim to an output claim. All rules in a group yield a single combined result, so if there are three matching rules for a given input claim set that yield three distinct output claims, the issued authorization token will contain all three claims. For Service Bus, the three permission claims are ‘Send’ for all send operations, ‘Listen’ to open up listeners or receive messages, and ‘Manage’ to observe or manage the state of the Service Bus tenant. To be precise, ‘Send’, ‘Listen’, and ‘Manage’ are the permitted values of the claim-type ‘net.windows.servicebus.action’. Creating a rule for Service Bus requires mapping an input claim, such as the nameidentifier of a service identity, to the desired permission claim. To grant the service identity “contoso” the permission to ‘Send’ on a queue, the rule definition would therefore map the issuer’s nameidentifier claim with the value “contoso” to a custom output claim of type ‘net.windows.servicebus.action’ with a value of ‘Send’. Granting the service identity all three permission claims requires three distinct rules. The goal of having just three permission claims is to limit the complexity of defining rules.
A token provider is a generic construct in the .NET managed API for Service Bus that allows turning some form of credential into an authorization token issued by the ACS service, that can then be passed on to Service Bus to perform the desired operation. TokenProvider is an abstract base class with three concrete implementations accessible via factory methods for the most basic scenarios:
Shared Secret – allows obtaining a token based on a service identity (and the shared key associated with that identity) that has been defined in the Service Bus service namespace “-sb” buddy namespace in ACS. The pre-provisioned service identity created when the service namespace is created is called “owner” and its shared secret is available through the management portal.
Simple Web Token (SWT) – allows obtaining a token based on a previously acquired SWT token passed to ACS via the token provider. The token is passed to ACS as a binary token using a WS-Trust/WS-Federation RST/RSTR request. Please refer to the ACSdocumentation for information about how to configure WS-Federation providers.
SAML – allows obtaining a token based on a previously acquired SAML token passed to ACS via the token provider. The token is passed to ACS using a WS-Trust/WS-Federation RST/RSTR request. Please refer to the ACSdocumentation for information about how to configure WS-Federation providers.
The Service Bus MessagingFactory, NamespaceManager, and TransportClientEndpointBehavior APIs accept TokenProvider instances. The token provider is called as tokens are required, which includes scenarios where a long-lived connection needs to acquire a new token once the existing token has passed its expiration (which defaults to 1200 seconds). Federation scenarios that require user interaction do require implementation of a custom token provider.
As an example, a custom token provider to enable a particular Facebook user to send messages to a particular queue will have to present the user, via ACS, with the appropriate Facebook UI to establish the Facebook identity, redirect via ACS to trade the Facebook token for an ACS token for Service Bus, and then extract the ACS token as the request gets redirected to the local application. The Service Bus Codeplex site will contain a growing collection of token provider examples for customization.