{"id":3016,"date":"2024-04-10T14:46:44","date_gmt":"2024-04-10T21:46:44","guid":{"rendered":"https:\/\/devblogs.microsoft.com\/azure-sdk\/?p=3016"},"modified":"2024-04-10T14:46:44","modified_gmt":"2024-04-10T21:46:44","slug":"silent-brokered-authentication-on-windows-with-the-azure-identity-libraries","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/azure-sdk\/silent-brokered-authentication-on-windows-with-the-azure-identity-libraries\/","title":{"rendered":"Silent, brokered authentication on Windows with the Azure Identity libraries"},"content":{"rendered":"<p>As <a href=\"https:\/\/devblogs.microsoft.com\/azure-sdk\/wham-authentication-broker-support-lands-in-the-azure-identity-libraries\/\">previously announced<\/a> in December 2023, the Azure Identity client libraries for .NET, Java, JavaScript, and Python include support for Web Account Manager (WAM). To recap, WAM:<\/p>\n<ul>\n<li>Is the system authentication broker for Windows.<\/li>\n<li>Offers a secure approach to acquire and refresh tokens issued by Microsoft Entra ID.<\/li>\n<li>Can be used via the .NET, Java, and JavaScript libraries&#8217; <code>InteractiveBrowserCredential<\/code> type; for Python, the <code>InteractiveBrowserBrokerCredential<\/code> type is used.<\/li>\n<\/ul>\n<p>The team reflected on the existing authentication experience\u2014more specifically, the possibility of suppressing the modal account picker dialog that supports interactively logging in. There are, after all, many customers who always sign into Windows with the same default user account and therefore only ever want to authenticate using that account. Forcing this cohort to repeatedly select their sole account from an account picker is aggravating.<\/p>\n<p>Today, we&#8217;re pleased to announce that silently authenticating the platform-specific default account via WAM is possible.<\/p>\n<h2>Authenticate the default system account via WAM<\/h2>\n<p>You can opt into attempting to sign in automatically with whatever the broker thinks is the default system account. In the context of Windows, that default system account is the signed-in user. As a prerequisite, use a version of the broker package that supports this feature.<\/p>\n<table>\n<thead>\n<tr>\n<th>Ecosystem<\/th>\n<th>Package<\/th>\n<th>Minimum package version<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>.NET<\/td>\n<td><a href=\"https:\/\/www.nuget.org\/packages\/Azure.Identity.Broker\">Azure.Identity.Broker<\/a><\/td>\n<td>1.1.0<\/td>\n<\/tr>\n<tr>\n<td>Java<\/td>\n<td><a href=\"https:\/\/central.sonatype.com\/artifact\/com.azure\/azure-identity-broker\">azure-identity-broker<\/a><\/td>\n<td>1.1.0<\/td>\n<\/tr>\n<tr>\n<td>JavaScript<\/td>\n<td><a href=\"https:\/\/www.npmjs.com\/package\/@azure\/identity-broker\">@azure\/identity-broker<\/a><\/td>\n<td>1.0.0\u2020<\/td>\n<\/tr>\n<tr>\n<td>Python<\/td>\n<td><a href=\"https:\/\/pypi.org\/project\/azure-identity-broker\/\">azure-identity-broker<\/a><\/td>\n<td>1.1.0<\/td>\n<\/tr>\n<\/tbody>\n<tfoot>\n<tr>\n<td colspan=\"3\">\u2020 <span style=\"font-size: 10pt;\">For JavaScript, update your <a href=\"https:\/\/www.npmjs.com\/package\/@azure\/identity\">@azure\/identity<\/a> dependency to version 4.1.0 or later. There&#8217;s no need to update the broker package to use this feature.<\/span><\/td>\n<\/tr>\n<\/tfoot>\n<\/table>\n<p>To opt in, see the ecosystem-specific guidance in the following sections.<\/p>\n<h3><span style=\"font-size: 14pt;\">.NET<\/span><\/h3>\n<p>Set <a href=\"https:\/\/learn.microsoft.com\/dotnet\/api\/azure.identity.broker.interactivebrowsercredentialbrokeroptions?view=azure-dotnet\">InteractiveBrowserCredentialBrokerOptions<\/a>&#8216; <code>UseDefaultBrokerAccount<\/code> property to <code>true<\/code>:<\/p>\n<pre><code class=\"language-csharp\">using Azure.Identity;\r\nusing Azure.Identity.Broker;\r\n\r\n\/\/ code omitted for brevity\r\n\r\nIntPtr windowHandle = GetForegroundWindow();\r\nInteractiveBrowserCredential credential = new(\r\n    new InteractiveBrowserCredentialBrokerOptions(windowHandle)\r\n    {\r\n        UseDefaultBrokerAccount = true,\r\n    });\r\n);<\/code><\/pre>\n<h3><span style=\"font-size: 14pt;\">Java<\/span><\/h3>\n<p>Invoke the <code>useDefaultBrokerAccount<\/code> method on the <a href=\"https:\/\/learn.microsoft.com\/java\/api\/com.azure.identity.broker.interactivebrowserbrokercredentialbuilder?view=azure-java-stable\">InteractiveBrowserBrokerCredentialBuilder<\/a> object:<\/p>\n<pre><code class=\"language-java\">import com.azure.identity.InteractiveBrowserCredential;\r\nimport com.azure.identity.broker.InteractiveBrowserBrokerCredentialBuilder;\r\n\r\n\/\/ code omitted for brevity\r\n\r\nlong windowHandle = getWindowHandle();\r\nInteractiveBrowserCredential credential = \r\n    new InteractiveBrowserBrokerCredentialBuilder()\r\n        .useDefaultBrokerAccount()\r\n        .setWindowHandle(windowHandle)\r\n        .build();<\/code><\/pre>\n<h3><span style=\"font-size: 14pt;\">JavaScript<\/span><\/h3>\n<p>In the <code>brokerOptions<\/code> object, set the <code>useDefaultBrokerAccount<\/code> property to <code>true<\/code>:<\/p>\n<pre><code class=\"language-javascript\">import { nativeBrokerPlugin } from \"@azure\/identity-broker\";\r\nimport { \r\n    useIdentityPlugin,\r\n    InteractiveBrowserCredential,\r\n} from \"@azure\/identity\";\r\n\r\nuseIdentityPlugin(nativeBrokerPlugin);\r\n\r\n\/\/ code omitted for brevity\r\n\r\nlet windowHandle = getWindowHandle();\r\n\r\nconst credential = new InteractiveBrowserCredential({\r\n    brokerOptions: {\r\n        enabled: true,\r\n        parentWindowHandle: windowHandle,\r\n        useDefaultBrokerAccount: true,\r\n    },\r\n});<\/code><\/pre>\n<h3><span style=\"font-size: 14pt;\">Python<\/span><\/h3>\n<p>Set <a href=\"https:\/\/learn.microsoft.com\/python\/api\/azure-identity-broker\/azure.identity.broker.interactivebrowserbrokercredential?view=azure-python\">InteractiveBrowserBrokerCredential<\/a>&#8216;s <code>use_default_broker_account<\/code> argument to <code>True<\/code>:<\/p>\n<pre><code class=\"language-python\">import win32gui\r\nfrom azure.identity.broker import InteractiveBrowserBrokerCredential\r\n\r\n# code omitted for brevity\r\n\r\nwindow_handle = win32gui.GetForegroundWindow()\r\n\r\ncredential = InteractiveBrowserBrokerCredential(\r\n    parent_window_handle=window_handle,\r\n    use_default_broker_account=True\r\n)<\/code><\/pre>\n<p>Once you opt into this behavior, the credential type attempts to sign in by asking the underlying Microsoft Authentication Library (MSAL) to perform the sign-in for the default system account. If the sign-in fails, the credential type falls back to displaying the account picker dialog, from which the user can select the appropriate account.<\/p>\n<h2>Comparison of authentication experiences<\/h2>\n<p>To better understand the differences in interactive versus silent authentication flows, let&#8217;s enable logging of events emitted only from the Azure Identity library. This logs filtering technique eliminates noise by writing messages only from the <code>Azure-Identity<\/code> event source. Let&#8217;s iterate on <a href=\"https:\/\/devblogs.microsoft.com\/azure-sdk\/wham-authentication-broker-support-lands-in-the-azure-identity-libraries\/#a-net-developers-end-to-end-experience\">the WinForms and C# example<\/a> from the previous blog post:<\/p>\n<pre><code class=\"language-csharp\">using Azure;\r\nusing Azure.Core;\r\nusing Azure.Core.Diagnostics;\r\nusing Azure.Identity;\r\nusing Azure.Identity.Broker;\r\nusing Azure.Monitor.Query;\r\nusing Azure.Monitor.Query.Models;\r\nusing System.Diagnostics.Tracing;\r\n\r\n\/\/ code omitted for brevity\r\n\r\nusing AzureEventSourceListener listener = new((args, message) =&gt;\r\n{\r\n    if (args.EventSource.Name == \"Azure-Identity\")\r\n    {\r\n        Console.WriteLine(message);\r\n    }\r\n}, EventLevel.LogAlways);\r\n\r\nInteractiveBrowserCredential credential = new(\r\n    new InteractiveBrowserCredentialBrokerOptions(windowHandle)\r\n    {\r\n        UseDefaultBrokerAccount = true,\r\n    });\r\n\r\n\/\/ code omitted for brevity\r\n\r\nLogsQueryClient client = new(credential);\r\nResponse&lt;LogsQueryResult&gt; response = await client.QueryResourceAsync(\r\n    new ResourceIdentifier(resourceId), query, QueryTimeRange.All);<\/code><\/pre>\n<p>When the preceding code is run, notice the following excerpt from the logs:<\/p>\n<pre><code>False MSAL 4.56.0.0 MSAL.NetCore .NET 8.0.2 Microsoft Windows 10.0.22631 [2024-04-04 00:20:04Z - 42bcd4c1-0a29-441c-8f89-2e6a37f2d37e] === Token Acquisition (SilentRequest) started:\r\n         Scopes: https:\/\/api.loganalytics.io\/\/.default\r\n        Authority Host: login.microsoftonline.com\r\nFalse MSAL 4.56.0.0 MSAL.NetCore .NET 8.0.2 Microsoft Windows 10.0.22631 [2024-04-04 00:20:04Z - 42bcd4c1-0a29-441c-8f89-2e6a37f2d37e] Broker is configured and enabled, attempting to use broker instead.\r\nFalse MSAL 4.56.0.0 MSAL.NetCore .NET 8.0.2 Microsoft Windows 10.0.22631 [2024-04-04 00:20:04Z] WAM supported OS.\r\nFalse MSAL 4.56.0.0 MSAL.NetCore .NET 8.0.2 Microsoft Windows 10.0.22631 [2024-04-04 00:20:04Z] [RuntimeBroker] WAM supported OS.\r\nFalse MSAL 4.56.0.0 MSAL.NetCore .NET 8.0.2 Microsoft Windows 10.0.22631 [2024-04-04 00:20:05Z - 42bcd4c1-0a29-441c-8f89-2e6a37f2d37e] Can invoke broker. Will attempt to acquire token with broker.\r\n\r\nFalse MSAL 4.56.0.0 MSAL.NetCore .NET 8.0.2 Microsoft Windows 10.0.22631 [2024-04-04 00:20:05Z] [MSAL:0002]     INFO    LogTelemetryData:340    Key: api_name, Value: SignInSilently<\/code><\/pre>\n<p><div class=\"alert alert-success\"><p class=\"alert-divider\"><i class=\"fabric-icon fabric-icon--Lightbulb\"><\/i><strong>View console logs in WinForms app<\/strong><\/p>To view these logs for the WinForms app, open the project&#8217;s <strong>Properties<\/strong> dialog in Visual Studio. Change the <strong>Output type<\/strong> setting from <strong>Windows Application<\/strong> to <strong>Console Application<\/strong>.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/azure-sdk\/wp-content\/uploads\/sites\/58\/2024\/04\/04-09-winforms-output-type.png\" alt=\"WinForms Output type drop-down list in project properties\" \/><\/div><\/p>\n<p>Because the Azure Identity library delegates to the underlying MSAL dependency for its WAM support, MSAL log entries are produced. Notice the <code>(SilentRequest)<\/code> text, indicating that the account picker dialog will be suppressed.<\/p>\n<p>If the <code>UseDefaultBrokerAccount<\/code> property is omitted or set to <code>false<\/code>, a subsequent run reveals the following log entries. Notice the <code>(InteractiveRequest)<\/code> text, indicating that an account picker dialog is necessary to support authentication.<\/p>\n<pre><code>False MSAL 4.56.0.0 MSAL.NetCore .NET 8.0.2 Microsoft Windows 10.0.22631 [2024-04-04 00:04:29Z - 65f48b47-0895-411f-b44b-f5c3d15ec30c] === Token Acquisition (InteractiveRequest) started:\r\n         Scopes: https:\/\/api.loganalytics.io\/\/.default\r\n        Authority Host: login.microsoftonline.com\r\nFalse MSAL 4.56.0.0 MSAL.NetCore .NET 8.0.2 Microsoft Windows 10.0.22631 [2024-04-04 00:04:30Z - 65f48b47-0895-411f-b44b-f5c3d15ec30c] Broker is configured. Starting broker flow without knowing the broker installation app link.\r\nFalse MSAL 4.56.0.0 MSAL.NetCore .NET 8.0.2 Microsoft Windows 10.0.22631 [2024-04-04 00:04:30Z] WAM supported OS.\r\nFalse MSAL 4.56.0.0 MSAL.NetCore .NET 8.0.2 Microsoft Windows 10.0.22631 [2024-04-04 00:04:30Z] [RuntimeBroker] WAM supported OS.\r\nFalse MSAL 4.56.0.0 MSAL.NetCore .NET 8.0.2 Microsoft Windows 10.0.22631 [2024-04-04 00:04:30Z - 65f48b47-0895-411f-b44b-f5c3d15ec30c] Can invoke broker. Will attempt to acquire token with broker.\r\nFalse MSAL 4.56.0.0 MSAL.NetCore .NET 8.0.2 Microsoft Windows 10.0.22631 [2024-04-04 00:04:30Z] [RuntimeBroker] Calling SignInInteractivelyAsync this will show the account picker.<\/code><\/pre>\n<p>Finally, here&#8217;s a video demonstrating the interactive and silent authentication experiences:<\/p>\n<p><div style=\"width: 640px;\" class=\"wp-video\"><video class=\"wp-video-shortcode\" id=\"video-3016-1\" width=\"640\" height=\"360\" preload=\"metadata\" controls=\"controls\"><source type=\"video\/mp4\" src=\"https:\/\/devblogs.microsoft.com\/azure-sdk\/wp-content\/uploads\/sites\/58\/2024\/04\/04-09-wam-flows-1.mp4?_=1\" \/><a href=\"https:\/\/devblogs.microsoft.com\/azure-sdk\/wp-content\/uploads\/sites\/58\/2024\/04\/04-09-wam-flows-1.mp4\">https:\/\/devblogs.microsoft.com\/azure-sdk\/wp-content\/uploads\/sites\/58\/2024\/04\/04-09-wam-flows-1.mp4<\/a><\/video><\/div><\/p>\n<h2>Feedback<\/h2>\n<p>We value your feedback on this new feature. How can we improve upon the existing authentication broker support in the Azure Identity client libraries? Let&#8217;s have those conversations on GitHub at these locations:<\/p>\n<ul>\n<li><a href=\"https:\/\/github.com\/Azure\/azure-sdk-for-net\/issues\">.NET<\/a><\/li>\n<li><a href=\"https:\/\/github.com\/Azure\/azure-sdk-for-java\/issues\">Java<\/a><\/li>\n<li><a href=\"https:\/\/github.com\/Azure\/azure-sdk-for-js\/issues\">JavaScript<\/a><\/li>\n<li><a href=\"https:\/\/github.com\/Azure\/azure-sdk-for-python\/issues\">Python<\/a><\/li>\n<\/ul>\n<p>Ecosystem-specific source code can be found on GitHub at the following locations:<\/p>\n<ul>\n<li><a href=\"https:\/\/github.com\/Azure\/azure-sdk-for-net\/tree\/main\/sdk\/identity\/Azure.Identity.Broker\">.NET<\/a><\/li>\n<li><a href=\"https:\/\/github.com\/Azure\/azure-sdk-for-java\/tree\/main\/sdk\/identity\/azure-identity-broker\">Java<\/a><\/li>\n<li><a href=\"https:\/\/github.com\/Azure\/azure-sdk-for-js\/tree\/main\/sdk\/identity\/identity-broker\">JavaScript<\/a><\/li>\n<li><a href=\"https:\/\/github.com\/Azure\/azure-sdk-for-python\/tree\/main\/sdk\/identity\/azure-identity-broker\">Python<\/a><\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>Learn how to silently authenticate the Windows default system account with the Azure Identity client libraries.<\/p>\n","protected":false},"author":63456,"featured_media":3011,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[701,927,841,750,160,159,162,24],"class_list":["post-3016","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-azure-sdk","tag-net","tag-authentication","tag-azure-identity","tag-azure-sdk","tag-java","tag-javascript","tag-python","tag-releases"],"acf":[],"blog_post_summary":"<p>Learn how to silently authenticate the Windows default system account with the Azure Identity client libraries.<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/azure-sdk\/wp-json\/wp\/v2\/posts\/3016","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/azure-sdk\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/azure-sdk\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/azure-sdk\/wp-json\/wp\/v2\/users\/63456"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/azure-sdk\/wp-json\/wp\/v2\/comments?post=3016"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/azure-sdk\/wp-json\/wp\/v2\/posts\/3016\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/azure-sdk\/wp-json\/wp\/v2\/media\/3011"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/azure-sdk\/wp-json\/wp\/v2\/media?parent=3016"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/azure-sdk\/wp-json\/wp\/v2\/categories?post=3016"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/azure-sdk\/wp-json\/wp\/v2\/tags?post=3016"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}