Skip to content

Commit b193f44

Browse files
Merge pull request #44561 from dotnet/main
Merge main into live
2 parents d44c248 + b0547e1 commit b193f44

File tree

117 files changed

+1918
-340
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

117 files changed

+1918
-340
lines changed

.github/workflows/live-protection.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ permissions:
66

77
jobs:
88
live_protection_job:
9-
name: Create comment
9+
name: Check base branch
1010
runs-on: ubuntu-latest
1111

1212
steps:

.github/workflows/scorecards.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,6 @@ jobs:
7171

7272
# Upload the results to GitHub's code scanning dashboard.
7373
- name: "Upload to code-scanning"
74-
uses: github/codeql-action/upload-sarif@d68b2d4edb4189fd2a5366ac14e72027bd4b37dd # v3.28.2
74+
uses: github/codeql-action/upload-sarif@17a820bf2e43b47be2c72b39cc905417bc1ab6d0 # v3.28.6
7575
with:
7676
sarif_file: results.sarif

.openpublishing.redirection.azure.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,10 @@
123123
{
124124
"source_path_from_root": "/docs/azure/sdk/azure-sdk-configure-proxy.md",
125125
"redirect_url": "/dotnet/azure/sdk/configure-proxy"
126+
},
127+
{
128+
"source_path_from_root": "/docs/azure/sdk/authentication/authentication-best-practices.md",
129+
"redirect_url": "/dotnet/azure/sdk/authentication/best-practices"
126130
}
127131
]
128132
}

