Skip to content

Commit e373aa6

Browse files
alexwolfmsftchristothesscottaddie
authored
Add Interactive brokered authentication and wam content (#42279)
Added brokered auth content Co-authored-by: Christopher Scott <[email protected]> --------- Co-authored-by: Christopher Scott <[email protected]> Co-authored-by: Scott Addie <[email protected]>
1 parent 28bd717 commit e373aa6

15 files changed

+805
-31
lines changed

docs/azure/sdk/authentication/additional-methods.md

Lines changed: 81 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -16,25 +16,92 @@ This method interactively authenticates an application through [`InteractiveBrow
1616

1717
Interactive browser authentication enables the application for all operations allowed by the interactive login credentials. As a result, if you're the owner or administrator of your subscription, your code has inherent access to most resources in that subscription without having to assign any specific permissions. For this reason, the use of interactive browser authentication is discouraged for anything but experimentation.
1818

19+
### Enable applications for interactive browser authentication
20+
21+
Perform the following steps to enable the application to authenticate through the interactive browser flow. These steps also work for the [device code authentication](#device-code-authentication) flow described later. This process is only necessary if you are using `InteractiveBrowserCredential` in your code.
22+
23+
1. In the [Azure portal](https://portal.azure.com), navigate to **Microsoft Entra ID** and select **App registrations** on the left navigation.
24+
1. Select the registration for your app, then select **Authentication**.
25+
1. Under **Advanced settings**, select **Yes** for **Allow public client flows**.
26+
1. Select **Save** to apply the changes.
27+
1. To authorize the application for specific resources, navigate to the resource in question, select **API Permissions**, and enable **Microsoft Graph** and other resources you want to access. Microsoft Graph is usually enabled by default.
28+
29+
> [!IMPORTANT]
30+
> You must also be the admin of your tenant to grant consent to your application when you sign in for the first time.
31+
1932
### Example using InteractiveBrowserCredential
2033

2134
The following example demonstrates using an [`InteractiveBrowserCredential`](/dotnet/api/azure.identity.interactivebrowsercredential) to authenticate with the [`BlobServiceClient`](/dotnet/api/azure.storage.blobs.blobserviceclient):
2235

23-
```csharp
24-
using Azure.Identity;
25-
using Azure.Storage.Blobs;
36+
:::code language="csharp" source="../snippets/additional-auth/interactive/InteractiveBrowserAuth.cs" highlight="15-17":::
2637

27-
var client = new BlobServiceClient(
28-
new Uri("https://<storage-account-name>.blob.core.windows.net"),
29-
new InteractiveBrowserCredential());
38+
For more exact control, such as setting redirect URIs, you can supply specific arguments to `InteractiveBrowserCredential` such as `redirect_uri`.
3039

31-
foreach (var blobItem in client.GetBlobContainers())
32-
{
33-
Console.WriteLine(blobItem.Name);
34-
}
35-
```
40+
## Interactive brokered authentication
3641

37-
For more exact control, such as setting redirect URIs, you can supply specific arguments to `InteractiveBrowserCredential` such as `redirect_uri`.
42+
This method interactively authenticates an application through [`InteractiveBrowserCredential`](/dotnet/api/azure.identity.interactivebrowsercredential?view=azure-dotnet) by collecting user credentials using the system authentication broker. A system authentication broker is an app running on a user's machine that manages the authentication handshakes and token maintenance for all connected accounts. Currently, only the Windows authentication broker, Web Account Manager (WAM), is supported. Users on macOS and Linux will be authenticated through the non-brokered interactive browser flow.
43+
44+
WAM enables identity providers such as Microsoft Entra ID to natively plug into the OS and provide the service to other apps to provide a more secure login process. WAM offers the following benefits:
45+
46+
- **Feature support**: Apps can access OS-level and service-level capabilities, including Windows Hello, conditional access policies, and FIDO keys.
47+
- **Streamlined single sign-on**: Apps can use the built-in account picker, allowing the user to select an existing account instead of repeatedly entering the same credentials.
48+
- **Enhanced security**: Bug fixes and enhancements ship with Windows.
49+
- **Token protection**: Refresh tokens are device-bound, and apps can acquire device-bound access tokens.
50+
51+
Interactive brokered authentication enables the application for all operations allowed by the interactive login credentials. Personal Microsoft accounts and work or school accounts are supported. If a supported version of Windows is used, the default browser-based UI is replaced with a smoother authentication experience, similar to Windows built-in apps.
52+
53+
### Enable applications for interactive brokered authentication
54+
55+
Perform the following steps to enable the application to authenticate through the interactive broker flow.
56+
57+
1. On the [Azure portal](https://portal.azure.com), navigate to **Microsoft Entra ID** and select **App registrations** on the left-hand menu.
58+
1. Select the registration for your app, then select **Authentication**.
59+
1. Add the WAM redirect URI to your app registration via a platform configuration:
60+
1. Under **Platform configurations**, select **+ Add a platform**.
61+
1. Under **Configure platforms**, select the tile for your application type (platform) to configure its settings, such as **mobile and desktop applications**.
62+
1. In **Custom redirect URIs**, enter the following WAM redirect URI:
63+
64+
```text
65+
ms-appx-web://microsoft.aad.brokerplugin/{client_id}
66+
```
67+
68+
The `{client_id}` placeholder must be replaced with the **Application (client) ID** listed on the **Overview** pane of the app registration.
69+
70+
1. Select **Configure**.
71+
72+
To learn more, see [Add a redirect URI to an app registration](/entra/identity-platform/quickstart-register-app#add-a-redirect-uri).
73+
74+
1. Back on the **Authentication** pane, under **Advanced settings**, select **Yes** for **Allow public client flows**.
75+
1. Select **Save** to apply the changes.
76+
1. To authorize the application for specific resources, navigate to the resource in question, select **API Permissions**, and enable **Microsoft Graph** and other resources you want to access. Microsoft Graph is usually enabled by default.
77+
78+
> [!IMPORTANT]
79+
> You must also be the admin of your tenant to grant consent to your application when you sign in for the first time.
80+
81+
### Example using InteractiveBrowserCredential
82+
83+
The following example demonstrates using an [`InteractiveBrowserCredential`](/dotnet/api/azure.identity.interactivebrowsercredential?view=azure-dotnet) in a Windows Forms app to authenticate with the [`BlobServiceClient`](/dotnet/api/azure.storage.blobs.blobserviceclient):
84+
85+
:::code language="csharp" source="../snippets/additional-auth/interactive/InteractiveBrokeredAuth.cs" highlight="16-20":::
86+
87+
> [!NOTE]
88+
> Visit the [Parent window handles](/entra/msal/dotnet/acquiring-tokens/desktop-mobile/wam#parent-window-handles) and [Retrieve a window handle](/windows/apps/develop/ui-input/retrieve-hwnd) articles for more information about retrieving window handles.
89+
90+
For the code to run successfully, your user account must be assigned an Azure role on the storage account that allows access to blob containers such as **Storage Account Data Contributor**. If an app is specified, it must have API permissions set for **user_impersonation Access Azure Storage** (step 6 in the previous section). This API permission allows the app to access Azure storage on behalf of the signed-in user after consent is granted during sign-in.
91+
92+
The following screenshot shows the user sign-in experience:
93+
94+
:::image type="content" source="../media/web-account-manager-sign-in-account-picker.png" alt-text="A screenshot that shows the sign-in experience when using the interactive browser broker credential to authenticate a user." :::
95+
96+
### Authenticate the default system account via WAM
97+
98+
Many people always sign in to Windows with the same user account and, therefore, only ever want to authenticate using that account. WAM and `InteractiveBrowserCredential` also support a silent login process that automatically uses a default account so the user doesn't have to repeatedly select it.
99+
100+
The following example shows how to enable sign-in with the default system account:
101+
102+
:::code language="csharp" source="../snippets/additional-auth/interactive/SilentBrokeredAuth.cs" highlight="16-24":::
103+
104+
Once you opt into this behavior, the credential 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 falls back to displaying the account picker dialog, from which the user can select the appropriate account.
38105
39106
## Device code authentication
40107
@@ -49,7 +116,7 @@ For more information, see [Microsoft identity platform and the OAuth 2.0 device
49116
50117
Device code authentication in a development environment enables the application for all operations allowed by the interactive login credentials. As a result, if you're the owner or administrator of your subscription, your code has inherent access to most resources in that subscription without having to assign any specific permissions. However, you can use this method with a specific client ID, rather than the default, for which you can assign specific permissions.
51118
52-
## Authentication with a username and password
119+
## Username and password authentication
53120
54121
This method authenticates an application using previously collected credentials and the [UsernamePasswordCredential](/dotnet/api/azure.identity.usernamepasswordcredential) object.
55122
@@ -58,21 +125,4 @@ This method authenticates an application using previously collected credentials
58125
>
59126
> Furthermore, this method authenticates only work and school accounts; Microsoft accounts aren't supported. For more information, see [Sign up your organization to use Microsoft Entra ID](/entra/fundamentals/sign-up-organization).
60127
61-
```csharp
62-
using Azure.Identity;
63-
using Azure.Storage.Blobs;
64-
65-
var clientId = Environment.GetEnvironmentVariable("AZURE_CLIENT_ID");
66-
var tenantId = Environment.GetEnvironmentVariable("AZURE_TENANT_ID");
67-
var username = Environment.GetEnvironmentVariable("AZURE_USERNAME");
68-
var password = Environment.GetEnvironmentVariable("AZURE_PASSWORD");
69-
70-
var client = new BlobServiceClient(
71-
new Uri("https://<storage-account-name>.blob.core.windows.net"),
72-
new UsernamePasswordCredential(username, password, tenantId, clientId));
73-
74-
foreach (var blobItem in client.GetBlobContainers())
75-
{
76-
Console.WriteLine(blobItem.Name);
77-
}
78-
```
128+
:::code language="csharp" source="../snippets/additional-auth/username-password/Program.cs" highlight="9-11":::
200 KB
Loading

docs/azure/sdk/snippets/additional-auth/interactive/InteractiveBrokeredAuth.Designer.cs

Lines changed: 59 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
using Azure.Identity;
2+
using Azure.Identity.Broker;
3+
using Azure.Storage.Blobs;
4+
5+
namespace InteractiveBrokeredAuthSample
6+
{
7+
public partial class InteractiveBrokeredAuth : Form
8+
{
9+
public InteractiveBrokeredAuth()
10+
{
11+
InitializeComponent();
12+
}
13+
14+
private void testInteractiveBrokeredAuth_Click(object sender, EventArgs e)
15+
{
16+
// Get the handle of the current window
17+
IntPtr windowHandle = this.Handle;
18+
19+
var credential = new InteractiveBrowserCredential(
20+
new InteractiveBrowserCredentialBrokerOptions(windowHandle));
21+
22+
// To authenticate and authorize with an Entra ID app registration, substitute the
23+
// <app_id> and <tenant_id> placeholders with the values for your app and tenant.
24+
// var credential = new InteractiveBrowserCredential(
25+
// new InteractiveBrowserCredentialBrokerOptions(windowHandle)
26+
// {
27+
// TenantId = "your-tenant-id",
28+
// ClientId = "your-client-id"
29+
// }
30+
// );
31+
32+
var client = new BlobServiceClient(
33+
new Uri("https://<storage-account-name>.blob.core.windows.net/"),
34+
credential
35+
);
36+
37+
// Prompt for credentials appears on first use of the client
38+
foreach (var container in client.GetBlobContainers())
39+
{
40+
Console.WriteLine(container.Name);
41+
}
42+
}
43+
}
44+
}
Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<root>
3+
<!--
4+
Microsoft ResX Schema
5+
6+
Version 2.0
7+
8+
The primary goals of this format is to allow a simple XML format
9+
that is mostly human readable. The generation and parsing of the
10+
various data types are done through the TypeConverter classes
11+
associated with the data types.
12+
13+
Example:
14+
15+
... ado.net/XML headers & schema ...
16+
<resheader name="resmimetype">text/microsoft-resx</resheader>
17+
<resheader name="version">2.0</resheader>
18+
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
19+
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
20+
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
21+
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
22+
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
23+
<value>[base64 mime encoded serialized .NET Framework object]</value>
24+
</data>
25+
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
26+
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
27+
<comment>This is a comment</comment>
28+
</data>
29+
30+
There are any number of "resheader" rows that contain simple
31+
name/value pairs.
32+
33+
Each data row contains a name, and value. The row also contains a
34+
type or mimetype. Type corresponds to a .NET class that support
35+
text/value conversion through the TypeConverter architecture.
36+
Classes that don't support this are serialized and stored with the
37+
mimetype set.
38+
39+
The mimetype is used for serialized objects, and tells the
40+
ResXResourceReader how to depersist the object. This is currently not
41+
extensible. For a given mimetype the value must be set accordingly:
42+
43+
Note - application/x-microsoft.net.object.binary.base64 is the format
44+
that the ResXResourceWriter will generate, however the reader can
45+
read any of the formats listed below.
46+
47+
mimetype: application/x-microsoft.net.object.binary.base64
48+
value : The object must be serialized with
49+
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
50+
: and then encoded with base64 encoding.
51+
52+
mimetype: application/x-microsoft.net.object.soap.base64
53+
value : The object must be serialized with
54+
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
55+
: and then encoded with base64 encoding.
56+
57+
mimetype: application/x-microsoft.net.object.bytearray.base64
58+
value : The object must be serialized into a byte array
59+
: using a System.ComponentModel.TypeConverter
60+
: and then encoded with base64 encoding.
61+
-->
62+
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
63+
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
64+
<xsd:element name="root" msdata:IsDataSet="true">
65+
<xsd:complexType>
66+
<xsd:choice maxOccurs="unbounded">
67+
<xsd:element name="metadata">
68+
<xsd:complexType>
69+
<xsd:sequence>
70+
<xsd:element name="value" type="xsd:string" minOccurs="0" />
71+
</xsd:sequence>
72+
<xsd:attribute name="name" use="required" type="xsd:string" />
73+
<xsd:attribute name="type" type="xsd:string" />
74+
<xsd:attribute name="mimetype" type="xsd:string" />
75+
<xsd:attribute ref="xml:space" />
76+
</xsd:complexType>
77+
</xsd:element>
78+
<xsd:element name="assembly">
79+
<xsd:complexType>
80+
<xsd:attribute name="alias" type="xsd:string" />
81+
<xsd:attribute name="name" type="xsd:string" />
82+
</xsd:complexType>
83+
</xsd:element>
84+
<xsd:element name="data">
85+
<xsd:complexType>
86+
<xsd:sequence>
87+
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
88+
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
89+
</xsd:sequence>
90+
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
91+
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
92+
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
93+
<xsd:attribute ref="xml:space" />
94+
</xsd:complexType>
95+
</xsd:element>
96+
<xsd:element name="resheader">
97+
<xsd:complexType>
98+
<xsd:sequence>
99+
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
100+
</xsd:sequence>
101+
<xsd:attribute name="name" type="xsd:string" use="required" />
102+
</xsd:complexType>
103+
</xsd:element>
104+
</xsd:choice>
105+
</xsd:complexType>
106+
</xsd:element>
107+
</xsd:schema>
108+
<resheader name="resmimetype">
109+
<value>text/microsoft-resx</value>
110+
</resheader>
111+
<resheader name="version">
112+
<value>2.0</value>
113+
</resheader>
114+
<resheader name="reader">
115+
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
116+
</resheader>
117+
<resheader name="writer">
118+
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
119+
</resheader>
120+
</root>
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<OutputType>WinExe</OutputType>
5+
<TargetFramework>net8.0-windows</TargetFramework>
6+
<Nullable>enable</Nullable>
7+
<UseWindowsForms>true</UseWindowsForms>
8+
<ImplicitUsings>enable</ImplicitUsings>
9+
</PropertyGroup>
10+
11+
<ItemGroup>
12+
<PackageReference Include="Azure.Identity" Version="1.12.0" />
13+
<PackageReference Include="Azure.Identity.Broker" Version="1.1.0" />
14+
<PackageReference Include="Azure.Storage.Blobs" Version="12.21.2" />
15+
</ItemGroup>
16+
17+
</Project>

0 commit comments

Comments
 (0)