{"id":2664,"date":"2014-02-16T17:43:13","date_gmt":"2014-02-17T00:43:13","guid":{"rendered":"http:\/\/www.cloudidentity.com\/blog\/?p=2664"},"modified":"2014-02-16T17:47:24","modified_gmt":"2014-02-17T00:47:24","slug":"adal-net-servicing-release-and-the-never-flag","status":"publish","type":"post","link":"https:\/\/www.cloudidentity.com\/blog\/2014\/02\/16\/adal-net-servicing-release-and-the-never-flag\/","title":{"rendered":"ADAL .NET Servicing Release and the Never Flag"},"content":{"rendered":"<p>The team just published an <a href=\"https:\/\/www.nuget.org\/packages\/Microsoft.IdentityModel.Clients.ActiveDirectory\" target=\"_blank\">update to ADAL .NET<\/a>: you can find the new package in ADAL\u2019s home on NuGet here as <a href=\"https:\/\/www.nuget.org\/packages\/Microsoft.IdentityModel.Clients.ActiveDirectory\/1.0.3\" target=\"_blank\">v1.0.3<\/a>.<\/p>\n<p>This is largely a service update &#8211; most of the work that went on it is bug fixing: we adjusted some weird cache behavior, we improved ADAL\u2019s behavior in error-prone situations such as temporary lack of connectivity, and so on.<\/p>\n<p>We did add one new feature, though. We extended the <font face=\"Consolas\">PromptBehavior<\/font> enum to include a new value, <strong><font face=\"Consolas\">Never<\/font><\/strong>. Let\u2019s dig into that for a bit.<\/p>\n<p>You might recall from <a href=\"https:\/\/www.cloudidentity.com\/blog\/2013\/10\/14\/adal-windows-azure-ad-and-multi-resource-refresh-tokens\/\" target=\"_blank\">earlier posts<\/a> that ADAL\u2019s <font face=\"Consolas\">AcquireToken<\/font> has an overload accepting a parameter of type <font face=\"Consolas\">PromptBehavior<\/font>. Until v1.0.2, <font face=\"Consolas\">PromptBehavior<\/font> featured the following two values:<\/p>\n<li><strong><font face=\"Consolas\">Auto<\/font><\/strong>: the default. In this mode, ADAL will do everything in its power to return a token complying to the requirements passed in the <font face=\"Consolas\">AcquireToken<\/font> call (issued for that specific clientID, scoped for the requested resource, etc) without showing a UI: that boils down to looking up the cache for a corresponding cached token, failing that looking up for a suitable (<a href=\"https:\/\/www.cloudidentity.com\/blog\/2013\/10\/14\/adal-windows-azure-ad-and-multi-resource-refresh-tokens\/\" target=\"_blank\">MRRT<\/a>) refresh token and using it. If that fails to retrieve a token, ADAL falls back to popping out a dialog hosting a browser and navigating to the authorization endpoint of the authority of choice (Windows Azure AD, ADFS).<br \/>This is the typical behavior you want when you trust the library to minimize user prompts but you can tolerate such prompts to pop out when needed. <br \/> \n<li><strong><font face=\"Consolas\">Always<\/font><\/strong>: this flag tells ADAL to disregard the cache and refresh token lookups, and directly prompt the user regardless of the cached state.<br \/>You\u2019ll want to do this when you want to guarantee that the user is given an opportunity of specifying a different account from the ones that might already have been used to obtain the tokens already present in cache. Say that you are developing an application which shows side by side resources from different tenants: you want to be able to obtain tokens for multiple, different users and keep them all in the cache at once. Say that you already got a token for resource R with user A: without something like the Always flag, a 2nd call to <font face=\"Consolas\">AcquireToken<\/font> for R would always automatically pick up the token you obtained with A, preventing the user from ever being able to specify B.\n<p>Those two values are fine and dandy, but in fact they don\u2019t cover all possible behaviors you might want to get from <font face=\"Consolas\">AcquireToken<\/font>. Say that you are doing some background work, like refreshing a secondary view, and that work requires you to access protected resources. Your user is focused on the primary view and does not even know that you are doing work on the background. Say that the token acquisition for some of the resources you are accessing in the background fails to take place via cache: would you interfere with the main view and interrupt the user\u2019s work with a credential prompt out of the blue? The user would not even understand why he\/she is being prompted!<\/p>\n<p>That is why we are introducing a new value in <font face=\"Consolas\">PromptBehavior<\/font>:<\/p>\n<li><strong><font face=\"Consolas\">Never<\/font><\/strong>: this flag guarantees that no UI will be displayed in the context of the present <font face=\"Consolas\">AcquireToken<\/font> call. <br \/>It tells ADAL to do whatever it is in its power to obtain the requested token without showing any UI, just like for <font face=\"Consolas\">Auto<\/font>, but if that fails it should stop and return an error that you can trap and handle as you deem appropriate for your application. For example, just to give you an idea: if the resource you were trying to access has a visual representation in your UI you could add a little warning icon or any other signal which gently informs the user about the current state and provide an affordance to explicitly initiate an interactive authentication flow when he\/she sees fit.\n<p>If the story would stop here, I\u2019d say it would be already interesting: but it gets better <img decoding=\"async\" class=\"wlEmoticon wlEmoticon-smile\" style=\"border-top-style: none; border-left-style: none; border-bottom-style: none; border-right-style: none\" alt=\"Smile\" src=\"https:\/\/www.cloudidentity.com\/blog\/wp-content\/uploads\/2014\/02\/wlEmoticon-smile2.png\"> to explain how, I have to peel off an abstraction layer and tell you a bit about the inner workings of the authentication flows and the .NET platform.<\/p>\n<p>When you go through a successful interactive <font face=\"Consolas\">AcquireToken<\/font> flow, the state of your app is altered in two aspects:<\/p>\n<li>ADAL\u2019s token cache gets a new entry: access token, refresh token, occasionally user info, and so on. if you are working with Windows Azure AD, the refresh token is actually a <a href=\"https:\/\/www.cloudidentity.com\/blog\/2013\/10\/14\/adal-windows-azure-ad-and-multi-resource-refresh-tokens\/\" target=\"_blank\">TGT-like artifact<\/a> which will allow you to silently obtain other access tokens for other resources <em>within the same tenant<\/em>.\n<li>As the interaction entails popping out a browser and authenticating to one or more web sites (the IdPs that serve pages for authenticating you: Windows Azure AD, MSA if you are using a guest account, etc) the web flow results in one or more session cookies that are now saved in your process\u2019 cookie jar, where they will stay as long as your process is up or you explicitly nuke them (via some DLL imports).\n<p>Now comes the good part. The effect of the <font face=\"Consolas\">Never<\/font> flag is not to suppress all browser activity in case the cache &amp; refresh token lookup fails: rather, it is to <em>use an invisible browser to hit the authorization endpoint<\/em>. Aha, I can almost see a light in your eyes! <img decoding=\"async\" class=\"wlEmoticon wlEmoticon-smile\" style=\"border-top-style: none; border-left-style: none; border-bottom-style: none; border-right-style: none\" alt=\"Smile\" src=\"https:\/\/www.cloudidentity.com\/blog\/wp-content\/uploads\/2014\/02\/wlEmoticon-smile2.png\"> This has two implications:<\/p>\n<li>If you already have a session cookie in my process jar for the IdP you want, for example thanks to a preceding interaction, the Never flag will allow you to get a token with no UI interaction even if you don\u2019t have any suitable refresh tokens in the cache\n<li>For guest scenarios, like the ones in which you use an MSA for accessing Windows Azure management APIs, <em>use of <font face=\"Consolas\">Never<\/font> +<\/em>&nbsp;<em>the presence of an MSA cookie allows you to silently obtain tokens cross-tenant <\/em>\u2013 whereas MRRTs are bounded to work within a single tenant.\n<p><a href=\"https:\/\/www.cloudidentity.com\/blog\/wp-content\/uploads\/2014\/02\/image19.png\"><img loading=\"lazy\" decoding=\"async\" title=\"image\" style=\"border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px\" border=\"0\" alt=\"image\" src=\"https:\/\/www.cloudidentity.com\/blog\/wp-content\/uploads\/2014\/02\/image_thumb19.png\" width=\"586\" height=\"480\"><\/a><\/p>\n<p><em>Phase 1: get a token via usual interactive flow<\/em><\/p>\n<p><em>Phase 2: delete the token cache content for any reason<\/em><\/p>\n<p><a href=\"https:\/\/www.cloudidentity.com\/blog\/wp-content\/uploads\/2014\/02\/image20.png\"><img loading=\"lazy\" decoding=\"async\" title=\"image\" style=\"border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px\" border=\"0\" alt=\"image\" src=\"https:\/\/www.cloudidentity.com\/blog\/wp-content\/uploads\/2014\/02\/image_thumb20.png\" width=\"570\" height=\"480\"><\/a><\/p>\n<p><font size=\"1\"><em>Phase 3: profit! Ehmm, I mean \u2013 using the <font face=\"Consolas\">Never<\/font> flag the cookie from the process jar is picked up and used to authenticate silently<\/em><\/font><\/p>\n<p>&nbsp;<\/p>\n<li>\n<p>That is pretty neat! But it is also very abstract. How about a quick demonstration of #1? Consider the following code.<\/p>\n<div class=\"csharpcode\">\n<pre><span class=\"lnum\">   1:  <\/span>AuthenticationContext ac = <\/pre>\n<pre><span class=\"lnum\">   2:  <\/span>     <span class=\"kwrd\">new<\/span> AuthenticationContext(<span class=\"str\">\"https:\/\/login.windows.net\/contoso7.onmicrosoft.com\"<\/span>);<\/pre>\n<pre><span class=\"lnum\">   3:  <\/span>&nbsp;<\/pre>\n<pre><span class=\"lnum\">   4:  <\/span><span class=\"rem\">\/\/the first call shows the UI<\/span><\/pre>\n<pre><span class=\"lnum\">   5:  <\/span>AuthenticationResult ar = ac.AcquireToken(<span class=\"str\">\"https:\/\/contoso7.onmicrosoft.com\/RichAPI\"<\/span>,<\/pre>\n<pre><span class=\"lnum\">   6:  <\/span>                    <span class=\"str\">\"be182811-9d0b-45b2-9ffa-52ede2a12230\"<\/span>,<\/pre>\n<pre><span class=\"lnum\">   7:  <\/span>                    <span class=\"kwrd\">new<\/span> Uri(<span class=\"str\">\"http:\/\/whatevah\"<\/span>));<\/pre>\n<pre><span class=\"lnum\">   8:  <\/span>&nbsp;<\/pre>\n<pre><span class=\"lnum\">   9:  <\/span><span class=\"rem\">\/\/the 2nd call hits the cache<\/span><\/pre>\n<pre><span class=\"lnum\">  10:  <\/span>ar = ac.AcquireToken(<span class=\"str\">\"https:\/\/contoso7.onmicrosoft.com\/RichAPI\"<\/span>,<\/pre>\n<pre><span class=\"lnum\">  11:  <\/span>                    <span class=\"str\">\"be182811-9d0b-45b2-9ffa-52ede2a12230\"<\/span>,<\/pre>\n<pre><span class=\"lnum\">  12:  <\/span>                    <span class=\"kwrd\">new<\/span> Uri(<span class=\"str\">\"http:\/\/whatevah\"<\/span>));<\/pre>\n<pre><span class=\"lnum\">  13:  <\/span>&nbsp;<\/pre>\n<pre><span class=\"lnum\">  14:  <\/span><span class=\"rem\">\/\/flush the cache<\/span><\/pre>\n<pre><span class=\"lnum\">  15:  <\/span>ac.TokenCacheStore.Clear();<\/pre>\n<pre><span class=\"lnum\">  16:  <\/span>&nbsp;<\/pre>\n<pre><span class=\"lnum\">  17:  <\/span><span class=\"rem\">\/\/the cookie jar already has the right cookie - the browser briefly flashes in and out of view<\/span><\/pre>\n<pre><span class=\"lnum\">  18:  <\/span>ar = ac.AcquireToken(<span class=\"str\">\"https:\/\/contoso7.onmicrosoft.com\/RichAPI\"<\/span>,<\/pre>\n<pre><span class=\"lnum\">  19:  <\/span>                     <span class=\"str\">\"be182811-9d0b-45b2-9ffa-52ede2a12230\"<\/span>,<\/pre>\n<pre><span class=\"lnum\">  20:  <\/span>                     <span class=\"kwrd\">new<\/span> Uri(<span class=\"str\">\"http:\/\/whatevah\"<\/span>));<\/pre>\n<pre><span class=\"lnum\">  21:  <\/span><span class=\"rem\">\/\/flush the cache again<\/span><\/pre>\n<pre><span class=\"lnum\">  22:  <\/span>ac.TokenCacheStore.Clear();<\/pre>\n<pre><span class=\"lnum\">  23:  <\/span>&nbsp;<\/pre>\n<pre><span class=\"lnum\">  24:  <\/span><span class=\"rem\">\/\/this call is like the 3rd call, but the Never flag makes it fully silent<\/span><\/pre>\n<pre><span class=\"lnum\">  25:  <\/span>ar = ac.AcquireToken(<span class=\"str\">\"https:\/\/contoso7.onmicrosoft.com\/RichAPI\"<\/span>,<\/pre>\n<pre><span class=\"lnum\">  26:  <\/span>                    <span class=\"str\">\"be182811-9d0b-45b2-9ffa-52ede2a12230\"<\/span>,<\/pre>\n<pre><span class=\"lnum\">  27:  <\/span>                    <span class=\"kwrd\">new<\/span> Uri(<span class=\"str\">\"http:\/\/whatevah\"<\/span>),<\/pre>\n<pre><span class=\"lnum\">  28:  <\/span>                    PromptBehavior.Never);<\/pre>\n<\/div>\n<style type=\"text\/css\">.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>Let\u2019s walk through what happens. Assume we are running this right when the process starts.<\/p>\n<p>When line 5 executes, you get the full interactive experience: there is not suitable token in cache yet, not passing any <font face=\"Consolas\">PromptBehavior<\/font> means defaulting to <font face=\"Consolas\">Auto<\/font>, hence this has to result in a prompt.<\/p>\n<p><a href=\"https:\/\/www.cloudidentity.com\/blog\/wp-content\/uploads\/2014\/02\/image21.png\"><img loading=\"lazy\" decoding=\"async\" title=\"image\" style=\"border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; display: inline; padding-right: 0px; border-top-width: 0px\" border=\"0\" alt=\"image\" src=\"https:\/\/www.cloudidentity.com\/blog\/wp-content\/uploads\/2014\/02\/image_thumb21.png\" width=\"411\" height=\"480\"><\/a><\/p>\n<p>(you might notice that the title of the dialog is a bit weird. We have a service side bug these days, hopefully that will be gone soon but it does not interfere with actual auth).<\/p>\n<p>After successful authentication, <font face=\"Consolas\">AcquireToken<\/font> returns and you get back a nice <font face=\"Consolas\">AuthenticationResult<\/font>. Also, the cache has now one new entry:<\/p>\n<p><a href=\"https:\/\/www.cloudidentity.com\/blog\/wp-content\/uploads\/2014\/02\/image22.png\"><img loading=\"lazy\" decoding=\"async\" title=\"image\" style=\"border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; display: inline; padding-right: 0px; border-top-width: 0px\" border=\"0\" alt=\"image\" src=\"https:\/\/www.cloudidentity.com\/blog\/wp-content\/uploads\/2014\/02\/image_thumb22.png\" width=\"640\" height=\"287\"><\/a><\/p>\n<p>Let\u2019s make the exact same call, as in line 10. We have just the right token in the cache, and we get it back right away.<\/p>\n<p>Now, let\u2019s play a bit. Line 15 flushes the cache, so that we end up with zero tokens.<\/p>\n<p><a href=\"https:\/\/www.cloudidentity.com\/blog\/wp-content\/uploads\/2014\/02\/image23.png\"><img loading=\"lazy\" decoding=\"async\" title=\"image\" style=\"border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; display: inline; padding-right: 0px; border-top-width: 0px\" border=\"0\" alt=\"image\" src=\"https:\/\/www.cloudidentity.com\/blog\/wp-content\/uploads\/2014\/02\/image_thumb23.png\" width=\"332\" height=\"159\"><\/a><\/p>\n<p>Let\u2019s run line 18, which contains the exact same call. <\/p>\n<p>It\u2019s hard to show without posting a video, but if you try that code yourself you\u2019ll see it very clearly: the browser briefly appears, but disappears right away before you have a chance of seeing anything. That\u2019s because your process jar already has a session cookie for the authority, which gets posted as soon as you hit its authorization endpoint, hence you find yourself automatically authenticated and <font face=\"Consolas\">AcquireToken<\/font> returns your token right away.<\/p>\n<p>Now, let\u2019s repeat the token cache flushing (line 22) and let\u2019s repeat the call, this time with the <font face=\"Consolas\">Never<\/font> flag: you\u2019ll get back a token, nice and clean, without any prior refresh token in the cache and without any confusing browser flashing.<\/p>\n<p>Well, that\u2019s pretty much it for <a href=\"https:\/\/www.nuget.org\/packages\/Microsoft.IdentityModel.Clients.ActiveDirectory\/1.0.3\" target=\"_blank\">this servicing release<\/a>! <br \/>TL;DR: more power for you. Let us know if you find the new flag useful <img decoding=\"async\" class=\"wlEmoticon wlEmoticon-smile\" style=\"border-top-style: none; border-left-style: none; border-bottom-style: none; border-right-style: none\" alt=\"Smile\" src=\"https:\/\/www.cloudidentity.com\/blog\/wp-content\/uploads\/2014\/02\/wlEmoticon-smile2.png\"><\/p>\n<\/li>\n","protected":false},"excerpt":{"rendered":"<p>The team just published an update to ADAL .NET: you can find the new package in ADAL\u2019s home on NuGet here as v1.0.3. This is largely a service update &#8211; most of the work that went on it is bug fixing: we adjusted some weird cache behavior, we improved ADAL\u2019s behavior in error-prone&#8230;<\/p>\n","protected":false},"author":1,"featured_media":2656,"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-2664","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\/2664","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=2664"}],"version-history":[{"count":1,"href":"https:\/\/www.cloudidentity.com\/blog\/wp-json\/wp\/v2\/posts\/2664\/revisions"}],"predecessor-version":[{"id":2665,"href":"https:\/\/www.cloudidentity.com\/blog\/wp-json\/wp\/v2\/posts\/2664\/revisions\/2665"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.cloudidentity.com\/blog\/wp-json\/wp\/v2\/media\/2656"}],"wp:attachment":[{"href":"https:\/\/www.cloudidentity.com\/blog\/wp-json\/wp\/v2\/media?parent=2664"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.cloudidentity.com\/blog\/wp-json\/wp\/v2\/categories?post=2664"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.cloudidentity.com\/blog\/wp-json\/wp\/v2\/tags?post=2664"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}