New: SAS token support in the new Azure Service Bus .NET Core client

For some time now, Azure Service Bus comes with two client libraries. The first is the good old WindowsAzure.ServiceBus, which is functionally complete and mature, but requires the full .NET Framework 4.5. The second is the new Microsoft.Azure.ServiceBus library which targets .NET Standard and is therefore usable within .NET Core, but is not functionally complete yet.

ASB

But a couple of days ago, at least one of those functional omissions was (partly) resolved with the release of version 2.0.0 of the client, because this version now offers rudimentary support for SAS tokens. Rudimentary because it will not generate tokens for you yet, but it will play nicely with tokens you crafted yourself.

Why is that important? Well, because SAS tokens play a key role in messaging scenarios that cross organizational boundaries. When two parties from different organizations communicate via Request/Reply messaging for example, one or both parties will be communicating via one or more queues that belong to the other party’s organization. In those situations, you’d typically prefer granting access using SAS tokens instead of keys.

Because crafting a SAS token is a rather precise task that can take some time for first-timers, I created a simple Request/Reply sample that involves using a SAS token. It’s intentionally kept simple so you will want to expand upon it before using it in your own application; it just aims to showcase the general idea of generating and using SAS tokens in a Request/Reply scenario. Let me know what you think in the comments!

Advertisements

HowTo: Secure a Custom Webhook for Azure Event Grid

As I wrote before, I’m playing around with the new Azure Event Grid lately. As I mentioned in my previous post, custom event publishers and subscribers hold a lot of promise, especially while we are still awaiting the bulk of Azure services to be hooked up to Event Grid.

AEG

But for custom publishers and subscribers to actually lift off, we need some way to authorize calls, both those from the publisher to Event Grid and those from Event Grid to the subscriber endpoint. Now the first is pretty well covered in the docs. But the call from Event Grid to the subscriber endpoint is not very well described at this point in time. It just mentions some initial validation sequence, which is supposed to prove ownership of the endpoint but in actuality just verifies that the endpoint is expecting to handle Event Grid events.

If this were the whole story, having an Event Grid subscriber endpoint would imply accepting unauthorized calls containing event payloads, meaning anyone with knowledge of the endpoint address can send bogus events your way – and since you have no way to tell authentic from fake events, you’d also be opened up for Denial of Service.

503-error

Luckily, a conversation with the Product Team quickly revealed that this is not the whole story. When you register a subscriber endpoint in Azure Event Grid, you can include a query string. This query string will be included in each and every call to your endpoint, so both the initial validation call and subsequent event notification calls. If you put some sort of key in there and then verify its presence in each incoming call, you’ve effectively locked out the Man In The Middle, and you just made a Denial of Service a lot harder.

EditEventSub

Furthermore, query strings that are added this way are not visible when enumerating Event Grid Subscribers in the portal, as an added layer of security.

ListEventSubs

I’ve updated my code samples to include a possible way to handle this for a ASP.NET Core WebAPI webhook.

Thanks to Dan Rosanova for clearing up how authorizing Event Grid calls to custom webhooks can be done.

Handling Custom Azure Event Grid Events

Lately I’ve been exploring the new possibilities opened up by Azure Event Grid, which was introduced last month.

Azure Event Grid is a fully managed platform for publishing and subscribing to event notifications. It is intended to ultimately encompass all Azure services as event publishers and/or subscribers but it also allows for custom, non-Azure participants. At this point, the following publishers and handlers are available:

event-grid-functional-model

For a little bit of background information on how AEG relates to the other event offerings on Azure, such and Event Hub or Service Bus, see this write-up by Saravana Kumar.

Long story short: it all looks very promising, but since most Azure services are yet to be hooked up to Event Grid the custom topic publishers and WebHook subscribers may hold the most promise for the short term.

So I tried my hand at actually getting that to work with a console app for publishing and a ASP.NET Core WebAPI for handling; code is available here.

In general, it’s relatively straightforward. The only thing that took me some time to get right is the handling of the validation process. The issue was that the documentation says that the validation request contains a header ‘Event-Key’ with a value of ‘Validation’. In actuality, this is ‘aeg-event-key’ with value ‘SubscriptionValidation’. Since my API is routing the validation request to a special action based on the header, this is pretty relevant. But, let’s keep in mind that Event Grid is in preview at this point, and the documentation is part of that status.

HowTo: Perform “On Behalf Of” Calls Using Azure Active Directory

Probably every developer out there is familiar with the scenario of a UI-driven application (let’s say a web app) that needs to make calls to a backend service, and in quite a few of those scenarios the backend service needs to know which user is logged in in order to fullfill the request. And if you have ever been in charge of deciding on an implementation for this, you have been at the crossroads: do I go with the full-fledged impersonation / delegation solution, or do I conveniently decide that I trust the web app to make the correct calls?

If you’ve chosen the latter, you went with the so-called trusted subsystem architecture. Simply put: your backend service is treating the web app as a system that can be trusted to properly authenticate end users, and only perform backend service calls if and when appropriate, possibly including end user identifiers (such as usernames) as part of these calls.

Trusted Subsystem
The Trusted Subsystem solution

