{"id":253,"date":"2013-02-18T01:04:00","date_gmt":"2013-02-18T10:04:00","guid":{"rendered":"http:\/\/www.cloudidentity.com\/blog\/2013\/02\/18\/use-the-jwt-handler-to-write-a-%ce%bc-authorization-server-in-3-lines-of-code-see-it-in-action-with-a-windows-store-app-client-web-api-pr-4\/"},"modified":"2013-03-14T15:45:04","modified_gmt":"2013-03-15T00:45:04","slug":"use-the-jwt-handler-to-write-a-authorization-server-in-3-lines-of-code-see-it-in-action-with-a-windows-store-app-client-amp-web-api-pr","status":"publish","type":"post","link":"https:\/\/www.cloudidentity.com\/blog\/2013\/02\/18\/use-the-jwt-handler-to-write-a-authorization-server-in-3-lines-of-code-see-it-in-action-with-a-windows-store-app-client-amp-web-api-pr\/","title":{"rendered":"Use the JWT handler to write a \u03bc- Authorization Server in ~3 lines of code \u2013 see it in action with a Windows Store app client &amp; Web API PR"},"content":{"rendered":"<p>[if there was ever a post where you NEED to understand my post disclaimers, this is it. This is my PERSONAL blog, what I write here are MY OWN personal elucubrations, largely written on nights and weekends instead of engaging in healthy activities, and is by no mean official guidance. Please refer to MSDN and to the official team blogs for those.]<\/p>\n<p>[In short: I will show you how to cobble together an MVC app which behaves like an micro Authorization Server, receives tokens from ACS\/Winodws Azure AD and uses the JWT handler to issue access tokens using the OAuth2 implicit profile. I will also show how to use that micro AS to authenticate users of a simple Windows Store app, and invoke a Web API (also using the JWT handler, this time for validating incoming tokens).]<\/p>\n<p>Last Friday I was walking with my good friend <a href=\"http:\/\/channel9.msdn.com\/events\/speakers\/daniel-roth\">Daniel Roth<\/a> to a meeting in a nearby building .     <br \/>Dan looks after Web API: as you can imagine, we\u2019ve been discussing Web API security often in the last few months.&#160; The latest subject was custom Authorization Servers: he mentioned that some of his customers really want to be able to control in fine details what resources can be accessed, what kind of permissions are possible, and similar considerations. Basically, he wanted to build a custom AS.     <br \/>My classic knee-jerk reaction was the same I have when talking about development of a custom STS: \u201cyou are better off using a packaged product or a hosted service\u201d. An AS, like an STS, is on the critical path of pretty much everything you do; it has to be available, manageable, secure, performing\u2026 and those are features that are expensive to obtain: whomever built the packaged product\/service already paid those prices, why should you re-do it, and so on. If you read this blog in the last few years, you already know that song.<\/p>\n<p>However, just like for the custom STS cases, there are indeed situations where the custom route \u2013 albeit steep \u2013 is the only one that offers the level of control required.    <br \/>That made me think of some examples. For a GIS service the resources could be maps of a region, information layers (such as points of interests, yearly temperature data, median income of the population), routes and similar; the permissions could be very specific, such as the ability of reading the artifacts referring to one area but not another; or to see all the maps for all regions, but no access to PII-rich data layers. That would indeed require an AS which is awfully close to the resources themselves, knows everything about the resource types and is aware of all the possible operations to authorize or prevent. <\/p>\n<p>That convinced me that trying to write an AS, even if very simple, would be a worthwhile experimentation. I knew that my wife was going to work this Sunday and that I would have had time on my hands, hence I promised Dan I would put something together. Well, here we are \ud83d\ude42 <\/p>\n<p>Here there\u2019s the plan:<\/p>\n<ul>\n<li>I\u2019ll put together a simple Windows Store app, consuming an (even simpler) Web API without any authentication. <\/li>\n<li>I\u2019&#8217;ll write a MVC4 application, adding in a controller the MINIMAL logic for processing OAuth2 token requests and generating responses, according to the implicit profile. I\u2019ll secure the app using the identity and access tools and ACS, which will allow us to use Facebook and Windows Azure AD users. Finally, I\u2019ll deploy the AS to Windows Azure Web Sites.<\/li>\n<li>I\u2019ll modify the Windows Store app client to obtain a token from the AS and use it to secure calls to the Web API service; <\/li>\n<li>I\u2019ll also modify the Web API to validate incoming tokens <\/li>\n<\/ul>\n<p>You\u2019ll see that the code is surprisingly simple, but don\u2019t get fooled into thinking that any of this can go \u2018as is\u2019 anywhere near to production! Just like for custom STSes, it\u2019s easy to put together something that goes through the protocol motions; but before even considering moving it further, there is an enormous amount of critical aspects to be addressed. As usual, please read all this with a humongous grain of salt. Think <a href=\"http:\/\/upload.wikimedia.org\/wikipedia\/en\/4\/46\/Design_fortress1.jpg\">Superman\u2019s Fortress of Solitude<\/a>-class.<\/p>\n<h1>Sample client and Web API\u2019s Protected Resource<\/h1>\n<p>Alrighty, let\u2019s get our hands dirty! \ud83d\ude42 I won\u2019t give you exact step by step instructions or the Sunday won&#8217;t be enough to write the post, but this should be detailed enough for you to follow if you are familiar with Visual Studio.<\/p>\n<p>Let\u2019s start with the service side. I want to create a simple inspirational quotes service. Here I will just support the classic IEnumerable GET of all the resources, but you can happily add editing capabilities later and implement the matching HTTP verbs afterwards.    <br \/>Create a new Web Application project, choose MVC 4 Web App, and pick the Web API template. I called my project MyProtectedResource.     <br \/>Add a new controller for serving the quotes. Here there\u2019s the code of the one I wrote:<\/p>\n<pre class=\"csharpcode\"><span class=\"kwrd\">using<\/span> System.Collections.Generic;\n<span class=\"kwrd\">using<\/span> System.Web.Http;\n\n<span class=\"kwrd\">namespace<\/span> MyProtectedResource.Controllers\n{\n    <span class=\"kwrd\">public<\/span> <span class=\"kwrd\">class<\/span> InspiringQuotesController : ApiController\n    {\n        <span class=\"rem\">\/\/<\/span>\n        <span class=\"rem\">\/\/ GET: \/InspiringQuotes\/<\/span>\n\n        <span class=\"kwrd\">private<\/span> <span class=\"kwrd\">static<\/span> <span class=\"kwrd\">readonly<\/span> List&lt;<span class=\"kwrd\">string<\/span>&gt; Quotes = <span class=\"kwrd\">new<\/span> List&lt;<span class=\"kwrd\">string<\/span>&gt;\n        {\n            <span class=\"str\">&quot;&quot;data is not information&quot;&quot;<\/span>,\n            <span class=\"str\">&quot;&quot;correlation is not causation&quot;&quot;<\/span>,\n            <span class=\"str\">&quot;&quot;Something, something, something, dark side. Something, something, something, complete&quot;&quot;<\/span>,\n        };\n\n        \n        <span class=\"kwrd\">public<\/span> IEnumerable&lt;<span class=\"kwrd\">string<\/span>&gt; Get()\n        {\n            <span class=\"kwrd\">return<\/span> Quotes;\n        }\n    }\n}<\/pre>\n<p>As straightforward as it gets. Let\u2019s move to the client.<\/p>\n<p>Add a new project to the solution: choose the Windows Store category, and create an empty application.<\/p>\n<p>Here I want to show a pretty Spartan UX: a title, a list of quotes (I\u2019ll data-bind) and a button to retrieve them. I could retrieve them at startup time, but I want the button to show you few interesting things about how authentication in Windows Store apps works later in the post. Here there\u2019s the XAML:<\/p>\n<pre class=\"csharpcode\"><span class=\"kwrd\">&lt;<\/span><span class=\"html\">Page<\/span>\n    <span class=\"attr\">x:Class<\/span><span class=\"kwrd\">=&quot;App1.MainPage&quot;<\/span>\n    <span class=\"attr\">xmlns<\/span><span class=\"kwrd\">=&quot;http:\/\/schemas.microsoft.com\/winfx\/2006\/xaml\/presentation&quot;<\/span>\n    <span class=\"attr\">xmlns:x<\/span><span class=\"kwrd\">=&quot;http:\/\/schemas.microsoft.com\/winfx\/2006\/xaml&quot;<\/span>\n    <span class=\"attr\">xmlns:local<\/span><span class=\"kwrd\">=&quot;using:App1&quot;<\/span>\n    <span class=\"attr\">xmlns:d<\/span><span class=\"kwrd\">=&quot;http:\/\/schemas.microsoft.com\/expression\/blend\/2008&quot;<\/span>\n    <span class=\"attr\">xmlns:mc<\/span><span class=\"kwrd\">=&quot;http:\/\/schemas.openxmlformats.org\/markup-compatibility\/2006&quot;<\/span>\n    <span class=\"attr\">mc:Ignorable<\/span><span class=\"kwrd\">=&quot;d&quot;<\/span><span class=\"kwrd\">&gt;<\/span>\n\n<span class=\"kwrd\">&lt;<\/span><span class=\"html\">Grid<\/span> <span class=\"attr\">Background<\/span><span class=\"kwrd\">=&quot;{StaticResource ApplicationPageBackgroundThemeBrush}&quot;<\/span><span class=\"kwrd\">&gt;<\/span>\n        \n<span class=\"kwrd\">&lt;<\/span><span class=\"html\">StackPanel<\/span> <span class=\"attr\">Orientation<\/span><span class=\"kwrd\">=&quot;Vertical&quot;<\/span><span class=\"kwrd\">&gt;<\/span>\n  <span class=\"kwrd\">&lt;<\/span><span class=\"html\">TextBlock<\/span> <span class=\"attr\">Text<\/span><span class=\"kwrd\">=&quot;Inspiring Quotes&quot;<\/span> \n            <span class=\"attr\">Margin<\/span><span class=\"kwrd\">=&quot;50,50,0,50&quot;<\/span> \n            <span class=\"attr\">Style<\/span><span class=\"kwrd\">=&quot;{StaticResource PageHeaderTextStyle}&quot;<\/span> <span class=\"kwrd\">\/&gt;<\/span>\n  <span class=\"kwrd\">&lt;<\/span><span class=\"html\">Button<\/span> <span class=\"attr\">Click<\/span><span class=\"kwrd\">=&quot;Button_Click_1&quot;<\/span> <span class=\"attr\">Margin<\/span><span class=\"kwrd\">=&quot;50,0,0,50&quot;<\/span><span class=\"kwrd\">&gt;<\/span>get quotes...<span class=\"kwrd\">&lt;\/<\/span><span class=\"html\">Button<\/span><span class=\"kwrd\">&gt;<\/span>\n  <span class=\"kwrd\">&lt;<\/span><span class=\"html\">ListView<\/span> <span class=\"attr\">x:Name<\/span><span class=\"kwrd\">=&quot;quotesListView&quot;<\/span><span class=\"kwrd\">&gt;<\/span>\n    <span class=\"kwrd\">&lt;<\/span><span class=\"html\">ListView.ItemTemplate<\/span><span class=\"kwrd\">&gt;<\/span>\n       <span class=\"kwrd\">&lt;<\/span><span class=\"html\">DataTemplate<\/span><span class=\"kwrd\">&gt;<\/span>\n         <span class=\"kwrd\">&lt;<\/span><span class=\"html\">Grid<\/span><span class=\"kwrd\">&gt;<\/span>\n           <span class=\"kwrd\">&lt;<\/span><span class=\"html\">Border<\/span><span class=\"kwrd\">&gt;<\/span>\n             <span class=\"kwrd\">&lt;<\/span><span class=\"html\">TextBlock<\/span> <span class=\"attr\">Text<\/span><span class=\"kwrd\">=&quot;{Binding}&quot;<\/span> \n                <span class=\"attr\">FontSize<\/span><span class=\"kwrd\">=&quot;18&quot;<\/span> <span class=\"attr\">FontFamily<\/span><span class=\"kwrd\">=&quot;Lucida Handwriting&quot;<\/span> <span class=\"attr\">Margin<\/span><span class=\"kwrd\">=&quot;50,50,0,50&quot;<\/span><span class=\"kwrd\">\/&gt;<\/span>\n            <span class=\"kwrd\">&lt;\/<\/span><span class=\"html\">Border<\/span><span class=\"kwrd\">&gt;<\/span>\n         <span class=\"kwrd\">&lt;\/<\/span><span class=\"html\">Grid<\/span><span class=\"kwrd\">&gt;<\/span>\n       <span class=\"kwrd\">&lt;\/<\/span><span class=\"html\">DataTemplate<\/span><span class=\"kwrd\">&gt;<\/span>\n     <span class=\"kwrd\">&lt;\/<\/span><span class=\"html\">ListView.ItemTemplate<\/span><span class=\"kwrd\">&gt;<\/span>\n  <span class=\"kwrd\">&lt;\/<\/span><span class=\"html\">ListView<\/span><span class=\"kwrd\">&gt;<\/span>\n<span class=\"kwrd\">&lt;\/<\/span><span class=\"html\">StackPanel<\/span><span class=\"kwrd\">&gt;<\/span>\n<span class=\"kwrd\">&lt;\/<\/span><span class=\"html\">Grid<\/span><span class=\"kwrd\">&gt;<\/span>\n<span class=\"kwrd\">&lt;\/<\/span><span class=\"html\">Page<\/span><span class=\"kwrd\">&gt;<\/span>\n<\/pre>\n<p>Yes, my XAML skills are pretty primitive \ud83d\ude42 but this will do.<\/p>\n<p>As you can see, the button is already wired up with one click event (i didn\u2019t even bother to rename the one that VS generated for me when I double clicked on the button in the designer). Let\u2019s take a look at its code.<\/p>\n<div class=\"csharpcode\">\n<pre><span class=\"lnum\">   1:  <\/span><span class=\"kwrd\">private<\/span> async <span class=\"kwrd\">void<\/span> InitializeQuotes()<\/pre>\n<pre><span class=\"lnum\">   2:  <\/span>{<\/pre>\n<pre><span class=\"lnum\">   3:  <\/span>  ObservableCollection&lt;<span class=\"kwrd\">string<\/span>&gt; quotesColl = <span class=\"kwrd\">null<\/span>;<\/pre>\n<pre><span class=\"lnum\">   4:  <\/span>&#160;<\/pre>\n<pre><span class=\"lnum\">   5:  <\/span>  <span class=\"kwrd\">using<\/span> (var http = <span class=\"kwrd\">new<\/span> HttpClient())<\/pre>\n<pre><span class=\"lnum\">   6:  <\/span>  {<\/pre>\n<pre><span class=\"lnum\">   7:  <\/span>     HttpResponseMessage response = <\/pre>\n<pre>              await http.GetAsync(<span class=\"kwrd\">new<\/span> Uri(<span class=\"str\">&quot;http:\/\/localhost:47524\/Api\/InspiringQuotes&quot;<\/span>));<\/pre>\n<pre><span class=\"lnum\">   8:  <\/span>     Stream rez = await response.Content.ReadAsStreamAsync();<\/pre>\n<pre><span class=\"lnum\">   9:  <\/span>     var deser = <span class=\"kwrd\">new<\/span> DataContractJsonSerializer(<span class=\"kwrd\">typeof<\/span>(List&lt;<span class=\"kwrd\">string<\/span>&gt;));<\/pre>\n<pre><span class=\"lnum\">  10:  <\/span>     quotesColl = <\/pre>\n<pre>              <span class=\"kwrd\">new<\/span> ObservableCollection&lt;<span class=\"kwrd\">string<\/span>&gt;((IEnumerable&lt;<span class=\"kwrd\">string<\/span>&gt;)deser.ReadObject(rez));<\/pre>\n<pre><span class=\"lnum\">  11:  <\/span>     quotesListView.ItemsSource = quotesColl;<\/pre>\n<pre><span class=\"lnum\">  12:  <\/span>  }<\/pre>\n<pre><span class=\"lnum\">  13:  <\/span>}<\/pre>\n<pre><span class=\"lnum\">  14:  <\/span>&#160;<\/pre>\n<pre><span class=\"lnum\">  15:  <\/span><span class=\"kwrd\">private<\/span> async <span class=\"kwrd\">void<\/span> Button_Click_1(<span class=\"kwrd\">object<\/span> sender, RoutedEventArgs e)<\/pre>\n<pre><span class=\"lnum\">  16:  <\/span>{<\/pre>\n<pre><span class=\"lnum\">  17:  <\/span>    InitializeQuotes();<\/pre>\n<pre><span class=\"lnum\">  18:  <\/span>}<\/pre>\n<\/div>\n<p>If you are familiar with Windows Store apps, that will be very straightforward; but in case you aren\u2019t<\/p>\n<ul>\n<li>Line 3: this collection will contain the list of quotes and be used as data source. I am using that type because that will allow you, if you choose to add editing capabilities, to propagate the changes back to the service using the WinRT environment\u2019s features. Feel free to ignore this last bit, it\u2019s irrelevant to this tutorial <\/li>\n<li>Line 5: creates an HttpClient for hitting the service with our request<\/li>\n<li>Line 7: hits the service with our request. The IIS express address is what I got from the property pages. I should have used HTTPS, of course.<\/li>\n<li>Lines 8 to 11: parses the response into our quotes collection. Note the complete absence of error management code, due to my slacking attitude during weekends<\/li>\n<li>Line 17: the actual call<\/li>\n<\/ul>\n<p>Simple, right? let\u2019s give it a spin. Go in the solution properties, make the solution multi-start, and pick both projects. Hit F5. <\/p>\n<p><a href=\"http:\/\/cloudidentity.com\/blog\/wp-content\/uploads\/2013\/02\/1256.image_5F00_3E29D8A6.png\"><img loading=\"lazy\" decoding=\"async\" title=\"image\" style=\"border: 0px currentcolor\" border=\"0\" alt=\"image\" src=\"http:\/\/cloudidentity.com\/blog\/wp-content\/uploads\/2013\/02\/1256.image_5F00_3E29D8A6.png\" width=\"550\" height=\"308\" \/><\/a> <\/p>\n<p>Hit \u201cget quotes\u201d\u2026<\/p>\n<p><a href=\"http:\/\/cloudidentity.com\/blog\/wp-content\/uploads\/2013\/02\/0412.image_5F00_0BC60527.png\"><img loading=\"lazy\" decoding=\"async\" title=\"image\" style=\"border: 0px currentcolor\" border=\"0\" alt=\"image\" src=\"http:\/\/cloudidentity.com\/blog\/wp-content\/uploads\/2013\/02\/0412.image_5F00_0BC60527.png\" width=\"550\" height=\"308\" \/><\/a> <\/p>\n<p>\u2026and like a fierce lighthouse piercing through the thick fog of confusion, three immortal quotes are revealed.<\/p>\n<p>Great! Now, let\u2019s say that we want to restrict access to this service to specific user populations. From all the JWT samples, we already know we can easily secure the Web API side. How to acquire a token from the Windows Store app, though? Windows provides nice API for that: but in order to use them, we need an Authorization Server.<\/p>\n<h1>A micro authorization server<\/h1>\n<p>Did you read the OAuth2 specification? I am totally serious, it is actually pretty readable! OAuth2 describes how a client can work with one entity called Authorization Server (from now on AS) to obtain delegated access to a protected resource. I won\u2019t go in the details of how that works here; rather, I\u2019ll discuss what I implemented and why. As usual, I\u2019ll do some pretty dramatic simplifications; also, per <a href=\"http:\/\/blogs.msdn.com\/b\/vbertocci\/archive\/2013\/01\/02\/oauth-2-0-and-sign-in.aspx\">what I wrote here<\/a> I won\u2019t even try to be \u201cinteroperable\u201d (<a href=\"http:\/\/blogs.msdn.com\/b\/vbertocci\/archive\/2013\/01\/02\/oauth-2-0-and-sign-in.aspx\">whatever that means in this context<\/a>).<\/p>\n<p>In a nutshell, the job of an AS is to <\/p>\n<ol>\n<li>establish the identity of the caller (to verify that he\/she actually is the resource owner)<\/li>\n<li>accept requests formed according to what the OAuth2 specs describe<\/li>\n<li>inform the caller about the permissions being asked, from which client and for what resources; ask for consent<\/li>\n<li>if the caller granted consent, return the kind of grant asked (code, token, etc etc) according to what the OAuth2 specs describe<\/li>\n<\/ol>\n<p>That\u2019s very similar to what you\u2019d do when implementing a passive STS: pretty much any web application will do. Good, I decided: I am going to use an MVC4 app for implementing the AS.<br \/>\n  <br \/>If you want to follow along, create a new MVC4 application in the solution: I called mine PoorMansAS. Any template will do: I picked the Intranet one simply because there\u2019s not too much stuff out of the box to clean up. <\/p>\n<p>Now, let\u2019s go through the various tasks listed above and see how to project those in our implementation.<\/p>\n<p>#1 is the step where people often gets confused. I believe this stems from the fact that this step entails securing the authorization endpoint with some kind of sign-in flow, which can (and often is) done with perfectly standard, traditional sign in methods: ASP.NET membership provider, OpenID provider, federation with ADFSv2, federation with an ACS namespace, Windows Azure AD\u2026 any method will work, as long as the AS can use its outcome to recognize the resource owner. The IdP used for sign-in can be in itself entirely oblivious about what will happen next (e.g. the actual OAuth bits).<br \/>\n  <br \/>For our AS I am going to use ACS. Concretely: I\u2019ll use the Identity and Access Tools for VS2012 to secure the MVC app against one ACS namespace. I am going to use one I already have, which happens to be already federated with Facebook and Windows Azure AD; you can find all the instructions <a href=\"http:\/\/blogs.msdn.com\/b\/vbertocci\/archive\/2012\/11\/07\/provisioning-a-directory-tenant-as-an-identity-provider-in-an-acs-namespace.aspx\">here<\/a>.&#160;&#160;&#160; <\/p>\n<p>#2 is pretty easy, especially if we pick an easy profile: here I\u2019ll go for the implicit profile, where a request directly leads to an access token without intermediate steps. Here there\u2019s how the spec describes a request for the implicit flow:<\/p>\n<p><font face=\"Courier New\">GET \/authorize?<font color=\"#ff0000\">response_type<\/font>=token&amp;<font color=\"#ff0000\">client_id<\/font>=s6BhdRkqt3&amp;<font color=\"#ff0000\">state<\/font>=xyz <\/p>\n<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &amp;<font color=\"#ff0000\">redirect_uri<\/font>=https%3A%2F%2Fclient%2Eexample%2Ecom%2Fcb HTTP\/1.1 <\/p>\n<p>Host: server.example.com<\/font><\/p>\n<p>That boils down to a controller and one action accepting the above as parameters. Hence, I\u2019ll create a new controller as one action as below:<\/p>\n<pre class=\"csharpcode\"><span class=\"kwrd\">namespace<\/span> PoorMansAS.Controllers\n{\n    <span class=\"kwrd\">public<\/span> <span class=\"kwrd\">class<\/span> AuthorizationServerController : Controller\n    {\n        [Authorize]\n        <span class=\"kwrd\">public<\/span> ActionResult Authorize(<span class=\"kwrd\">string<\/span> response_type,\n                                      <span class=\"kwrd\">string<\/span> client_id,\n                                     <span class=\"kwrd\">string<\/span> state,\n                                     <span class=\"kwrd\">string<\/span> redirect_uri,\n                                     <span class=\"kwrd\">string<\/span> resource)\n        {  <\/pre>\n<p>You might have noticed I have added an extra parameter, resource. Its purpose is to let the AS know which resource we are asking access to. That will likely trigger some controversy about use of Scope for that purpose instead. I don\u2019t want to enter in religious arguments here, if you are interested in the rationale we can chat offline; let\u2019s just say that for the purpose of this example (which is NOT production ready, as you already know) the resource parameter makes up of an easier flow.<\/p>\n<p>#3 is the step that I am going to leave in its entirety as exercise for the reader. It entails looking up the current user (which you\u2019ll find in ClaimsPrincipal.Current, as authenticated from ACS and WIF in #1), comparing it with the resources model that is specific to your case, render some UI which prompts the user for the things you want to ask, and get back here with the results (and without having forgotten the list of parameters you originally received). That\u2019s pure MVC UX, no OAuth magic required, hence I\u2019ll skip it.<\/p>\n<p>#4 is the interesting part. It mainly entails creating the token you want to return to the client, and embed it in the right format. Per the OAuth spec, it should look like the following:<\/p>\n<p><font face=\"Courier New\">HTTP\/1.1 302 Found<br \/>\n    <br \/>Location: http:\/\/example.com\/cb#<font color=\"#ff0000\">access_token<\/font>=2YotnFZFEjr1zCsicMWpAA <\/p>\n<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &amp;<font color=\"#ff0000\">state<\/font>=xyz&amp;<font color=\"#ff0000\">token_type<\/font>=example&amp;<font color=\"#ff0000\">expires_in<\/font>=3600<\/font><\/p>\n<p>That\u2019s right, this is just a redirect against the redirect_uri specified in the request (which you should normally validate against what you know about the client, BTW). This means we can just generate a token, embed it in the right URL template, return it within a RedirectResult and call it a day. Sounds simple enough. Let\u2019s get to work and write the body of Authorize.<\/p>\n<p>Given that we are skipping #3, what should we put in the token? I have a proposal. How about we take the claims content of the incoming token (the one we get from #1) and just re-issue those? For the tutorial that seems good enough; if you want to apply sophisticated transformation logic without repackaging, that\u2019s pretty simple: do whatever claims arithmetic you want on the incoming ClaimsPrincipal before using it to seed the outgoing token.<br \/>\n  <br \/>Speaking of the outgoing token: the obvious choice here is a JWT, hence make sure you add a reference to the <a href=\"https:\/\/nuget.org\/packages\/Microsoft.IdentityModel.Tokens.JWT\">JWT Handler NuGet<\/a>. The good news is that creating a new JWT is ridiculously easy with the new JWT handler, we don\u2019t even need to bother setting up with an STS pipeline; we can literally just new() one, with the parameters we want. So, here there\u2019s the first line of our Authorize method:<\/p>\n<div class=\"csharpcode\">\n<pre><span class=\"lnum\">   1:  <\/span>JWTSecurityToken jst = <span class=\"kwrd\">new<\/span> JWTSecurityToken(<span class=\"str\">&quot;urn:poormansas&quot;<\/span>,<\/pre>\n<pre><span class=\"lnum\">   2:  <\/span>                                             resource, <\/pre>\n<pre><span class=\"lnum\">   3:  <\/span>                                             ClaimsPrincipal.Current.Claims, <\/pre>\n<pre><span class=\"lnum\">   4:  <\/span>                                             CreateSigningCredentials(), <\/pre>\n<pre><span class=\"lnum\">   5:  <\/span>                                             DateTime.Now, <\/pre>\n<pre><span class=\"lnum\">   6:  <\/span>                                             DateTime.Now.AddHours(1));<\/pre>\n<\/div>\n<p> I broke the parameters down so that I can provide some commentary.<\/p>\n<p>Line 1: this string is the Issuer identifier I picked for our micro AS.<\/p>\n<p>Line 2: that\u2019s the resource ID: basically it\u2019s the token audience, the service we are issuing a token for<\/p>\n<p>Line 3: the claims describing the current authenticated user<\/p>\n<p>Line 4: the key used by the AS to sign the token. More about that below<\/p>\n<p>Line 5: creation instant<\/p>\n<p>Line 6: validity limits. This token will be valid for one hour, starting from now.<\/p>\n<p>Now we have a token in memory. Superb! All we need to do is serialize it and return it as described by the standard. Here there are the next (and last) 2 lines of Authorize.<\/p>\n<div class=\"csharpcode\">\n<pre><span class=\"lnum\">   1:  <\/span>JWTSecurityTokenHandler jh = <span class=\"kwrd\">new<\/span> JWTSecurityTokenHandler();<\/pre>\n<pre><span class=\"lnum\">   2:  <\/span>&#160;<\/pre>\n<pre><span class=\"lnum\">   3:  <\/span><span class=\"kwrd\">return<\/span> <span class=\"kwrd\">new<\/span> RedirectResult(<\/pre>\n<pre><span class=\"lnum\">   4:  <\/span>   <span class=\"kwrd\">string<\/span>.Format(<span class=\"str\">&quot;{0}#access_token={1}{2}&amp;token_type=bearer&amp;expires_in=3600&quot;<\/span>, <\/pre>\n<pre><span class=\"lnum\">   5:  <\/span>                  redirect_uri, <\/pre>\n<pre><span class=\"lnum\">   6:  <\/span>                  jh.WriteToken(jst), <\/pre>\n<pre><span class=\"lnum\">   7:  <\/span>                  ((state == <span class=\"kwrd\">null<\/span>) ? <span class=\"kwrd\">string<\/span>.Empty : <span class=\"str\">&quot;&amp;state=&quot;<\/span> + state)));   <\/pre>\n<\/div>\n<p>Line 1: in order to serialize the token, we need a handler instance<\/p>\n<p>Line 3: to return a 302, we return a RedirectResult <\/p>\n<p>Line 4: this is the URL template as shown in the snippet form the standard, with the proper placeholders<\/p>\n<p>Line 5: the redirect_uri provided by the client. Did I mention you\u2019d normally validate it somehow?<\/p>\n<p>Line 6: the handler is used to emit the JWT in its encoded format, ready to travel on the wire<\/p>\n<p>Line 7: if the client specified a state, we play it back.<\/p>\n<p>&#160;<\/p>\n<p>This is pretty much all we need for our micro AS. There\u2019s a detail missing, though: the key we use for signing tokens. My personal preference is using X509 certificates, as they dramatically simplify key distribution; however, as you\u2019ll see in a moment, here I used a symmetric key. Why? For a very menial reason, which requires me to do a little bit of a detour. <\/p>\n<p>You see, the AS is going to be accessed through the WebAuthenticationBroker (WAB from now on) API. The WAB offers a very handy API for driving OAuth-based authentication experiences: as we will see in the next section, all you need to do is specifying the AS request URL, the redirect_uri and everything else will be taken care of for you. That includes summoning a surface on the screen that the AS can use as a canvas for rendering its authentication and consent experience. That surface tends to be extremely picky about the URLs it will render: for example, URLs that would make the bar of your browser red would not even show up in the WAB. Also, working with the WAB and URLs pointing to the local machine tends to require extra work with loopback adapters and similar. That\u2019s all for the end user\u2019s protection, hence all good: however, given that it\u2019s Sunday, I don\u2019t feel like doing a lot of extra work for working around those protections (and explaining you what I had to do). Instead I\u2019ll avoid the problem altogether, by deploying and running my AS in Windows Azure Web Sites. It takes just minutes:<\/p>\n<ol>\n<li>I created a new Windows Azure Web Site, poormansas.azurewebsites.net, and downloaded the associated publishing profile<\/li>\n<li>I re-ran the Identity and Access Tools for VS2012, doing the following changes:<\/li>\n<ol>\n<li>In the Providers tab, changed the return URL for the app to <a href=\"https:\/\/poormansas.azurewebsites.net\/\">https:\/\/poormansas.azurewebsites.net\/<\/a> <\/li>\n<li>In the Configuration tab, I made sure that both realm and audienceURI are at \u201curn:poormansas\u201d; and I checked the \u201cEnable web farm cookies\u201d box<\/li>\n<\/ol>\n<li>I published the PoorMansAS project directly from Visual Studio to the corresponding Windows Azure Web Site<\/li>\n<\/ol>\n<p>And voila\u2019, we now have a publicly addressable AS that will make the WAB happy.<\/p>\n<p>OK &#8211; you might say \u2013 that\u2019s all fine and dandy, but what does that have to do with the use of symmetric keys instead of certificates? The fact is, using certificates in Windows Azure Web Sites is not super-easy right now. I could have targeted a Cloud Service, which does have nice support for X509, but things would have taken longer; so I just factored out from Authorize the actual signing credentials creation so that you can easily substitute its code for a certificate if you so choose. Now that you finally know why I am using a symmetric key, here there\u2019s the code of CreateSigningCredentials:<\/p>\n<pre class=\"csharpcode\"><span class=\"kwrd\">private<\/span> SigningCredentials CreateSigningCredentials()\n{\n   <span class=\"kwrd\">string<\/span> symmetricKey = <span class=\"str\">&quot;V..................................E=&quot;<\/span>;\n   <span class=\"kwrd\">byte<\/span>[] keybytes = Convert.FromBase64String(symmetricKey);  \n   SecurityKey securityKey = <span class=\"kwrd\">new<\/span> InMemorySymmetricSecurityKey(keybytes);\n   SigningCredentials signingCredentials = \n           <span class=\"kwrd\">new<\/span> SigningCredentials(securityKey, \n               SecurityAlgorithms.HmacSha256Signature,\n               SecurityAlgorithms.Sha256Digest);   \n   <span class=\"kwrd\">return<\/span> signingCredentials;\n}<\/pre>\n<p>Not much to comment here, it\u2019s some crypto soup which gets distilled in a signing credential (thank you Brent for knowing *everything* about this stuff, you\u2019re a national treasure :-)). Ah, and of course that code has to be in the package you deploy to your Web Site.<\/p>\n<p>Alrighty! So many words, but so little code required \u2013 in what I believe is a testament of how neat &amp; handy MVC, WIF, the JWT handler and OAuth in general are.<br \/>\n  <br \/>I trust you fully understand that this implementation is obscenely lacking in term of basic security, error management, and all that is good and required for software to even dream of getting closer to something with any actual use; this is just for giving you an idea of the entire scenario, kind of when we add custom STSes in our samples and labs for showing things end to end. Sorry if those frequent disclaimers are annoying, but I just want to make sure we\u2019re clear \ud83d\ude42<\/p>\n<h1>Securing the Web API with the JWT Handler<\/h1>\n<p>Very well. Now that we have an AS, we can add a DelegatingHandler to the Web API representing the resource (MyProtectedResource) in the same was as explained in the backed section <a href=\"http:\/\/blogs.msdn.com\/b\/vbertocci\/archive\/2013\/01\/09\/using-the-jwt-handler-for-implementing-poor-man-s-delegation-actas.aspx\">here<\/a>. The only difference is in fact in the use of the symmetric key for validating the incoming token. In concrete, you\u2019ll have to modify the creation of the TokenValidationParameters as follows:<\/p>\n<pre class=\"csharpcode\">TokenValidationParameters validationParameters =\n<span class=\"kwrd\">new<\/span> TokenValidationParameters()\n{\n   AllowedAudience = <span class=\"str\">&quot;urn:poormansactassample&quot;<\/span>,\n   ValidIssuer = <span class=\"str\">&quot;urn:poormansas&quot;<\/span>,\n   SigningToken = <span class=\"kwrd\">new<\/span> BinarySecretSecurityToken(\n       Convert.FromBase64String(<span class=\"str\">&quot;V...............E=&quot;<\/span>))\n};<\/pre>\n<p>Everything else is as described in <a href=\"http:\/\/blogs.msdn.com\/b\/vbertocci\/archive\/2013\/01\/09\/using-the-jwt-handler-for-implementing-poor-man-s-delegation-actas.aspx\">here<\/a>.<\/p>\n<p>Now that the API is ready to validate incoming tokens, it\u2019s time to get us some.<\/p>\n<h1>Getting tokens with the WebAuthenticationBroker<\/h1>\n<p>Let\u2019s get back to the client. In order to complete our scenario, we need to perform 2 tasks:<\/p>\n<ul>\n<li>we need to modify the call to the service to include a token<\/li>\n<li>we need to add logic to acquire the token through our new AS<\/li>\n<\/ul>\n<p>The first one is easy, so let\u2019s get it out of the way:<\/p>\n<div class=\"csharpcode\">\n<pre><span class=\"lnum\">   1:  <\/span><span class=\"kwrd\">private<\/span> async <span class=\"kwrd\">void<\/span> InitializeQuotes(<span class=\"kwrd\">string<\/span> token)<\/pre>\n<pre><span class=\"lnum\">   2:  <\/span>{<\/pre>\n<pre><span class=\"lnum\">   3:  <\/span>  ObservableCollection&lt;<span class=\"kwrd\">string<\/span>&gt; quotesColl = <span class=\"kwrd\">null<\/span>;<\/pre>\n<pre><span class=\"lnum\">   4:  <\/span>&#160;<\/pre>\n<pre><span class=\"lnum\">   5:  <\/span>  <span class=\"kwrd\">using<\/span> (var http = <span class=\"kwrd\">new<\/span> HttpClient())<\/pre>\n<pre><span class=\"lnum\">   6:  <\/span>  {<\/pre>\n<pre><span class=\"lnum\">   7:  <\/span>      http.DefaultRequestHeaders.Authorization = <\/pre>\n<pre>                <span class=\"kwrd\">new<\/span> System.Net.Http.Headers.AuthenticationHeaderValue(<\/pre>\n<pre>                <span class=\"str\">&quot;bearer&quot;<\/span>, token);<\/pre>\n<pre><span class=\"lnum\">   8:  <\/span>      HttpResponseMessage response = await http.GetAsync(<span class=\"kwrd\">new<\/span> Uri(<span class=\"str\">&quot;http:\/\/localhost:47524\/Api\/InspiringQuotes&quot;<\/span>));     <\/pre>\n<pre><span class=\"lnum\">   9:  <\/span>      Stream rez = await response.Content.ReadAsStreamAsync();<\/pre>\n<pre><span class=\"lnum\">  10:  <\/span>      var deser = <span class=\"kwrd\">new<\/span> DataContractJsonSerializer(<span class=\"kwrd\">typeof<\/span>(List&lt;<span class=\"kwrd\">string<\/span>&gt;));<\/pre>\n<pre><span class=\"lnum\">  11:  <\/span>      quotesColl = <span class=\"kwrd\">new<\/span> ObservableCollection&lt;<span class=\"kwrd\">string<\/span>&gt;((IEnumerable&lt;<span class=\"kwrd\">string<\/span>&gt;)deser.ReadObject(rez));<\/pre>\n<pre><span class=\"lnum\">  12:  <\/span>      quotesListView.ItemsSource = quotesColl;<\/pre>\n<pre><span class=\"lnum\">  13:  <\/span>    }<\/pre>\n<pre><span class=\"lnum\">  14:  <\/span>}<\/pre>\n<\/div>\n<p>I didn\u2019t reformat much, because there\u2019s only 2 lines that changed: #1, in which we added a parameter token, and #7, where we add the token as authentication header. Everything else remains the same.<\/p>\n<p>And now, for a bit more fun, let\u2019s see how to change the click handler of the button to include a request for a token to the AS:<\/p>\n<div class=\"csharpcode\">\n<pre><span class=\"lnum\">   1:  <\/span> <span class=\"kwrd\">private<\/span> async <span class=\"kwrd\">void<\/span> Button_Click_1(<span class=\"kwrd\">object<\/span> sender, RoutedEventArgs e)<\/pre>\n<pre><span class=\"lnum\">   2:  <\/span>{<\/pre>\n<pre><span class=\"lnum\">   3:  <\/span>   <span class=\"kwrd\">string<\/span> StartUri = <\/pre>\n<pre><span class=\"lnum\">   4:  <\/span>     <span class=\"str\">&quot;https:\/\/poormansas.azurewebsites.net\/AuthorizationServer\/Authorize?<\/span><\/pre>\n<pre><span class=\"str\">             response_type=token<\/span><span class=\"str\">&amp;<\/span><\/pre>\n<pre><span class=\"str\">             state=xyz&amp;<\/span><\/pre>\n<pre><span class=\"str\">             resource=urn:poormansactassample&amp;<\/span><\/pre>\n<pre><span class=\"str\">             client_id=s6BhdRkqt3&amp;<\/span><\/pre>\n<pre><span class=\"str\">             redirect_uri=&quot;<\/span><\/pre>\n<pre><span class=\"lnum\">   5:  <\/span>     + Uri.EscapeUriString(<span class=\"str\">&quot;http:\/\/myreturnuri&quot;<\/span>);<\/pre>\n<pre><span class=\"lnum\">   6:  <\/span>    WebAuthenticationResult WebAuthenticationResult = <\/pre>\n<pre>              await WebAuthenticationBroker.AuthenticateAsync(  <\/pre>\n<pre>                      WebAuthenticationOptions.None,<\/pre>\n<pre>                      <span class=\"kwrd\">new<\/span> System.Uri(StartUri),<\/pre>\n<pre>                      <span class=\"kwrd\">new<\/span> System.Uri(<span class=\"str\">&quot;http:\/\/myreturnuri&quot;<\/span>)  );<\/pre>\n<pre><span class=\"lnum\">   7:  <\/span>            <\/pre>\n<pre><span class=\"lnum\">   8:  <\/span>  <span class=\"kwrd\">if<\/span> (WebAuthenticationResult.ResponseStatus ==<\/pre>\n<pre>             WebAuthenticationStatus.Success)<\/pre>\n<pre><span class=\"lnum\">   9:  <\/span>  {<\/pre>\n<pre><span class=\"lnum\">  10:  <\/span>     <span class=\"kwrd\">string<\/span> a = WebAuthenticationResult.ResponseData.ToString();<\/pre>\n<pre><span class=\"lnum\">  11:  <\/span>     <span class=\"kwrd\">string<\/span> token = <\/pre>\n<pre>              a.Substring(a.IndexOf(<span class=\"str\">'='<\/span>) + 1, <\/pre>\n<pre>                          a.IndexOf(<span class=\"str\">'&amp;'<\/span>) - a.IndexOf(<span class=\"str\">'='<\/span>) - 1);<\/pre>\n<pre><span class=\"lnum\">  12:  <\/span>&#160;<\/pre>\n<pre><span class=\"lnum\">  13:  <\/span>     InitializeQuotes(token);<\/pre>\n<pre><span class=\"lnum\">  14:  <\/span>   }<\/pre>\n<pre><span class=\"lnum\">  15:  <\/span>   <span class=\"kwrd\">else<\/span> <span class=\"kwrd\">if<\/span> (WebAuthenticationResult.ResponseStatus == WebAuthenticationStatus.ErrorHttp)<\/pre>\n<pre><span class=\"lnum\">  16:  <\/span>   {<\/pre>\n<pre><span class=\"lnum\">  17:  <\/span>     <span class=\"kwrd\">string<\/span> ee = WebAuthenticationResult.ResponseErrorDetail.ToString();  <\/pre>\n<pre><span class=\"lnum\">  18:  <\/span>    }<\/pre>\n<pre><span class=\"lnum\">  19:  <\/span>    <span class=\"kwrd\">else<\/span><\/pre>\n<pre><span class=\"lnum\">  20:  <\/span>    {<\/pre>\n<pre><span class=\"lnum\">  21:  <\/span>      <span class=\"kwrd\">string<\/span> rs = WebAuthenticationResult.ResponseStatus.ToString();<\/pre>\n<pre><span class=\"lnum\">  22:  <\/span>     } <\/pre>\n<pre><span class=\"lnum\">  23:  <\/span>}<\/pre>\n<\/div>\n<p>Lots of long lines, which I had to break in nonstandard ways to adapt to the blog narrow theme\u2026 hopefully the colored syntax will help. Let\u2019s dive:<\/p>\n<p>Line 3: this string contains the request for the AS. I broke that down for legibility. The first part is, obviously, the path to the action. The response_type=token indicates that we want to do the implicit profile. The state is there just to show that, well, it works :-). The resource is the \u201crealm\u201d\/intended audience\/ID of the service we are asking a token for. The client ID is a random string I am using a placeholder, but IRL you\u2019d use the ID that the client used to register itself with the AS (and the AS would validate it). The redirect_uri is an arbitrary URI that will be used by the AS to 302\u2019s the result. It does not have to correspond to a network addressable endpoint, and in fact in this case it does not.<\/p>\n<p>Line 4: this is the key line. Here we invoke the WAB, via the AuthenticateAsync method, passing: default authentication settings (please ignore this for this post, I might touch on that in the future), the AS request URL as the initial URL to render in the WAB, and the redirect_uri value. The last value tells the WAB that as soon as the flow would end up accessing such URI, it\u2019s time to interrupt the interaction and return the last URL in its entirety.<\/p>\n<p>Line 8: if the authentication flow terminated successfully:<\/p>\n<p>Line 10: we extract from the AuthenticationResults the ResponseData, which are in fact the latest request\u2019 URL<\/p>\n<p>Line 11: we parse out from it the token bits, in a very un-scientific fashion (see earlier for the format in which tokens are returned in the implicit profile).<\/p>\n<p>Line 13: we make our call, passing the token, with the modified InitializeQuotes shown earlier.<\/p>\n<p>Line 15 to 22: just some interesting places for you to keep an eye on when something does not go as expected.<\/p>\n<p>&#160;<\/p>\n<p>Perfect, we are ready to see this thing in action! Place a breakpoint on line 13, and hit F5.<\/p>\n<p>You\u2019ll see the same app screen as before. Hit Get quotes.<\/p>\n<p>&#160;<\/p>\n<p><a href=\"http:\/\/cloudidentity.com\/blog\/wp-content\/uploads\/2013\/02\/1565.image_5F00_5D6C7F79.png\"><img loading=\"lazy\" decoding=\"async\" title=\"image\" style=\"border: 0px currentcolor\" border=\"0\" alt=\"image\" src=\"http:\/\/cloudidentity.com\/blog\/wp-content\/uploads\/2013\/02\/1565.image_5F00_5D6C7F79.png\" width=\"550\" height=\"309\" \/><\/a> <\/p>\n<p>A-ha! DO you recognize that screen? yes, it\u2019s the ACS HRD page. Hit Facebook.<\/p>\n<p>&#160;<\/p>\n<p><a href=\"http:\/\/cloudidentity.com\/blog\/wp-content\/uploads\/2013\/02\/7848.image_5F00_16172987.png\"><img loading=\"lazy\" decoding=\"async\" title=\"image\" style=\"border: 0px currentcolor\" border=\"0\" alt=\"image\" src=\"http:\/\/cloudidentity.com\/blog\/wp-content\/uploads\/2013\/02\/7848.image_5F00_16172987.png\" width=\"550\" height=\"300\" \/><\/a> <\/p>\n<p>It was to be expected. ACS has no idea that you are browsing thru the WAB, which uses a fixed with, hence it does not invoke Facebook with the smaller auth page layout. But hey, this is an experiment, no expectations of perfection here. Go ahead and authenticate; if everything goes well, VS should stop at the breakpoint.<\/p>\n<p>Hover over the variable a: it\u2019s interesting to see what we get back. In my case, I get<\/p>\n<p>http:\/\/myreturnuri\/#access_token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.ey<br \/>\n  <br \/>[OMISSIS]ck&amp;state=xyz&amp;token_type=bearer&amp;expires_in=3600<\/p>\n<p>..which is really not that surprising, but I would say reassuring \ud83d\ude42<\/p>\n<p>Now, I\u2019ll show you a pretty neat trick. Hover over the token variable, and copy its value from the debugger \u201ctooltip\u201d. Now: open a browser and navigate to <a title=\"http:\/\/openidtest.uninett.no\/jwt\" href=\"http:\/\/openidtest.uninett.no\/jwt\">http:\/\/openidtest.uninett.no\/jwt<\/a>.<\/p>\n<p>Here, paste the bits in the left side under Encoded JWT. Remember to get rid of the quotes! Hit \u201cdecode\u201d, and admire the results\u2026 the page unpacks the JWT for you and nicely visualizes its content, as shown below:<\/p>\n<p><a href=\"http:\/\/cloudidentity.com\/blog\/wp-content\/uploads\/2013\/02\/4621.image_5F00_11A0A8C0.png\"><img loading=\"lazy\" decoding=\"async\" title=\"image\" style=\"border: 0px currentcolor\" border=\"0\" alt=\"image\" src=\"http:\/\/cloudidentity.com\/blog\/wp-content\/uploads\/2013\/02\/4621.image_5F00_11A0A8C0.png\" width=\"533\" height=\"480\" \/><\/a> <\/p>\n<p>You should recognize the values for the issuer, the audience, and the usual claims you get from Facebook via ACS.<br \/>\n  <br \/>Thank you <a href=\"http:\/\/openidtest.uninett.no\/about\">Andreas and Roland<\/a> for this cool tool!<\/p>\n<p>Now that we took a peek, we can hit F5 to see the rest of the call; if everything goes well, you\u2019ll get the same screen you got in in the non-secured version.<br \/>\n  <br \/>For added points, before letting the call go you could open the Locals window and edit the value of the token variable (you might delete 1 character, for example). That should be enough to make the call fail, proving that yes, without valid token no more inspiring quotes for you \ud83d\ude42<\/p>\n<p>&#160;<\/p>\n<h1>Variants &amp; Considerations<\/h1>\n<p>In theory, the above concludes the scenario I committed to write for Dan; however there are a couple of interesting things that, now that you have the context fresh in your mind, would be criminal of me not to mention.<\/p>\n<h2>WAB\u2019s SSO mode<\/h2>\n<p>Try the following experiment. Run the application as described above, but when it\u2019s time to authenticate with Facebook, please check the \u201cKeep me logged in\u201d checkbox. Authenticate as usual, and observe the quotes appearing on your screen. Now hit the Get quotes button again: the experience will be exactly the same, just like if you would not have checked the&#160; \u201cKeep me logged in\u201d checkbox. What\u2019s going on?<\/p>\n<p>The WAB takes your privacy very seriously, and will try to protect you from generic web sites trying to use your existing sessions without you knowing. How does it do that? Simple. In the default case, the one we implemented so far, every time you invoke the WAB you are getting a brand-new session. That session has no access to any cookies you might have saved in former sessions, and has no access to the cookies on your machine (e.g. the ones you use with IE). That way, the pages you are showing now cannot use existing cookies to access web sites on your behalf without you knowing.<\/p>\n<p>That said: there are indeed situations in which you would like to be able to save cookies and access them later. There is a way for you to invoke the WAB while retaining access to cookies saved in past sessions: in WAB jargon it is called&#160; \u201cSSO mode\u201d, and it its described in details <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/windows\/apps\/jj856909.aspx\">here<\/a>.<\/p>\n<p>In a nutshell: you access SSO mode by invoking AuthenticateAsync without specifying the redirect_uri. That tells the WAB to open its \u201cbrowser\u201d against an existing SSO container. The idea is that, instead of allowing for an arbitrary redirect_uri, the AS is supposed to redirect to a special address, which is in fact the ID of the Windows Store application as assigned by the Windows Dev Center. Do read the msdn page I linked earlier: however here there\u2019s what you need to do in practice. <\/p>\n<ol>\n<li>Find out the application ID. Given that the app is not registered in the Dev Cetner, what can we use? There is an API you can use to find out the right value: it\u2019s basically <strong>Uri EndUri = WebAuthenticationBroker.GetCurrentApplicationCallbackUri();<\/strong><\/li>\n<li>Modify the StarUri cosntruction so that the redirect_uri parameter gets the value calculated in #1. Note, IRL you might want to pre-register that URL with the AS and make it correspond to the client ID, in which case you would not need to explicitly pass it<\/li>\n<li>Modify the call to AuthenticateAsync by eliminating the last parameter<\/li>\n<\/ol>\n<p>If you do the above and run through the same sequence described earlier in this section, you\u2019ll see that this time the \u201ckeep me logged in\u201d flag does work. There\u2019s more! Close the app and restart it: you\u2019ll discover that the cookie is still there, the SSO container is independent from the application \ud83d\ude42 that is a blessing, but it is also a curse: if you save the wrong cookie, then it\u2019s going to be hard to clear it up ad the only way of getting to the SSO cookies jar is to open the WAB in SSO mode.<\/p>\n<h2>Windows Azure AD preview experience opt-in<\/h2>\n<p>The ACS namespace I used here is federated with a Windows Azure Active Directory tenant. Try to run the app and choose Trey Research 2, you\u2019ll get to the following:<\/p>\n<p><a href=\"http:\/\/cloudidentity.com\/blog\/wp-content\/uploads\/2013\/02\/5850.image_5F00_49DF1FD8.png\"><img loading=\"lazy\" decoding=\"async\" title=\"image\" style=\"border: 0px currentcolor\" border=\"0\" alt=\"image\" src=\"http:\/\/cloudidentity.com\/blog\/wp-content\/uploads\/2013\/02\/5850.image_5F00_49DF1FD8.png\" width=\"550\" height=\"307\" \/><\/a> <\/p>\n<p>That is also the \u201cfull desktop\u201d authentication layout. However, in this case there is something you can do about it!<\/p>\n<p>You might have read that we <a href=\"http:\/\/blogs.msdn.com\/b\/windowsazure\/archive\/2013\/02\/05\/simple-responsive-sign-in-to-microsoft-services-driven-by-windows-azure-ad.aspx\">just released in preview a new responsive design<\/a> for our sign-in experiences. The good news is that the way in which you opt in for using the new experience is\u2026 navigating to a page which will record your choice in a cookie \ud83d\ude42 doesn&#8217;t that sound like a perfect dovetail to what we just learned about the SSO mode?<\/p>\n<p>Assuming you did the steps for getting into SSO mode. Temporarily modify your app to use , then launch and click the Get quotes button. You will see the following:<\/p>\n<p><a href=\"http:\/\/cloudidentity.com\/blog\/wp-content\/uploads\/2013\/02\/0676.image_5F00_0289C9E6.png\"><img loading=\"lazy\" decoding=\"async\" title=\"image\" style=\"border: 0px currentcolor\" border=\"0\" alt=\"image\" src=\"http:\/\/cloudidentity.com\/blog\/wp-content\/uploads\/2013\/02\/0676.image_5F00_0289C9E6.png\" width=\"550\" height=\"305\" \/><\/a> <\/p>\n<p>Click opt-in, go back to the app, stop, change the startUri back to the SSO mode value, and hit F5 again.<\/p>\n<p>Click to get quotes, choose Trey Research 2, and\u2026 there\u2019s the beautifully scaled responsive design experience for you \ud83d\ude42<\/p>\n<p><a href=\"http:\/\/cloudidentity.com\/blog\/wp-content\/uploads\/2013\/02\/7827.image_5F00_6921C6AB.png\"><img loading=\"lazy\" decoding=\"async\" title=\"image\" style=\"border: 0px currentcolor\" border=\"0\" alt=\"image\" src=\"http:\/\/cloudidentity.com\/blog\/wp-content\/uploads\/2013\/02\/7827.image_5F00_6921C6AB.png\" width=\"550\" height=\"308\" \/><\/a> <\/p>\n<h1>Summary<\/h1>\n<p>Well, Dan, I hope you\u2019re satisfied \ud83d\ude42 It took until midnight, but I did manage to do and document all the various moving parts we discussed.<\/p>\n<p>Let\u2019s review what I did here:<\/p>\n<ul>\n<li>i started from a simple Windows Store client app, consuming a basic Web API<\/li>\n<li>I created an MVC4 app, secured it with ACS, and added a controller which accepts requests which look (almost) like the ones described by the implicit profile in the OAuth2 specs and spits out JWTs, also as described in the implicit profile<\/li>\n<li>I modified the Web API to expect JWTs issued from the MVC 4 app<\/li>\n<li>I modified the client app to obtain tokens from the MVC 4 app via WebAuthenticationBroker, and inject those tokens in calls to the Web API<\/li>\n<li>I explored a couple of variants, specifically around WebAuthenticationBroker and Windows Azure AD (unrelated) features<\/li>\n<\/ul>\n<p>I called the MVC4 app described above a micro Authorization Server. Is it fair? Perhaps not, given that the skeleton implementation presented lacks many key features; and of course, all the warnings about custom STSes are even stronger here. Packaged products, and even better services, will almost always be a better choice than rolling your own. That said, I hope you found this little experiment fun and thought-provoking \ud83d\ude42<\/p>\n<div style=\"clear:both\"><\/div>\n","protected":false},"excerpt":{"rendered":"<p>[if there was ever a post where you NEED to understand my post disclaimers, this is it. This is my PERSONAL blog, what I write here are MY OWN personal elucubrations, largely written on nights and weekends instead of engaging in healthy activities, and is by no mean official guidance. Please refer to&#8230;<\/p>\n","protected":false},"author":1,"featured_media":1306,"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":[7,8,14,15,5,12,4,17,16],"tags":[],"class_list":["post-253","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-access-control-service","category-acs","category-jwt","category-oauth2","category-wif","category-windows-azure-active-directory","category-windows-identity-foundation","category-windows-store","category-windows8"],"_links":{"self":[{"href":"https:\/\/www.cloudidentity.com\/blog\/wp-json\/wp\/v2\/posts\/253","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=253"}],"version-history":[{"count":5,"href":"https:\/\/www.cloudidentity.com\/blog\/wp-json\/wp\/v2\/posts\/253\/revisions"}],"predecessor-version":[{"id":1644,"href":"https:\/\/www.cloudidentity.com\/blog\/wp-json\/wp\/v2\/posts\/253\/revisions\/1644"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.cloudidentity.com\/blog\/wp-json\/wp\/v2\/media\/1306"}],"wp:attachment":[{"href":"https:\/\/www.cloudidentity.com\/blog\/wp-json\/wp\/v2\/media?parent=253"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.cloudidentity.com\/blog\/wp-json\/wp\/v2\/categories?post=253"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.cloudidentity.com\/blog\/wp-json\/wp\/v2\/tags?post=253"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}