.openpublishing.redirection.core.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -338,6 +338,10 @@
338338
"redirect_url": "/dotnet/core/compatibility/sdk/5.0/sdk-and-target-framework-change",
339339
"redirect_document_id": true
340340
},
341+
{
342+
"source_path_from_root": "/docs/core/compatibility/windows-forms/8.0/anchor-layout.md",
343+
"redirect_url": "/dotnet/core/compatibility/8.0"
344+
},
341345
{
342346
"source_path_from_root": "/docs/core/deploying/applications.md",
343347
"redirect_url": "/dotnet/core/deploying/index"

docfx.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -475,7 +475,6 @@
475475
"docs/standard/collections/**/**.md": "dapine",
476476
"docs/standard/commandline/**/**.md": "tdykstra",
477477
"docs/standard/data/**/**.md": "gewarren",
478-
"docs/standard/data/sqlite/**/**.md": "avickers",
479478
"docs/standard/datetime/**/**.md": "adegeo",
480479
"docs/standard/design-guidelines/**/**.md": "kcwalina",
481480
"docs/standard/events/**/**.md": "dapine",

docs/ai/how-to/app-service-aoai-auth.md

Lines changed: 57 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,30 @@
11
---
2-
title: "Authenticate and Authorize App Service to Azure OpenAI using Microsoft Entra and the Semantic Kernel SDK"
3-
description: "Learn how to authenticate and authorize your app service application to an Azure OpenAI resource by using Microsoft Entra managed identities and the Semantic Kernel SDK for .NET."
2+
title: "Authenticate an Azure hosted .NET app to Azure OpenAI using Microsoft Entra ID"
3+
description: "Learn how to authenticate your Azure hosted .NET app to an Azure OpenAI resource using Microsoft Entra ID."
44
author: haywoodsloan
55
ms.topic: how-to
66
ms.custom: devx-track-azurecli
7-
ms.date: 11/24/2024
7+
ms.date: 01/29/2025
88
zone_pivot_groups: azure-interface
99
#customer intent: As a .NET developer, I want authenticate and authorize my App Service to Azure OpenAI by using Microsoft Entra so that I can securely use AI in my .NET application.
1010
---
1111

12-
# Authenticate an AI app hosted on Azure App Service to Azure OpenAI using Microsoft Entra ID
12+
# Authenticate to Azure OpenAI from an Azure hosted app using Microsoft Entra ID
1313

14-
This article demonstrates how to use [Microsoft Entra ID managed identities](/azure/app-service/overview-managed-identity) to authenticate and authorize an App Service application to an Azure OpenAI resource.
14+
This article demonstrates how to use [Microsoft Entra ID managed identities](/azure/app-service/overview-managed-identity) and the [Microsoft.Extensions.AI library](/dotnet/ai/ai-extensions) to authenticate an Azure hosted app to an Azure OpenAI resource.
1515

16-
This article also demonstrates how to use the [Semantic Kernel SDK](/semantic-kernel/overview) to easily implement Microsoft Entra authentication in your .NET application.
17-
18-
By using a managed identity from Microsoft Entra, your App Service application can easily access protected Azure OpenAI resources without having to manually provision or rotate any secrets.
16+
A managed identity from Microsoft Entra ID allows your app to easily access other Microsoft Entra protected resources such as Azure OpenAI. The identity is managed by the Azure platform and doesn't require you to provision, manage, or rotate any secrets.
1917

2018
## Prerequisites
2119

2220
* An Azure account that has an active subscription. [Create an account for free](https://azure.microsoft.com/free/?WT.mc_id=A261C142F).
2321
* [.NET SDK](https://dotnet.microsoft.com/download/visual-studio-sdks)
24-
* [`Microsoft.SemanticKernel` NuGet package](https://www.nuget.org/packages/Microsoft.SemanticKernel)
25-
* [`Azure.Identity` NuGet package](https://www.nuget.org/packages/Azure.Identity)
2622
* [Create and deploy an Azure OpenAI Service resource](/azure/ai-services/openai/how-to/create-resource)
2723
* [Create and deploy a .NET application to App Service](/azure/app-service/quickstart-dotnetcore)
2824

2925
## Add a managed identity to App Service
3026

31-
Your application can be granted two types of identities:
27+
Managed identities provide an automatically managed identity in Microsoft Entra ID for applications to use when connecting to resources that support Microsoft Entra authentication. Applications can use managed identities to obtain Microsoft Entra tokens without having to manage any credentials. Your application can be assigned two types of identities:
3228

3329
* A **system-assigned identity** is tied to your application and is deleted if your app is deleted. An app can have only one system-assigned identity.
3430
* A **user-assigned identity** is a standalone Azure resource that can be assigned to your app. An app can have multiple user-assigned identities.
@@ -41,6 +37,11 @@ Your application can be granted two types of identities:
4137
1. Select **Identity**.
4238
1. On the **System assigned** tab, toggle *Status* to **On**, and then select **Save**.
4339

40+
:::image type="content" source="../media/azure-hosted-apps/system-assigned-managed-identity-in-azure-portal.png" alt-text="A screenshot showing how to add a system assigned managed identity to an app.":::
41+
42+
> [!NOTE]
43+
> The preceding screenshot demonstrates this process on an Azure App Service, but the steps are similar on other hosts such as Azure Container Apps.
44+
4445
## [User-assigned](#tab/user-assigned)
4546

4647
To add a user-assigned identity to your app, create the identity, and then add its resource identifier to your app config.
@@ -54,6 +55,11 @@ To add a user-assigned identity to your app, create the identity, and then add i
5455
> [!IMPORTANT]
5556
> After you select **Add**, the app restarts.
5657
58+
:::image type="content" source="../media/azure-hosted-apps/user-assigned-managed-identity-in-azure-portal.png" alt-text="A screenshot showing how to add a system assigned managed identity to an app.":::
59+
60+
> [!NOTE]
61+
> The preceding screenshot demonstrates this process on an Azure App Service, but the steps are similar on other hosts such as Azure Container Apps.
62+
5763
---
5864

5965
:::zone-end
@@ -86,13 +92,16 @@ az webapp identity assign --name <appName> --resource-group <groupName>
8692
8793
:::zone-end
8894
89-
## Add an Azure OpenAI user role to your managed identity
95+
## Add an Azure OpenAI user role to the identity
9096
9197
:::zone target="docs" pivot="azure-portal"
9298
9399
1. In the [Azure Portal](https://aka.ms/azureportal), navigate to the scope that you want to grant **Azure OpenAI** access to. The scope can be a **Management group**, **Subscription**, **Resource group**, or a specific **Azure OpenAI** resource.
94100
1. In the left navigation pane, select **Access control (IAM)**.
95101
1. Select **Add**, then select **Add role assignment**.
102+
103+
:::image type="content" source="../media/azure-hosted-apps/add-entra-role.png" alt-text="A screenshot showing how to add an RBAC role.":::
104+
96105
1. On the **Role** tab, select the **Cognitive Services OpenAI User** role.
97106
1. On the **Members** tab, select the managed identity.
98107
1. On the **Review + assign** tab, select **Review + assign** to assign the role.
@@ -101,53 +110,78 @@ az webapp identity assign --name <appName> --resource-group <groupName>
101110
102111
:::zone target="docs" pivot="azure-cli"
103112
104-
**Resource scope**
113+
You can use the Azure CLI to assign the Cognitive Services OpenAI User role to your managed identity at varying scopes.
114+
115+
# [Resource](#tab/resource)
105116
106117
```azurecli
107118
az role assignment create --assignee "<managedIdentityObjectID>" \
108119
--role "Cognitive Services OpenAI User" \
109120
--scope "/subscriptions/<subscriptionId>/resourcegroups/<resourceGroupName>/providers/<providerName>/<resourceType>/<resourceSubType>/<resourceName>"
110121
```
111122

112-
**Resource group scope**
123+
# [Resource group](#tab/resource-group)
113124

114125
```azurecli
115126
az role assignment create --assignee "<managedIdentityObjectID>" \
116127
--role "Cognitive Services OpenAI User" \
117128
--scope "/subscriptions/<subscriptionId>/resourcegroups/<resourceGroupName>"
118129
```
119130

120-
**Subscription scope**
131+
# [Subscription](#tab/subscription)
121132

122133
```azurecli
123134
az role assignment create --assignee "<managedIdentityObjectID>" \
124135
--role "Cognitive Services OpenAI User" \
125136
--scope "/subscriptions/<subscriptionId>"
126137
```
127138

128-
**Management group scope**
139+
# [Management group](#tab/management-group)
129140

130141
```azurecli
131142
az role assignment create --assignee "<managedIdentityObjectID>" \
132143
--role "Cognitive Services OpenAI User" \
133144
--scope "/providers/Microsoft.Management/managementGroups/<managementGroupName>"
134145
```
135146

147+
---
148+
136149
:::zone-end
137150

138-
## Implement token-based authentication using Semantic Kernel SDK
151+
## Implement identity authentication in your app code
152+
153+
1. Add the following NuGet packages to your app:
154+
155+
```dotnetcli
156+
dotnet add package Azure.Identity
157+
dotnet add package Azure.AI.OpenAI
158+
dotnet add package Microsoft.Extensions.Azure
159+
dotnet add package Microsoft.Extensions.AI
160+
dotnet add package Microsoft.Extensions.AI.OpenAI
161+
```
162+
163+
The preceding packages each handle the following concerns for this scenario:
164+
165+
- **[Azure.Identity](https://www.nuget.org/packages/Azure.Identity)**: Provides core functionality to work with Microsoft Entra ID
166+
- **[Azure.AI.OpenAI](https://www.nuget.org/packages/Azure.AI.OpenAI)**: Enables your app to interface with the Azure OpenAI service
167+
- **[Microsoft.Extensions.Azure](https://www.nuget.org/packages/Microsoft.Extensions.Azure)**: Provides helper extensions to register services for dependency injection
168+
- **[Microsoft.Extensions.AI](https://www.nuget.org/packages/Microsoft.Extensions.AI)**: Provides AI abstractions for common AI tasks
169+
- **[Microsoft.Extensions.AI.OpenAI](https://www.nuget.org/packages/Microsoft.Extensions.AI.OpenAI)**: Enables you to use OpenAI service types as AI abstractions provided by **Microsoft.Extensions.AI**
170+
171+
1. In the `Program.cs` file of your app, create a `DefaultAzureCredential` object to discover and configure available credentials:
139172
140-
1. Initialize a `DefaultAzureCredential` object to assume your app's managed identity:
173+
:::code language="csharp" source="./snippets/hosted-app-auth/program.cs" range="13-22":::
141174
142-
:::code language="csharp" source="./snippets/semantic-kernel/IdentityExamples.cs" id="tokenCredential":::
175+
1. Create an AI service and register it with the service collection:
143176
144-
1. Build a `Kernel` object that includes the Azure OpenAI Chat Completion Service, and use the previously created credentials:
177+
:::code language="csharp" source="./snippets/hosted-app-auth/program.cs" range="24-30":::
145178
146-
:::code language="csharp" source="./snippets/semantic-kernel/IdentityExamples.cs" id="kernelBuild":::
179+
1. Inject the registered service for use in your endpoints:
147180
148-
1. Use the `Kernel` object to invoke prompt completion through Azure OpenAI:
181+
:::code language="csharp" source="./snippets/hosted-app-auth/program.cs" range="41-46":::
149182
150-
:::code language="csharp" source="./snippets/semantic-kernel/IdentityExamples.cs" id="invokePrompt":::
183+
> [!TIP]
184+
> Learn more about ASP.NET Core dependency injection and how to register other AI services types in the Azure SDK for .NET [dependency injection](/dotnet/azure/sdk/dependency-injection) documentation.
151185
152186
## Related content
153187
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
using Azure.AI.OpenAI;
2+
using Azure.Identity;
3+
using Microsoft.Extensions.AI;
4+
using Microsoft.Extensions.Azure;
5+
6+
var builder = WebApplication.CreateBuilder(args);
7+
8+
// Add services to the container
9+
// Learn more about configuring OpenAPI at https://aka.ms/aspnet/openapi
10+
builder.Services.AddOpenApi();
11+
12+
// DefaultAzureCredential attempts several auth flows in order until one is available
13+
// For example, will discover Visual Studio or Azure CLI credentials
14+
// in local environments and managed identity credentials in production deployments
15+
var credential = new DefaultAzureCredential(
16+
new DefaultAzureCredentialOptions
17+
{
18+
// If necessary, specify the tenant ID,
19+
// user-assigned identity client or resource ID, or other options
20+
}
21+
);
22+
23+
// Retrieve the Azure OpenAI endpoint and deployment name
24+
string endpoint = builder.Configuration["AZURE_OPENAI_ENDPOINT"];
25+
string deployment = builder.Configuration["AZURE_OPENAI_GPT_NAME"];
26+
27+
builder.Services.AddChatClient(
28+
new AzureOpenAIClient(new Uri(endpoint), credential)
29+
.AsChatClient(deployment));
30+
31+
var app = builder.Build();
32+
33+
// Configure the HTTP request pipeline.
34+
if (app.Environment.IsDevelopment())
35+
{
36+
app.MapOpenApi();
37+
}
38+
39+
app.UseHttpsRedirection();
40+
41+
app.MapGet("/test-prompt", async (IChatClient chatClient) =>
42+
{
43+
return await chatClient.CompleteAsync("Test prompt", new ChatOptions());
44+
})
45+
.WithName("Test prompt");
46+
47+
app.Run();
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
{
2+
"$schema": "https://json.schemastore.org/launchsettings.json",
3+
"profiles": {
4+
"http": {
5+
"commandName": "Project",
6+
"dotnetRunMessages": true,
7+
"launchBrowser": false,
8+
"applicationUrl": "http://localhost:5140",
9+
"environmentVariables": {
10+
"ASPNETCORE_ENVIRONMENT": "Development"
11+
}
12+
},
13+
"https": {
14+
"commandName": "Project",
15+
"dotnetRunMessages": true,
16+
"launchBrowser": false,
17+
"applicationUrl": "https://localhost:7137;http://localhost:5140",
18+
"environmentVariables": {
19+
"ASPNETCORE_ENVIRONMENT": "Development"
20+
}
21+
}
22+
}
23+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{
2+
"Logging": {
3+
"LogLevel": {
4+
"Default": "Information",
5+
"Microsoft.AspNetCore": "Warning"
6+
}
7+
},
8+
"AZURE_OPENAI_ENDPOINT": "your-azure-openai-endpoint",
9+
"AZURE_OPENAI_GPT_NAME": "your-azure-openai-deployment-name"
10+
}

0 commit comments

Comments
 (0)