If you opted for the full-fledged impersonation and delegation solution, you probably learned very soon that this is hard. In the old on-prem enterprise world, you would have to learn about the intimate details of Kerberos Constrained Delegation. And if you were ‘lucky’ enough to be working with WIF and WS-Federation or SAML, you would find out that these protocols do support these scenarios, but still make it pulling-your-hair-out-difficult to implement. And now we’re just calling one downstream service from our web app; once we need to call yet another service from the first service, we more often than not just give up and go with the trusted subsystem approach after all.

Azure Active Directory To The Rescue

Luckily, SAML and WS-* are no longer the only protocols available. OAuth 2.0 and OpenID Connect have been gaining momentum for some time now, and are treated as first class citizens in the latest Identity & Access Management solutions that Microsoft is offering, especially Azure Active Directory. To add to that, Microsoft has provided a client-side library called ADAL (Active Directory Authentication Library) for a variety of platforms (including AngularJS and iOS for example) to simplify interaction with Azure Active Directory as much as possible.

And the good news is: even impersonation and delegation has gotten really simple, with a lot less moving parts on the client. (Everyone who has ever struggled with config files trying to get this to work using WS-* and WIF knows exactly what I mean…)

The guys at Microsoft are also putting a lot of effort into code samples on Github that show how to use Azure AD and ADAL to get all sorts of scenarios working.

image

The On Behalf Of scenario is also available on there. It’s a native client that calls an API, which in turn calls the Graph API on behalf of the logged in user. Obviously, the native client app can be substituted for an ASP.NET Core MVC web app, as shown in this repo.

Not every platform-scenario-combo is available. For example, the API calling another API scenario (i.e. the On Behalf Of scenario) is not available in its ASP.NET Core incarnation. And since the code to achieve this for ASP.NET Core Web API is not readily deducible from the native client sample that is only available with a ASP.NET Web API, I’d like to share some of it here.

First of all, the middleware to wire up an ASP.NET Core Web API to actually consume tokens is a bit different from how it used to be done. You can take you queue from the aforementioned repo; just make sure to save the token you receive so that you can access it later:

app.UseJwtBearerAuthentication(new JwtBearerOptions
{
    AutomaticAuthenticate = true,
    AutomaticChallenge = true,
    Authority = String.Format(Configuration["AzureAd:AadInstance"], Configuration["AzureAD:Tenant"]),
    Audience = Configuration["AzureAd:Audience"],
    SaveToken = true
});

Actually using this token to bootstrap the On Behalf Of flow works like this:

var authority = [insert authority here];
var clientId = [insert client ID here];
var clientSecret = [insert client secret here];
var resourceId = [insert the resource ID for the called API here];

AuthenticationContext authContext = new AuthenticationContext(authority);
ClientCredential credential = new ClientCredential(clientId, clientSecret);
AuthenticateInfo info = await HttpContext.Authentication.GetAuthenticateInfoAsync(JwtBearerDefaults.AuthenticationScheme);
var token = info.Properties.Items[".Token.access_token"];
var username = User.FindFirst(ClaimTypes.Upn).Value;
var userAssertion = new UserAssertion(token, "urn:ietf:params:oauth:grant-type:jwt-bearer", username);
AuthenticationResult result = await authContext.AcquireTokenAsync(resourceId, credential, userAssertion);

The AuthenticationResult that ADAL is returning here contains an Access Token that can be used to call the downstream Web API. Simple, right? OK, it involves some code, but it’s pretty straighforward when compared to a WS-*-and-a-WCF-service scenario I wrote about earlier.

Enter Microservices

As said before, we’ve all encountered On Behalf Of scenarios and the perils of getting them to work using SAML, WS-* or Kerberos, and more often than not we gave up on the full-fledged scenario. But in an increasingly API-centered world, we are calling other external services much more frequently than we did only a couple of years ago. And now that microservices gains a lot of momentum as an architectural style, this frequency increases even more since fulfilling a user request in a microservices environment is pretty much always a matter of multiple services collaborating.

Advocates of microservices recognize that flowing user identities through services is a concern that deserves more attention in a microservices architecture. Sam Newman, for example, discusses this issue in his book Building Microservices, in a paragraph aptly titled “The Deputy Problem”.

He recognizes the ease of use that comes with OpenID Connect and OAuth 2.0. And while he is still somewhat skeptical about whether these protocols will make it into the mainstream market any time soon, for all you dev’s out there that are on the Microsoft ecosystem, this is not a concern anymore.

Extending The Scenario

Obviously, we want to do more than simply impersonate end users when calling downstream services. Especially in a microservices environment, where multiple clients are calling multiple services for even the most mundane of tasks, we may want to have varying levels of trust: “Sure, I’d be more than happy to perform this request for the user, but only if he is calling me through an application that is entrusted to make these types of delegated calls.” In order words, you may want to base your authorization decisions on characteristics of both the end user and the calling app.

Azure Active Directory is capable of handing these types of scenarios as well, for example by using scopes. I’m not getting into those now, but I’ll be teaming up with my colleague Jurgen van den Broek for a session at the Dutch TechDays 2016, in which we will cover these and a lot more scenarios – including a peek into the future by discussing what the AAD v2 endpoint brings to the table.

Immediately after the TechDays session, I’ll update this post with a link to the full code sample. So stay tuned, and feel free to post a comment if you need help in the meantime.