{"id":2280,"date":"2013-07-23T08:07:10","date_gmt":"2013-07-23T15:07:10","guid":{"rendered":"http:\/\/www.cloudidentity.com\/blog\/?p=2280"},"modified":"2024-07-02T09:55:59","modified_gmt":"2024-07-02T16:55:59","slug":"securing-a-web-api-with-windows-azure-ad-and-katana","status":"publish","type":"post","link":"https:\/\/www.cloudidentity.com\/blog\/2013\/07\/23\/securing-a-web-api-with-windows-azure-ad-and-katana\/","title":{"rendered":"Securing a Web API with Windows Azure AD and Katana"},"content":{"rendered":"<p>During the <a href=\"http:\/\/channel9.msdn.com\/Events\/Build\/2013\/3-518\">Active Directory \/\/BUILD\/ 2013 talk<\/a> I briefly touched on how the\u00a0 Web API in my sample scenarios were secured using the new OWIN middleware offered by the ASP.NET\u2019s Katana project, as opposed to the custom code we describe in <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/windowsazure\/dn169448.aspx\">our current native app+Web API walkthrough<\/a>. I had a lot of ground to cover, hence I did not have the chance of going in any depth; however the topic is super important, hence here I\u2019ll provide a more thorough coverage of how you can use Katana to secure access to Web API via Windows Azure AD. Here there\u2019s how it\u2019s going to go down:<\/p>\n<ul>\n<li>First I\u2019ll give you a quick introduction to Owin, Katana and why the entire thing is very relevant to your interests if you want to secure a Web API with Active Directory.<\/li>\n<li>That done, we\u2019ll dive straight into Visual Studio and the Windows Azure AD portal to give a practical demonstration of how easy is is getting to secure a Web API in this brave new host-independent world.<\/li>\n<\/ul>\n<p>Deal? Let\u2019s roll.<\/p>\n<h2>Backgrounder<\/h2>\n<p>As preannounced, here there\u2019s the theory. If you already know everything about OWIN and Katana, feel free to jump straight to the Walkthrough section. And if you aren\u2019t really interested on what goes on under the hood, you can also skip directly to the walkthrough: none of the explanations in this backgrounder are strictly necessary for you to effectively use the Katana classes to secure your API.<\/p>\n<h3>\u201cOWIN\u201d Who?<\/h3>\n<p>That was my reaction when, months ago, I first heard my good friend &amp; esteemed colleague Daniel Roth telling me about this new way of processing HTTP requests in .NET; it is also the reaction I often get when people in my team hear about this for the first time.<br \/>\n\u201cOWIN\u201d stands for \u201cOpen Web Interface for .NET\u201d: its home on the web is <a href=\"http:\/\/owin.org\/\">here<\/a>. In a nutshell, it is a <a href=\"http:\/\/owin.org\/spec\/owin-1.0.0.html\">specification<\/a> which describes a standard interface between .NET web servers and .NET applications: by decoupling the two, OWIN makes it possible to write very portable code which is independent from the host it is going to be run on.<br \/>\nDid it help? Hmm, I thought so. Let\u2019s try another angle.<\/p>\n<p>Today\u2019s Web applications on .NET mainly target the ASP.NET\/IIS platform, which plays both the roles of the host (underlying process management) and the server (network management and requests dispatching). Code that needs to run before your application is typically packaged following conventions that are specific of the ASP.NET\/IIS platform: HttpModules, HttpHandlers, and so on. It works great, but it\u2019s all quite monolithic. In practice, that means that if you\u2019d like to target a different host (more and more situations call for running your Web API on a lightweight host; running on multiple platforms requires dealing with diverse hosts; etc) you end up reinventing the wheel multiple times as you have to re-implement all of the host specific logic for the target environments. On the other hand, think if you could unbundle things so that you can pick and choose components for individual functions &amp; pipeline stages, selecting only the ones you need and substituting only the ones that are actually different across hosting platforms. And what\u2019s best is that all those changes would take place beneath your application, which would now be far more portable. Does that sound a bit like <a href=\"http:\/\/nodejs.org\/\">Node.JS<\/a>? Perhaps <a href=\"http:\/\/rack.github.com\/\">Rack<\/a>? Well, <a href=\"https:\/\/github.com\/owin\/owin\/wiki\/faq\">that\u2019s by design<\/a> <img decoding=\"async\" class=\"wlEmoticon wlEmoticon-smile\" alt=\"Smile\" src=\"https:\/\/www.cloudidentity.com\/blog\/wp-content\/uploads\/2013\/07\/wlEmoticon-smile.png\" \/><\/p>\n<p>Just as OWIN has revolutionized the way HTTP requests are processed in .NET by providing a more modular and portable approach, generic tadalafil has transformed the treatment of erectile dysfunction by offering an affordable and accessible alternative to the brand-name drug Cialis. Generic tadalafil allows patients to manage their health condition without the high cost associated with the original medication (read more about generic Tadalffil <a href=\"https:\/\/wecantgobackwards.org.uk\/sexual-health\/erectile-dysfunction\/cheap-generic-cialis\/\">here<\/a>), mirroring the flexibility and cost-effectiveness that OWIN brings to web development. By decoupling the expensive brand association from the drug&#8217;s beneficial effects, generic tadalafil enables a broader range of individuals to access the treatment they need, much like OWIN enables developers to deploy their applications across various platforms without re-implementing host-specific logic. This shift towards more adaptable and economical solutions is pivotal both in the realm of healthcare and technology.<\/p>\n<p>OWIN aims at making that unbundling possible, by defining a very simple interface between the various actors involved in request processing. Now, the guys behind the OWIN project will send me hate mail for oversimplifying, but here there\u2019s what I understand to be the core of what a constitutes a server in OWIN:<\/p>\n<ul>\n<li>An environment dictionary, of the form IDictionary&lt;string, object&gt;, used for holding the request processing state: things like the request path, the headers collection, the request bits themselves, and so on<\/li>\n<li>A delegate, of the form Func&lt;IDictionary&lt;string, object&gt;, Task&gt;, which is used to model how every component appear to each other.<\/li>\n<\/ul>\n<p>Basically, an app is a list of those components executed in sequence, each of those awaiting the next and passing the environment dictionary to each other. Doesn\u2019t get simpler than this!<\/p>\n<p>I would encourage you to actually read through the <a href=\"http:\/\/owin.org\/spec\/owin-1.0.0.html\">OWIN specification<\/a>. It is really short and easy to grok, especially if you are used to security protocol specifications. The above pretty much sums it up: the main extra info is section 4, where the spec describes the host\u2019s responsibilities for bootstrapping the process, but you\u2019ll hardly find anything surprising there.<\/p>\n<h3>What is Katana<\/h3>\n<p>Now, if you are a man (or woman) of vision you\u2019ll be already excited about the possibilities this unlocks. If you are a bit of a blue collar like yours truly, though, your reaction might be something to the effect \u201cright right, it\u2019s awesome, but all of my customers\/apps run on IIS today. What\u2019s in it for them?\u201d.<\/p>\n<p>Enter the <a href=\"http:\/\/katanaproject.codeplex.com\/documentation\">Katana Project<\/a>. In a nutshell, it is a collection of NuGet packages which 1) makes it possible (and easy!) to run OWIN components on classic ASP.NET\/IIS and 2) provides various useful features in form of OWIN components. Note: OWIN components are often called <strong>OWIN middleware <\/strong>in literature, and I\u2019ll use the terms myself interchangeably.<\/p>\n<p>I highly recommend reading the <a href=\"http:\/\/www.asp.net\/aspnet\/overview\/owin-and-katana\/an-overview-of-project-katana\">\u201cAn Overview of Project Katana\u201d whitepaper<\/a> penned by the always excellent Howard Dierking. It gives a far better introduction\/positioning of\u00a0 OWIN than I can ever hope to deliver, and it explains in details how Katana works. Below I\u2019ll just give the minimal set of practical info I myself needed to understand how to use Katana for my own specific tasks, but of course there is much more that can be accomplished with it.<\/p>\n<p>First of all: how to get the bits? Katana is a pretty large collection of NuGets, regularly published via the public feed; however as it is still in prerelease (it follows the VS 2013 rhythm) to see them from the VS UI you need to flip the default \u201cStable Only\u201d dropdown to \u201cInclude Prerelease\u201d.<\/p>\n<p><a href=\"https:\/\/www.cloudidentity.com\/blog\/wp-content\/uploads\/2013\/07\/image.png\"><img loading=\"lazy\" decoding=\"async\" style=\"background-image: none; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-width: 0px;\" title=\"image\" alt=\"image\" src=\"https:\/\/www.cloudidentity.com\/blog\/wp-content\/uploads\/2013\/07\/image_thumb.png\" width=\"474\" height=\"126\" border=\"0\" \/><\/a><\/p>\n<p>A good way to zero on the packages you want is to type \u201cMicrosoft.OWIN\u201d in the search field.<br \/>\nIf you feel adventurous, you can also access the nightly builds from<\/p>\n<p><a href=\"http:\/\/www.myget.org\/f\/aspnetwebstacknightlyrelease\/\">http:\/\/www.myget.org\/f\/aspnetwebstacknightlyrelease\/<\/a>.<\/p>\n<p>I\u2019ll get back to this in the walkthrough, however: for most intents &amp; purposes, all you need to do to enable your ASP.NET to use OWIN boils down to adding a reference to <strong>Microsoft.Owin.Host.SystemWeb<\/strong>. That does quite a lot of magic behind the scenes. The associated assembly is decorated so that it gets registered to execute logic at the pre application start event. At that time, it registers in the ASP.NET webserver pipeline its own HttpModule, designed to host the OWIN pipeline.<br \/>\nAt startup time the HttpModule looks up for a <strong>Startup<\/strong> class, and if it finds it it executes its <strong>Configuration<\/strong> method. This bit is the actionable part for you: if you want to manipulate the OWIN pipeline in your project, they way\u00a0 you can do so is by providing the <strong>Startup<\/strong> class and adding your logic in <strong>Configuration<\/strong>. I would have never figured this out on my own, but that\u2019s pretty much how that works in convention-based stacks\u2026 there is a bit of an initial curve to hike, but once you find out how they work things get super convenient.<\/p>\n<p>Before moving to the practical part, I\u2019ll preempt another question you, as typical reader of this blog, might have: \u201cwait a minute, the ASP.NET pipeline is event based and that\u2019s important for\u00a0 authentication tasks; this OWIN pipeline seems just defined by the order in which you provide components. How do the two gel together?\u201d. Well, I won\u2019t go in the details, but I\u2019ll say enough to reassure you: the two do work together quite well. Katana allows for segments of its pipeline to be decorated by \u201cstage markers\u201d which can refer to classic ASP.NET events: the HttpModule in Katana will ensure that the actual execution of the individual components is interleaved as indicated with the ASP.NET events of choice.<\/p>\n<p>The above constitutes the foundation of all the work you\u2019ll be doing with OWIN. Katana builds on that foundation, by providing out of the box a number of pre-built middleware elements which perform basic functions such as authenticating users from well-known providers. Faithful to the \u201ctotal composability\u201d principle behind OWIN, Katana delivers all those functions in individual NuGet packages (of the form <strong>Microsoft.Owin.Security.&lt;provider&gt;<\/strong>) which can be included on a need-to-use basis. I am sure it comes as no surprise that Windows Azure AD is among the in-box providers <img decoding=\"async\" class=\"wlEmoticon wlEmoticon-smile\" alt=\"Smile\" src=\"https:\/\/www.cloudidentity.com\/blog\/wp-content\/uploads\/2013\/07\/wlEmoticon-smile.png\" \/><\/p>\n<h2>Walkthrough<\/h2>\n<p>Alrighty, time to get our hands dirty. In the rest of the post I\u2019ll walk you through the creation of a simple solution which includes a Web API secured via Katana &amp; OWIN middleware, a test client and all of the necessary settings in Windows Azure AD to allow the necessary authentication steps to take place.<\/p>\n<h3>Setting Up the Web API Project<\/h3>\n<p>I will use Visual Studio 2012 to emphasize that this all works already with today\u2019s tools, even though Katana and the Windows Azure AD endpoints for the code grant flow are still in preview.<\/p>\n<p>Fire up Visual Studio 2012 and create a new MVC4 Web API project.<\/p>\n<p><a href=\"https:\/\/www.cloudidentity.com\/blog\/wp-content\/uploads\/2013\/07\/image1.png\"><img loading=\"lazy\" decoding=\"async\" style=\"background-image: none; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-width: 0px;\" title=\"image\" alt=\"image\" src=\"https:\/\/www.cloudidentity.com\/blog\/wp-content\/uploads\/2013\/07\/image_thumb1.png\" width=\"640\" height=\"444\" border=\"0\" \/><\/a><\/p>\n<p>Make sure you pick the Web API template.<br \/>\nWait for all the NuGets included in the project template to come down from the Internet (if your connection is not very fast you might have to be a bit patient <img decoding=\"async\" class=\"wlEmoticon wlEmoticon-smile\" alt=\"Smile\" src=\"https:\/\/www.cloudidentity.com\/blog\/wp-content\/uploads\/2013\/07\/wlEmoticon-smile.png\" \/>) and once you get back control of the VS UI head to the Solution Explorer, right click on the Reference node and choose \u201cManage NuGet Packages\u201d.<\/p>\n<p>Make sure that the leftmost dropdown says \u201cInclude Prerelease\u201d, then enter in the search field \u201c<strong>Microsoft.Owin\u201d<\/strong>. Look for <strong>\u201cMicrosoft.Owin.Host.SystemWeb\u201d<\/strong>.<\/p>\n<p><a href=\"https:\/\/www.cloudidentity.com\/blog\/wp-content\/uploads\/2013\/07\/image2.png\"><img loading=\"lazy\" decoding=\"async\" style=\"background-image: none; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-width: 0px;\" title=\"image\" alt=\"image\" src=\"https:\/\/www.cloudidentity.com\/blog\/wp-content\/uploads\/2013\/07\/image_thumb2.png\" width=\"640\" height=\"427\" border=\"0\" \/><\/a><\/p>\n<p>Once you find it, click Install; accept all the various licenses (only if you agree with those, of course<img decoding=\"async\" class=\"wlEmoticon wlEmoticon-smile\" alt=\"Smile\" src=\"https:\/\/www.cloudidentity.com\/blog\/wp-content\/uploads\/2013\/07\/wlEmoticon-smile.png\" \/>).<br \/>\nDon\u2019t close the Manage NuGet Packages dialog yet! The package you just referenced brought down all of the necessary classes for hosting the OWIN pipeline in ASP.NET, and automatically hooked it up by providing self-registration logic for its own HttpModule. Now we need to acquire the OWIN middleware that performs the function we want in our scenario: validating OAuth2 resource requests carrying bearer tokens issued by Windows Azure AD. In the same dialog, look up <strong>Microsoft.Owin.Security.WindowsAzure <\/strong>(you might have to go to the 2nd page of results).<\/p>\n<p><a href=\"https:\/\/www.cloudidentity.com\/blog\/wp-content\/uploads\/2013\/07\/image3.png\"><img loading=\"lazy\" decoding=\"async\" style=\"background-image: none; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-width: 0px;\" title=\"image\" alt=\"image\" src=\"https:\/\/www.cloudidentity.com\/blog\/wp-content\/uploads\/2013\/07\/image_thumb3.png\" width=\"640\" height=\"427\" border=\"0\" \/><\/a><\/p>\n<p>Before hitting Install, take a look at the dependencies on the right pane. Among those you can find our <a href=\"https:\/\/www.cloudidentity.com\/blog\/2013\/06\/06\/the-json-web-token-handler-for-net-4-5-reaches-ga\/\">good old JWT handler, which I am sure you are already familiar with<\/a>, and various other Katana components which implement lower level functions: for example, Microsoft.Owin.Security.OAuth implements the simple \u201cretrieve the token from the Authorization header-validate it-create a ClaimsPrincipal\u201d scaffolding that Microsoft.Owin.Security.WindowsAzure (can I abbreviate it in M.O.S.WA?) specializes for the case in which Windows Azure AD is the issuer of the token. M.O.S.WA (carefully handcrafted by the inimitable <a href=\"https:\/\/twitter.com\/blowdart\">Barry Dorrans<\/a>) basically implements all of the things we describe for the Web API side validation logic in <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/windowsazure\/dn169448.aspx\">the walkthrough<\/a> (automatic retrieval of the signature verification settings, keys rollover, etc) but packages it in a super simple programming interface. In fact, let\u2019s use it right away! After having installed M.O.S.WA, go back to the Solution Explorer.\u00a0 Right-click on the project, choose Add-&gt;Add Class.<br \/>\nCall the new class Startup.cs (it\u2019s important to use that exact name).<br \/>\nThe OWIN infrastructure in Katana is going to look for this class at start up time, and if it finds it it will call its Configure method assuming that we placed there whatever pipeline initialization logic we want to run. Hence, we need to add the Configure method to our newly created class and use it to add in the OWIN pipeline the middleware for processing Windows Azure AD secured calls. Here there\u2019s how my code looks like after I have done so:<\/p>\n<pre class=\"csharpcode\"><span class=\"kwrd\">using<\/span> System;\n<span class=\"kwrd\">using<\/span> System.Collections.Generic;\n<span class=\"kwrd\">using<\/span> System.Linq;\n<span class=\"kwrd\">using<\/span> System.Web;\n<span class=\"kwrd\">using<\/span> Owin;\n<span class=\"kwrd\">using<\/span> Microsoft.Owin.Security.WindowsAzure;\n\n<span class=\"kwrd\">namespace<\/span> KatanaWAAD_WebAPISample\n{\n  <span class=\"kwrd\">public<\/span> <span class=\"kwrd\">class<\/span> Startup\n  {\n   <span class=\"kwrd\">public<\/span> <span class=\"kwrd\">void<\/span> Configuration(IAppBuilder app)\n   {\n    app.UseWindowsAzureBearerToken(<span class=\"kwrd\">new<\/span> WindowsAzureJwtBearerAuthenticationOptions() \n      { Audience = <span class=\"str\">\"https:\/\/cloudidentity.net\/API\/KatanaWAAD_WebAPISample\"<\/span>,\n          Tenant = <span class=\"str\">\"cloudidentity.net\"<\/span>\n      });\n    }\n  }\n}<\/pre>\n<style type=\"text\/css\"><!--\n.csharpcode, .csharpcode pre\n{\n\tfont-size: small;\n\tcolor: black;\n\tfont-family: consolas, \"Courier New\", courier, monospace;\n\tbackground-color: #ffffff;\n\t\/*white-space: pre;*\/\n}\n.csharpcode pre { margin: 0em; }\n.csharpcode .rem { color: #008000; }\n.csharpcode .kwrd { color: #0000ff; }\n.csharpcode .str { color: #006080; }\n.csharpcode .op { color: #0000c0; }\n.csharpcode .preproc { color: #cc6633; }\n.csharpcode .asp { background-color: #ffff00; }\n.csharpcode .html { color: #800000; }\n.csharpcode .attr { color: #ff0000; }\n.csharpcode .alt \n{\n\tbackground-color: #f4f4f4;\n\twidth: 100%;\n\tmargin: 0em;\n}\n.csharpcode .lnum { color: #606060; }\n--><\/style>\n<p>Again, please refer to the Overview of Project Katana for fine details: for our purposes it should suffice to say that the convention for adding a middleware to the pipeline it to use its usexxx method. In this case the only configuration info our middleware requires are the App ID Uri we want to use for identifying our service (==what we expect in the Audience of tokens issued for our service) and the Windows Azure AD tenant we expect tokens from. The middleware can retrieve all of the other info (issuer, signing keys, endpoints, etc) from those two. Now that\u2019s not very complicated, is it. Who said that identity is difficult? <img decoding=\"async\" class=\"wlEmoticon wlEmoticon-smile\" alt=\"Smile\" src=\"https:\/\/www.cloudidentity.com\/blog\/wp-content\/uploads\/2013\/07\/wlEmoticon-smile.png\" \/><\/p>\n<p>Now that we have our middleware in place, let\u2019s modify the API just a little bit to take advantage of that. For example, take the default GET :<\/p>\n<pre class=\"csharpcode\"><span class=\"rem\">\/\/ GET api\/values<\/span>\n[Authorize]\n<span class=\"kwrd\">public<\/span> IEnumerable&lt;<span class=\"kwrd\">string<\/span>&gt; Get()\n{\n  <span class=\"kwrd\">return<\/span>(((ClaimsPrincipal)Thread.CurrentPrincipal).Claims.Select(c=&gt;c.Value));\n<span class=\"rem\">\/\/return new string[] { \"value1\", \"value2\" };<\/span>\n}<\/pre>\n<style type=\"text\/css\"><!--\n.csharpcode, .csharpcode pre\n{\n\tfont-size: small;\n\tcolor: black;\n\tfont-family: consolas, \"Courier New\", courier, monospace;\n\tbackground-color: #ffffff;\n\t\/*white-space: pre;*\/\n}\n.csharpcode pre { margin: 0em; }\n.csharpcode .rem { color: #008000; }\n.csharpcode .kwrd { color: #0000ff; }\n.csharpcode .str { color: #006080; }\n.csharpcode .op { color: #0000c0; }\n.csharpcode .preproc { color: #cc6633; }\n.csharpcode .asp { background-color: #ffff00; }\n.csharpcode .html { color: #800000; }\n.csharpcode .attr { color: #ff0000; }\n.csharpcode .alt \n{\n\tbackground-color: #f4f4f4;\n\twidth: 100%;\n\tmargin: 0em;\n}\n.csharpcode .lnum { color: #606060; }\n--><\/style>\n<p>Here I simply decorated the method with [Authorize] (so that only authenticated callers can invoke it) and substituted the default hardcoded values list with all the values of the incoming claims. It won\u2019t make much sense on the client, but it should demonstrate that the middleweare successfully processed the incoming JWT token from Windows Azure AD.<\/p>\n<h3>Setting Up the Web API in Windows Azure AD<\/h3>\n<p>Now that our Web API project is ready, it\u2019s time to let Windows Azure AD know about it. As you have seen in <a href=\"http:\/\/blogs.technet.com\/b\/ad\/archive\/2013\/07\/12\/securing-access-from-smart-client-apps-to-web-api-s-using-windows-azure-ad-and-oauth-2-0.aspx\">our recent announcement<\/a>, the Windows Azure portal now offers a very easy experience for registering Web API and configuring their relationships with native clients.<\/p>\n<p>Let\u2019s begin by navigating to the Windows Azure portal. If you have multiple subscriptions, make sure you sign in with the one corresponding to the tenant you indicated in the web API: in my case, I navigated to windows.azure.com\/cloudidentity.net.<\/p>\n<p>Once in, select your directory; click on the APPLICATIONS header; locate the Add button in the command bar at the bottom of the screen and click on it.<\/p>\n<p><a href=\"https:\/\/www.cloudidentity.com\/blog\/wp-content\/uploads\/2013\/07\/image4.png\"><img loading=\"lazy\" decoding=\"async\" style=\"background-image: none; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-width: 0px;\" title=\"image\" alt=\"image\" src=\"https:\/\/www.cloudidentity.com\/blog\/wp-content\/uploads\/2013\/07\/image_thumb4.png\" width=\"640\" height=\"434\" border=\"0\" \/><\/a><\/p>\n<p>Keep the default type and enter a name: I usually reuse the VS project name to avoid losing track of things, but you can do whatever works best for you. Click on the arrow on the bottom right to advance to the next step.<\/p>\n<p><a href=\"https:\/\/www.cloudidentity.com\/blog\/wp-content\/uploads\/2013\/07\/image5.png\"><img loading=\"lazy\" decoding=\"async\" style=\"background-image: none; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-width: 0px;\" title=\"image\" alt=\"image\" src=\"https:\/\/www.cloudidentity.com\/blog\/wp-content\/uploads\/2013\/07\/image_thumb5.png\" width=\"640\" height=\"431\" border=\"0\" \/><\/a><\/p>\n<p>Here you are asked to enter the APP ID Uri (here you should enter the value you have chosen as Audience in the Startup.cs file in your Web API project) and the application URL.<\/p>\n<p>About the latter, I\u2019ll tell you a secret: that value is truly needed only if you are writing a Web application, which is one of the possible uses of the wizard we are going through. In that case, the URL is used to know to where the token representing successful authentication should be sent to. In the case of a Web API, however, the return URL will be handled by the client; hence here you can put whatever valid URL you like and that won\u2019t have impact on the process. It is usually a good idea to put the correct URL anyway, given that you never know how you\u2019ll want to evolve this API in the future (perhaps you\u2019ll want to add a web UX!) but in this case I am not doing it for not adding steps to the walkthrough.<\/p>\n<p>Use the right arrow to move to the next screen.<\/p>\n<p><a href=\"https:\/\/www.cloudidentity.com\/blog\/wp-content\/uploads\/2013\/07\/image6.png\"><img loading=\"lazy\" decoding=\"async\" style=\"background-image: none; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-width: 0px;\" title=\"image\" alt=\"image\" src=\"https:\/\/www.cloudidentity.com\/blog\/wp-content\/uploads\/2013\/07\/image_thumb6.png\" width=\"640\" height=\"448\" border=\"0\" \/><\/a><\/p>\n<p>Here you can choose to grant extra powers to your Web API: if as part of the function being performed you need it to access the tenant\u2019s Graph API, here you can ensure that the app entry representing your Web API will have the necessary privileges. Here we just want a token back, hence you can stick with the default and click the checkmark button on the lower right.<\/p>\n<p><a href=\"https:\/\/www.cloudidentity.com\/blog\/wp-content\/uploads\/2013\/07\/image7.png\"><img loading=\"lazy\" decoding=\"async\" style=\"background-image: none; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-width: 0px;\" title=\"image\" alt=\"image\" src=\"https:\/\/www.cloudidentity.com\/blog\/wp-content\/uploads\/2013\/07\/image_thumb7.png\" width=\"640\" height=\"337\" border=\"0\" \/><\/a><\/p>\n<p>It is done! Your Web API is now listed among the apps of your Windows Azure AD tenant.<\/p>\n<h3>Setting Up a Test Client Project in the Portal and in Visual Studio<\/h3>\n<p>To exercise our Web API we need a client capable of obtaining a token from Windows Azure AD; in turn, Windows Azure AD requires such client to be registered and explicitly tied to the Web API before issuing tokens for it.<\/p>\n<p>Since we are already in the portal, let\u2019s go ahead and register our client right away: we\u2019ll create a Visual Studio project for it right after.<\/p>\n<p>Click on the big back arrow on the top left to get back to the applications list; once again, click on Add.<\/p>\n<p><a href=\"https:\/\/www.cloudidentity.com\/blog\/wp-content\/uploads\/2013\/07\/image8.png\"><img loading=\"lazy\" decoding=\"async\" style=\"background-image: none; padding-top: 0px; padding-left: 0px; margin: 0px; display: inline; padding-right: 0px; border-width: 0px;\" title=\"image\" alt=\"image\" src=\"https:\/\/www.cloudidentity.com\/blog\/wp-content\/uploads\/2013\/07\/image_thumb8.png\" width=\"640\" height=\"444\" border=\"0\" \/><\/a><\/p>\n<p>This time, you\u2019ll want to select \u201cnative client application\u201d as the application type. Move to the next screen.<\/p>\n<p><a href=\"https:\/\/www.cloudidentity.com\/blog\/wp-content\/uploads\/2013\/07\/image9.png\"><img loading=\"lazy\" decoding=\"async\" style=\"background-image: none; padding-top: 0px; padding-left: 0px; margin: 0px; display: inline; padding-right: 0px; border-width: 0px;\" title=\"image\" alt=\"image\" src=\"https:\/\/www.cloudidentity.com\/blog\/wp-content\/uploads\/2013\/07\/image_thumb9.png\" width=\"640\" height=\"436\" border=\"0\" \/><\/a><\/p>\n<p>Here the wizard just asks you what URI should be used in the OAuth2 code grant flow for returning the code to the client application. If that sounds Klingon to you, don\u2019t worry: we\u2019ll postpone the detailed discussion of what it means to another day. Just think of this as a value that you\u2019ll need to enter in your client that will be used at token acquisition time. Click on the checkmark button to finalize.<\/p>\n<p><a href=\"https:\/\/www.cloudidentity.com\/blog\/wp-content\/uploads\/2013\/07\/image10.png\"><img loading=\"lazy\" decoding=\"async\" style=\"background-image: none; padding-top: 0px; padding-left: 0px; margin: 0px; display: inline; padding-right: 0px; border-width: 0px;\" title=\"image\" alt=\"image\" src=\"https:\/\/www.cloudidentity.com\/blog\/wp-content\/uploads\/2013\/07\/image_thumb10.png\" width=\"640\" height=\"344\" border=\"0\" \/><\/a><\/p>\n<p>Excellent! Now Windows Azure AD has an entry for our client. We have two things left to do on the portal: ensure that this client is enabled to call our Web API, and gather the client coordinates we need to plug in our client project for obtaining access tokens. Let\u2019s start with fixing things up between our client and our perspective service. Click on the \u201cConfigure Access to Web APIs\u201d link in the Get Started section of the screen above, and select \u201cconfigure it now\u201d. You\u2019ll end up on the following screen:<\/p>\n<p><a href=\"https:\/\/www.cloudidentity.com\/blog\/wp-content\/uploads\/2013\/07\/image11.png\"><img loading=\"lazy\" decoding=\"async\" style=\"background-image: none; padding-top: 0px; padding-left: 0px; margin: 0px; display: inline; padding-right: 0px; border-width: 0px;\" title=\"image\" alt=\"image\" src=\"https:\/\/www.cloudidentity.com\/blog\/wp-content\/uploads\/2013\/07\/image_thumb11.png\" width=\"483\" height=\"480\" border=\"0\" \/><\/a><\/p>\n<p>Select your Web API (mine is \u201c\u201dKatanaWAAD_WebAPISample\u201d) from the dropdown at the bottom of the page and hit Save from the command bar. Your client is now in the list of clients that can call your Web API.<\/p>\n<p>Don\u2019t close the browser, we\u2019ll need some of the stuff on this page, and go back to Visual Studio.<\/p>\n<p>In the Solution Explorer, right click on the solution and click Add-&gt;New Project. Here I am going to create a blank Windows Store application, but you can definitely create any type of app you like (classic desktop apps are <a href=\"https:\/\/www.cloudidentity.com\/blog\/2012\/11\/20\/a-refresh-of-the-windows-azure-authentication-library-developer-preview-2\/\">super easy to handle via AAL .NET<\/a>, but even without libraries <a href=\"https:\/\/www.cloudidentity.com\/blog\/2013\/04\/29\/fun-with-windows-azure-ad-calling-rest-services-from-a-windows-phone-8-app\/\">WP8 apps aren\u2019t too hard either<\/a>).<\/p>\n<p><a href=\"https:\/\/www.cloudidentity.com\/blog\/wp-content\/uploads\/2013\/07\/image12.png\"><img loading=\"lazy\" decoding=\"async\" style=\"background-image: none; padding-top: 0px; padding-left: 0px; margin: 0px; display: inline; padding-right: 0px; border-width: 0px;\" title=\"image\" alt=\"image\" src=\"https:\/\/www.cloudidentity.com\/blog\/wp-content\/uploads\/2013\/07\/image_thumb12.png\" width=\"640\" height=\"440\" border=\"0\" \/><\/a><\/p>\n<p>We aren\u2019t going to do anything fancy here, we just want to see the various moving parts move. Head to MainPage.xaml, and add a button as shown below.<\/p>\n<p><a href=\"https:\/\/www.cloudidentity.com\/blog\/wp-content\/uploads\/2013\/07\/image13.png\"><img loading=\"lazy\" decoding=\"async\" style=\"background-image: none; padding-top: 0px; padding-left: 0px; margin: 0px; display: inline; padding-right: 0px; border-width: 0px;\" title=\"image\" alt=\"image\" src=\"https:\/\/www.cloudidentity.com\/blog\/wp-content\/uploads\/2013\/07\/image_thumb13.png\" width=\"640\" height=\"61\" border=\"0\" \/><\/a><\/p>\n<p>If you first name the button and then type the Click attribute, you\u2019ll have the chance of having Visual Studio generate the event handler declaration for you. That\u2019s what I did, VS generated myButton_Click for me.<\/p>\n<p>That done, I added a reference to the AAL for Windows Store package:<\/p>\n<p><a href=\"https:\/\/www.cloudidentity.com\/blog\/wp-content\/uploads\/2013\/07\/image14.png\"><img loading=\"lazy\" decoding=\"async\" style=\"background-image: none; padding-top: 0px; padding-left: 0px; margin: 0px; display: inline; padding-right: 0px; border-width: 0px;\" title=\"image\" alt=\"image\" src=\"https:\/\/www.cloudidentity.com\/blog\/wp-content\/uploads\/2013\/07\/image_thumb14.png\" width=\"640\" height=\"425\" border=\"0\" \/><\/a><\/p>\n<p>That done, all that\u2019s left is to wire up the event with the code to 1) acquire the access token for the service and 2) use it to invoke the Web API. That\u2019s largely boilerplate code, where you plug in the parameters specific to your scenario. Below you can find MainPage.xaml.cs in its entirety, so that you can see the usings directives as well.<\/p>\n<div class=\"csharpcode\">\n<pre><span class=\"lnum\">   1:  <\/span><span class=\"kwrd\">using<\/span> Microsoft.Preview.WindowsAzure.ActiveDirectory.Authentication;<\/pre>\n<pre><span class=\"lnum\">   2:  <\/span><span class=\"kwrd\">using<\/span> System;<\/pre>\n<pre><span class=\"lnum\">   3:  <\/span><span class=\"kwrd\">using<\/span> System.Net.Http;<\/pre>\n<pre><span class=\"lnum\">   4:  <\/span><span class=\"kwrd\">using<\/span> System.Net.Http.Headers;<\/pre>\n<pre><span class=\"lnum\">   5:  <\/span><span class=\"kwrd\">using<\/span> Windows.UI.Popups;<\/pre>\n<pre><span class=\"lnum\">   6:  <\/span><span class=\"kwrd\">using<\/span> Windows.UI.Xaml;<\/pre>\n<pre><span class=\"lnum\">   7:  <\/span><span class=\"kwrd\">using<\/span> Windows.UI.Xaml.Controls;<\/pre>\n<pre><span class=\"lnum\">   8:  <\/span><span class=\"kwrd\">using<\/span> Windows.UI.Xaml.Navigation;<\/pre>\n<pre><span class=\"lnum\">   9:  <\/span><\/pre>\n<pre><span class=\"lnum\">  10:  <\/span><span class=\"kwrd\">namespace<\/span> KatanaWaad_W8ClientSample<\/pre>\n<pre><span class=\"lnum\">  11:  <\/span>{<\/pre>\n<pre><span class=\"lnum\">  12:  <\/span>    <span class=\"kwrd\">public<\/span> <span class=\"kwrd\">sealed<\/span> <span class=\"kwrd\">partial<\/span> <span class=\"kwrd\">class<\/span> MainPage : Page<\/pre>\n<pre><span class=\"lnum\">  13:  <\/span>    {<\/pre>\n<pre><span class=\"lnum\">  14:  <\/span>        <span class=\"kwrd\">public<\/span> MainPage()<\/pre>\n<pre><span class=\"lnum\">  15:  <\/span>        {<\/pre>\n<pre><span class=\"lnum\">  16:  <\/span>            <span class=\"kwrd\">this<\/span>.InitializeComponent();<\/pre>\n<pre><span class=\"lnum\">  17:  <\/span>        }<\/pre>\n<pre><span class=\"lnum\">  18:  <\/span><\/pre>\n<pre><span class=\"lnum\">  19:  <\/span>        <span class=\"kwrd\">private<\/span> async <span class=\"kwrd\">void<\/span> myButton_Click(<span class=\"kwrd\">object<\/span> sender, RoutedEventArgs e)<\/pre>\n<pre><span class=\"lnum\">  20:  <\/span>        {<\/pre>\n<pre><span class=\"lnum\">  21:  <\/span>            AuthenticationContext authenticationContext =<\/pre>\n<pre><span class=\"lnum\">  22:  <\/span>                <span class=\"kwrd\">new<\/span> AuthenticationContext(<span class=\"str\">\"https:\/\/login.windows.net\/cloudidentity.net\"<\/span>);<\/pre>\n<pre><span class=\"lnum\">  23:  <\/span>            AuthenticationResult _authResult =<\/pre>\n<pre><span class=\"lnum\">  24:  <\/span>                await authenticationContext.AcquireTokenAsync(<\/pre>\n<pre><span class=\"lnum\">  25:  <\/span>                <span class=\"str\">\"https:\/\/cloudidentity.net\/API\/KatanaWAAD_WebAPISample\"<\/span>,<\/pre>\n<pre><span class=\"lnum\">  26:  <\/span>                <span class=\"str\">\"3fb2a37f-4ced-409c-937c-dddd776f4dfd\"<\/span>,<\/pre>\n<pre><span class=\"lnum\">  27:  <\/span>                <span class=\"str\">\"http:\/\/whatever\"<\/span>,<\/pre>\n<pre><span class=\"lnum\">  28:  <\/span>                <span class=\"str\">\"vibro@cloudidentity.net\"<\/span>, <span class=\"str\">\"\"<\/span>);<\/pre>\n<pre><span class=\"lnum\">  29:  <\/span><\/pre>\n<pre><span class=\"lnum\">  30:  <\/span>            <span class=\"kwrd\">string<\/span> result = <span class=\"kwrd\">string<\/span>.Empty;<\/pre>\n<pre><span class=\"lnum\">  31:  <\/span>            HttpClient httpClient = <span class=\"kwrd\">new<\/span> HttpClient();<\/pre>\n<pre><span class=\"lnum\">  32:  <\/span>            httpClient.DefaultRequestHeaders.Authorization =<\/pre>\n<pre><span class=\"lnum\">  33:  <\/span>                <span class=\"kwrd\">new<\/span> AuthenticationHeaderValue(<span class=\"str\">\"Bearer\"<\/span>, _authResult.AccessToken);<\/pre>\n<pre><span class=\"lnum\">  34:  <\/span>            HttpResponseMessage response =<\/pre>\n<pre><span class=\"lnum\">  35:  <\/span>                await httpClient.GetAsync(<span class=\"str\">\"http:\/\/localhost:16159\/Api\/Values\"<\/span>);<\/pre>\n<pre><span class=\"lnum\">  36:  <\/span><\/pre>\n<pre><span class=\"lnum\">  37:  <\/span>            <span class=\"kwrd\">if<\/span> (response.IsSuccessStatusCode)<\/pre>\n<pre><span class=\"lnum\">  38:  <\/span>            {<\/pre>\n<pre><span class=\"lnum\">  39:  <\/span>                result = await response.Content.ReadAsStringAsync();<\/pre>\n<pre><span class=\"lnum\">  40:  <\/span><\/pre>\n<pre><span class=\"lnum\">  41:  <\/span>            }<\/pre>\n<pre><span class=\"lnum\">  42:  <\/span>            MessageDialog md = <span class=\"kwrd\">new<\/span> MessageDialog(result);<\/pre>\n<pre><span class=\"lnum\">  43:  <\/span>            IUICommand x = await md.ShowAsync();<\/pre>\n<pre><span class=\"lnum\">  44:  <\/span>        }<\/pre>\n<pre><span class=\"lnum\">  45:  <\/span>    }<\/pre>\n<pre><span class=\"lnum\">  46:  <\/span>}<\/pre>\n<\/div>\n<style type=\"text\/css\"><!--\n.csharpcode, .csharpcode pre\n{\n\tfont-size: small;\n\tcolor: black;\n\tfont-family: consolas, \"Courier New\", courier, monospace;\n\tbackground-color: #ffffff;\n\t\/*white-space: pre;*\/\n}\n.csharpcode pre { margin: 0em; }\n.csharpcode .rem { color: #008000; }\n.csharpcode .kwrd { color: #0000ff; }\n.csharpcode .str { color: #006080; }\n.csharpcode .op { color: #0000c0; }\n.csharpcode .preproc { color: #cc6633; }\n.csharpcode .asp { background-color: #ffff00; }\n.csharpcode .html { color: #800000; }\n.csharpcode .attr { color: #ff0000; }\n.csharpcode .alt \n{\n\tbackground-color: #f4f4f4;\n\twidth: 100%;\n\tmargin: 0em;\n}\n.csharpcode .lnum { color: #606060; }\n--><\/style>\n<style type=\"text\/css\"><!--\n.csharpcode, .csharpcode pre\n{\n\tfont-size: small;\n\tcolor: black;\n\tfont-family: consolas, \"Courier New\", courier, monospace;\n\tbackground-color: #ffffff;\n\t\/*white-space: pre;*\/\n}\n.csharpcode pre { margin: 0em; }\n.csharpcode .rem { color: #008000; }\n.csharpcode .kwrd { color: #0000ff; }\n.csharpcode .str { color: #006080; }\n.csharpcode .op { color: #0000c0; }\n.csharpcode .preproc { color: #cc6633; }\n.csharpcode .asp { background-color: #ffff00; }\n.csharpcode .html { color: #800000; }\n.csharpcode .attr { color: #ff0000; }\n.csharpcode .alt \n{\n\tbackground-color: #f4f4f4;\n\twidth: 100%;\n\tmargin: 0em;\n}\n.csharpcode .lnum { color: #606060; }\n--><\/style>\n<p>Here there are few notes on the salient lines. Please refer to the <a href=\"https:\/\/www.cloudidentity.com\/blog\/2013\/04\/22\/windows-azure-authentication-library-aal-for-windows-store-a-deep-dive\/\">AAL content<\/a> for more in depth info of what\u2019s going on in here.<\/p>\n<p>Line 21: here you create the AuthenticationContext pointing to your Windows Azure AD tenant of choice.<\/p>\n<p>Lines 23-28: the call to AcquireTokenAsync specifies the resource you want a token for (you chose this identifier at Web API project development time and used in when registering the API with AD), the client ID of your application and associated return URI (as copied from the client properties page you should still have open in the browser), and some extra parameters (here I provide the user I want to be pre-populated in the authentication dialog, so that I\u2019ll have less typing to do <img decoding=\"async\" class=\"wlEmoticon wlEmoticon-smile\" alt=\"Smile\" src=\"https:\/\/www.cloudidentity.com\/blog\/wp-content\/uploads\/2013\/07\/wlEmoticon-smile.png\" \/>)<\/p>\n<p>Lines 32-33 add the resulting access token in the Authorization header, as expected when using OAuth2 for accessing a resource<\/p>\n<p>Lines 35-36 perform the actual call: you might notice I am calling on HTTP, that\u2019s <em>really<\/em> bad of me as a bearer token should always be used on a protected channel. I am skipping it just for keeping the walkthrough short.<\/p>\n<p>The rest of the code just reads the response and displays it on a dialog.<\/p>\n<h3>Testing the Solution<\/h3>\n<p>Finally ready to rock &amp; roll! Put a breakpoint on Configuration in Startup.cs and hit F5.<\/p>\n<p>Did the debugger break there? Excellent. That means that the Owin pipeline is correctly registered and is operating as expected. F10 your way to the end of Configuration, then open the Immediate window to take a look at the effects of the call to UseWindowsAzureBearerToken.<\/p>\n<p>Let\u2019s start by examining the list of HttpModules: type <strong>HttpContext.Current.ApplicationInstance.Modules.AllKeys<\/strong>.<\/p>\n<p><a href=\"https:\/\/www.cloudidentity.com\/blog\/wp-content\/uploads\/2013\/07\/image15.png\"><img loading=\"lazy\" decoding=\"async\" style=\"background-image: none; padding-top: 0px; padding-left: 0px; margin: 0px; display: inline; padding-right: 0px; border: 0px;\" title=\"image\" alt=\"image\" src=\"https:\/\/www.cloudidentity.com\/blog\/wp-content\/uploads\/2013\/07\/image_thumb15.png\" width=\"640\" height=\"313\" border=\"0\" \/><\/a><\/p>\n<p>As you can see in [14], the OwinHttpModule has been successfully added to the list. Very good.<br \/>\nWhat about the OWIN pipeline itself? Well, that\u2019s a bit more complicated; but if you feel adventurous, you can use the Locals window to examine the non-public members of <strong>app<\/strong> (the parameter of Configure) and there you\u2019l find a _middleware property, which does show that the OAuth2BearerTokenAuthenticationMiddleware is now in the collection.<br \/>\nEnough snooping <img decoding=\"async\" class=\"wlEmoticon wlEmoticon-smile\" alt=\"Smile\" src=\"https:\/\/www.cloudidentity.com\/blog\/wp-content\/uploads\/2013\/07\/wlEmoticon-smile.png\" \/> hit F5 to let the Web API project fully start.<\/p>\n<p>Go back to Visual Studio, right click on the client project in the Solution Explorer and choose Debug-&gt;Run new instance. The minimal UI of our text client shows up:<\/p>\n<p><a href=\"https:\/\/www.cloudidentity.com\/blog\/wp-content\/uploads\/2013\/07\/image16.png\"><img loading=\"lazy\" decoding=\"async\" style=\"background-image: none; padding-top: 0px; padding-left: 0px; margin: 0px; display: inline; padding-right: 0px; border: 0px;\" title=\"image\" alt=\"image\" src=\"https:\/\/www.cloudidentity.com\/blog\/wp-content\/uploads\/2013\/07\/image_thumb16.png\" width=\"640\" height=\"359\" border=\"0\" \/><\/a><\/p>\n<p>Hit the button: as expected, you\u2019ll get the familiar WAB-based authentication experience.<\/p>\n<p><a href=\"https:\/\/www.cloudidentity.com\/blog\/wp-content\/uploads\/2013\/07\/image17.png\"><img loading=\"lazy\" decoding=\"async\" style=\"background-image: none; padding-top: 0px; padding-left: 0px; margin: 0px; display: inline; padding-right: 0px; border: 0px;\" title=\"image\" alt=\"image\" src=\"https:\/\/www.cloudidentity.com\/blog\/wp-content\/uploads\/2013\/07\/image_thumb17.png\" width=\"640\" height=\"360\" border=\"0\" \/><\/a><\/p>\n<p>Sign in with your test user.<\/p>\n<p><a href=\"https:\/\/www.cloudidentity.com\/blog\/wp-content\/uploads\/2013\/07\/image18.png\"><img loading=\"lazy\" decoding=\"async\" style=\"background-image: none; padding-top: 0px; padding-left: 0px; margin: 0px; display: inline; padding-right: 0px; border: 0px;\" title=\"image\" alt=\"image\" src=\"https:\/\/www.cloudidentity.com\/blog\/wp-content\/uploads\/2013\/07\/image_thumb18.png\" width=\"640\" height=\"358\" border=\"0\" \/><\/a><\/p>\n<p>As expected, you get back a jumbled array of values which proves that the Web API correctly processed the incoming token.<\/p>\n<h2>Wrap<\/h2>\n<p>Everything you have read about in this post is possible today: and although it is still in preview, it should give you a pretty good idea of what the experience at release time is going to be. Given how much simpler everything is, if you plan to secure Web API with organizational accounts I would recommend you start experimenting with this ASAP.<\/p>\n<p>What\u2019s next? For starters, more flexible middleware. Barry is working on middleware that will work with ADFS vNext, and on middleware that will dispense with all of the metadata automation and allow you to specify every parameter manually (for those custom cases where you need more fine grained control).\u00a0 Then, expect the steps described in this post (at least the ones about the service) to be automated by ASP.NET VS2013 templates at some point in the future, similarly to what you have seen for Web UX template types. It\u2019s an exciting time for developing business API <img decoding=\"async\" class=\"wlEmoticon wlEmoticon-smile\" alt=\"Smile\" src=\"https:\/\/www.cloudidentity.com\/blog\/wp-content\/uploads\/2013\/07\/wlEmoticon-smile.png\" \/> stay tuned!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>During the Active Directory \/\/BUILD\/ 2013 talk I briefly touched on how the\u00a0 Web API in my sample scenarios were secured using the new OWIN middleware offered by the ASP.NET\u2019s Katana project, as opposed to the custom code we describe in our current native app+Web API walkthrough. I had a lot of ground&#8230;<\/p>\n","protected":false},"author":1,"featured_media":2265,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_kad_post_transparent":"","_kad_post_title":"","_kad_post_layout":"","_kad_post_sidebar_id":"","_kad_post_content_style":"","_kad_post_vertical_padding":"","_kad_post_feature":"","_kad_post_feature_position":"","_kad_post_header":false,"_kad_post_footer":false,"footnotes":""},"categories":[1],"tags":[],"class_list":["post-2280","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-uncategorized"],"_links":{"self":[{"href":"https:\/\/www.cloudidentity.com\/blog\/wp-json\/wp\/v2\/posts\/2280","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.cloudidentity.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.cloudidentity.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.cloudidentity.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.cloudidentity.com\/blog\/wp-json\/wp\/v2\/comments?post=2280"}],"version-history":[{"count":4,"href":"https:\/\/www.cloudidentity.com\/blog\/wp-json\/wp\/v2\/posts\/2280\/revisions"}],"predecessor-version":[{"id":3735,"href":"https:\/\/www.cloudidentity.com\/blog\/wp-json\/wp\/v2\/posts\/2280\/revisions\/3735"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.cloudidentity.com\/blog\/wp-json\/wp\/v2\/media\/2265"}],"wp:attachment":[{"href":"https:\/\/www.cloudidentity.com\/blog\/wp-json\/wp\/v2\/media?parent=2280"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.cloudidentity.com\/blog\/wp-json\/wp\/v2\/categories?post=2280"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.cloudidentity.com\/blog\/wp-json\/wp\/v2\/tags?post=2280"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}