{"id":2850,"date":"2014-07-08T00:45:10","date_gmt":"2014-07-08T07:45:10","guid":{"rendered":"http:\/\/www.cloudidentity.com\/blog\/?p=2850"},"modified":"2014-07-11T17:46:51","modified_gmt":"2014-07-12T00:46:51","slug":"using-adal-net-to-authenticate-users-via-usernamepassword","status":"publish","type":"post","link":"https:\/\/www.cloudidentity.com\/blog\/2014\/07\/08\/using-adal-net-to-authenticate-users-via-usernamepassword\/","title":{"rendered":"Using ADAL .NET to Authenticate Users via Username\/Password"},"content":{"rendered":"<p>This might be the most requested feature for ADAL: the ability of authenticating a user by pumping in username\/password, without showing any pop up. There are perfectly legitimate scenarios that require that feature; unfortunately there are also many ways in which abusing this feature might backfire.<\/p>\n<p>With the RC we just released, we added this feature to ADAL .NET (but not to Windows Store or Windows Phone). We have a sample showing how to use it; here I\u2019ll highlight the minimal syntax that lights it up, discuss some considerations about different cases,\u00a0 and above all I\u2019ll spell out limitations and warnings about what you are bargaining when you choose to go this route.<\/p>\n<h2>When to Use This Feature<\/h2>\n<p>There are a number of scenarios where the direct use of username and password is inevitable. The ones below are the ones I encountered most often.<\/p>\n<p>Note that all of those scenarios could be potentially solved by Windows Integrated Auth (WIA), however not all setups can leverage that (e.g. cloud-only tenants, clients running outside of the domain, etc) hence in the below I assume we\u2019re in such unfortunate cases.<\/p>\n<h3>Headless clients<\/h3>\n<p>Say that you are operating from a console app, running on a Server Core. There is simply no Windows manager on the box to render any UX \u2013 everything needs to take place in text.<\/p>\n<h3>Legacy Solutions<\/h3>\n<p>During the Ask the Expert night at this year\u2019s TechEd North America I met with a gentleman who described a setup in which he was using legacy hardware already sending username and password. His investment in such clients was massive and decomissioning them (or the software running on them) was out of question. He very much wanted to move to AAD and move his backend to the cloud, but could not rely on our current credential gathering experience. The direct use of username and password will allow him to bridge his legacy solution to his new cloud based backend, secured via AAD.<\/p>\n<h3>Automated Testing<\/h3>\n<p>This is an all-time favorite of our partners within Microsoft. If I\u2019s have a dollar for every mail\/IM\/hallway conversation I got about this\u2026 <img decoding=\"async\" class=\"wlEmoticon wlEmoticon-smile\" src=\"https:\/\/www.cloudidentity.com\/blog\/wp-content\/uploads\/2014\/07\/wlEmoticon-smile1.png\" alt=\"Smile\" \/><br \/>\nThe scenario is simple: you have a solution based on native clients and you want to automate its verification. Existing test harnesses don\u2019t always make it easy to automate a web based credential gathering interface, hence the request for a mechanism to easily obtain tokens in exchange for test credentials.<\/p>\n<h2>When NOT to Use This Feature<\/h2>\n<p>This is easy: in pretty much any other case! <img decoding=\"async\" class=\"wlEmoticon wlEmoticon-smile\" src=\"https:\/\/www.cloudidentity.com\/blog\/wp-content\/uploads\/2014\/07\/wlEmoticon-smile1.png\" alt=\"Smile\" \/> Direct manipulation of credentials is a BIG responsibility that significantly grows your attack surface, is conducive of bad habits (like caching the credentials), denies you pretty much all of the advantages you get by presenting a server-driven experience (multi factor auth, consent, multi-hop federation, etc \u2013 see below) and makes your client deployments brittle.<\/p>\n<p>The main anti-pattern hidden behind requests for this feature is the desire for customizing the authentication experience. I totally understand that desire, but I often get the impression that the tradeoff one makes when going that route are not always well understood. Falling back to direct credential manipulation is an awfully high price to pay: it cuts you our from a long list of features and puts both your users and your app at risk. I would rather hear your feedback about what parts of the server-provided UX you want to customize &#8211; and fiercely fight for you in shiproom to make that change happen \u2013 rather than helping you through a security crisis.<\/p>\n<h2>How it works<\/h2>\n<p>Enough with the doom &amp; gloom, let\u2019s take a look at some code! <img decoding=\"async\" class=\"wlEmoticon wlEmoticon-winkingsmile\" src=\"https:\/\/www.cloudidentity.com\/blog\/wp-content\/uploads\/2014\/07\/wlEmoticon-winkingsmile.png\" alt=\"Winking smile\" \/><br \/>\nFor the visitors form the future: this feature lights up for the first time in ADAL version <a href=\"http:\/\/www.nuget.org\/packages\/Microsoft.IdentityModel.Clients.ActiveDirectory\/2.7.10707.1513-rc\">2.7.10707.1513-rc<\/a>.<\/p>\n<p>I\u2019d daresay that the way in which this feature has been implemented fits right in in the existing, well-proven credentials model we introduced since v1 for handling client credentials flow (see <a href=\"https:\/\/github.com\/AzureADSamples\/Daemon-DotNet\">this sample<\/a>).<br \/>\nWe introduced a new type, <strong>UserCredential<\/strong>, which represents a user credential. If you want to use username and password, you\u2019d initialize a new instance via the following:<\/p>\n<pre class=\"csharpcode\">UserCredential uc = <span class=\"kwrd\">new<\/span> UserCredential(user, password);<\/pre>\n<pre class=\"csharpcode\"><\/pre>\n<p>Where user is a string containing the UPN of the user you want to authenticate, and password is a string or a SecureString containing\u2026 well, you know.<\/p>\n<p>How to you use uc for getting a token? Well, we added a couple of overloads to the AcquireToken* family:<\/p>\n<pre class=\"csharpcode\"><span class=\"kwrd\">public<\/span> AuthenticationResult AcquireToken(<span class=\"kwrd\">string<\/span> resource, <span class=\"kwrd\">string<\/span> clientId, UserCredential userCredential);\r\n<span class=\"kwrd\">public<\/span> Task&lt;AuthenticationResult&gt; AcquireTokenAsync(<span class=\"kwrd\">string<\/span> resource, <span class=\"kwrd\">string<\/span> clientId, UserCredential userCredential);<\/pre>\n<p>&nbsp;<\/p>\n<p>The relationship between the client app and the resource is precisely the same one you learned about in all other single tenant native client-&gt;web service ADAL samples: both need to be registered, the API needs to expose at least a permission, the client needs to be configured to request such permission, and so on. Note that ehre there is no opportunity for AAD to prompt for consent, hence flows which would require it are off limits here.<\/p>\n<p>Once you call one of those overloads, as long as you provided the correct credentials (and your tenant is configured correctly) you\u2019ll get back a standard AuthenticationResult, the resulting tokens will be automatically cached, and so on.<\/p>\n<p>You can get a feeling of how this all works by giving a spin to our <a href=\"https:\/\/github.com\/AzureADSamples\/NativeClient-Headless-DotNet\">headless native client sample on GitHub.<\/a> Here there\u2019s a screenshot of a typical run, to give you a feeling of the experience you can achieve with this flow. Party like it\u2019s \u201895! <img decoding=\"async\" class=\"wlEmoticon wlEmoticon-smile\" src=\"https:\/\/www.cloudidentity.com\/blog\/wp-content\/uploads\/2014\/07\/wlEmoticon-smile1.png\" alt=\"Smile\" \/><\/p>\n<p><a href=\"https:\/\/www.cloudidentity.com\/blog\/wp-content\/uploads\/2014\/07\/image2.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\" src=\"https:\/\/www.cloudidentity.com\/blog\/wp-content\/uploads\/2014\/07\/image_thumb2.png\" alt=\"image\" width=\"570\" height=\"480\" border=\"0\" \/><\/a><\/p>\n<p>To peek a bit behind the scenes, there are two main sub-scenarios:<\/p>\n<ul>\n<li>your user belongs to a managed tenant. In that case, ADAL performs an OAuth2 password grant and gets back the usual result.<\/li>\n<li>your user belongs to a federated tenant. In that case, ADAL discovers the coordinates of the corresponding ADFS instance, hits it via WS-Trust, sends the resulting SAML token to AAD as an assertion and gets back the usual result.<\/li>\n<\/ul>\n<p>From your code you won\u2019t notice any difference between the two cases \u2013 I am just mentioning that so that you\u2019re aware of what\u2019s required for making this flow work. For example, if instead of ADFS you set up another IP that does not expose WS-Trust endpoints or does it differently from ADFS, this flow will likely fail.<\/p>\n<h2>Constraints &amp; Limitations<\/h2>\n<p>Here there\u2019s a list of limitations you\u2019ll have to take into account when using this flow.<\/p>\n<h4>Only on .NET<\/h4>\n<p>Given the intended usage of this feature, we decided to add it only to .NET.<\/p>\n<p>On Windows Store we added the ability to use Windows Integrated auth, which has many of the same advantages and less drawbacks. Details in another post.<\/p>\n<h4>No web sites\/confidential clients<\/h4>\n<p>This is not an ADAL limitation, but an AAD setting. You can only use those flows from a native client. A confidential client, such as a web site, cannot use direct user credentials.<\/p>\n<h4>No MSA<\/h4>\n<p>Microsoft accounts that are used in the context of an AAD tenant (classic example: Azure admins) cannot authenticate to AAD via raw credentials \u2013 they MUST use the interactive flow (though the PromptBehavior.Never flag remains an option).<\/p>\n<h4>No MFA<\/h4>\n<p>Multi-factor authentication requires dynamic UX to be served on the fly \u2013 that clearly cannot happen in this flow.<\/p>\n<h4>No Consent<\/h4>\n<p>Users do not have any opportunity of providing consent if username &amp; password are passed directly.<\/p>\n<h4>No multi-hop federation<\/h4>\n<p>Any scenario requiring home realm discovery, multiple federation hops and similar won\u2019t work \u2013 the protocol steps are rigidly codified in the client library, with no chance for the server to dynamically influence the authentication path.<\/p>\n<h4>No any server side features, really<\/h4>\n<p>In the \u201ctraditional\u201d AcquireToken flows you have the opportunity of injecting extra parameters that will influence the behavior of AAD \u2013 including parameters that AAD didn\u2019t even support when the library was released. None of that is an option when using username and password directly.<\/p>\n<h2>Next<\/h2>\n<p>Direct use of username an password is a powerful feature, which enables important scenarios. However it also a bit of a Faustian pact \u2013 the price you pay for its directness is in the many limitations it entails and the reduced flexibility that it imposes on any solution relying on it.<br \/>\nIf you are in doubt on whether this feature is right for your scenario, feel free to drop us a line!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>This might be the most requested feature for ADAL: the ability of authenticating a user by pumping in username\/password, without showing any pop up. There are perfectly legitimate scenarios that require that feature; unfortunately there are also many ways in which abusing this feature might backfire. With the RC we just released, we&#8230;<\/p>\n","protected":false},"author":1,"featured_media":2853,"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-2850","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\/2850","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=2850"}],"version-history":[{"count":3,"href":"https:\/\/www.cloudidentity.com\/blog\/wp-json\/wp\/v2\/posts\/2850\/revisions"}],"predecessor-version":[{"id":2878,"href":"https:\/\/www.cloudidentity.com\/blog\/wp-json\/wp\/v2\/posts\/2850\/revisions\/2878"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.cloudidentity.com\/blog\/wp-json\/wp\/v2\/media\/2853"}],"wp:attachment":[{"href":"https:\/\/www.cloudidentity.com\/blog\/wp-json\/wp\/v2\/media?parent=2850"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.cloudidentity.com\/blog\/wp-json\/wp\/v2\/categories?post=2850"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.cloudidentity.com\/blog\/wp-json\/wp\/v2\/tags?post=2850"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}