diff --git a/OpenAI-DotNet.sln b/OpenAI-DotNet.sln
index 85eae7ee..22d9c2ad 100644
--- a/OpenAI-DotNet.sln
+++ b/OpenAI-DotNet.sln
@@ -11,11 +11,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenAI-DotNet-Tests", "Open
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenAI-DotNet-Tests-Proxy", "OpenAI-DotNet-Tests-Proxy\OpenAI-DotNet-Tests-Proxy.csproj", "{F8B5D079-FD33-4A9E-92C4-CC88C911CFF3}"
EndProject
-Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{01FAF825-F72B-4FBD-9CFF-57FDAB089F36}"
- ProjectSection(SolutionItems) = preProject
- Directory.Build.props = Directory.Build.props
- EndProjectSection
-EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
diff --git a/OpenAI-DotNet/Models/ModelsEndpoint.cs b/OpenAI-DotNet/Models/ModelsEndpoint.cs
index 22b23612..5670550a 100644
--- a/OpenAI-DotNet/Models/ModelsEndpoint.cs
+++ b/OpenAI-DotNet/Models/ModelsEndpoint.cs
@@ -9,7 +9,7 @@ namespace OpenAI.Models
{
///
/// List and describe the various models available in the API.
- /// You can refer to the Models documentation to understand what are available and the differences between them.
+ /// You can refer to the Models documentation to understand what are available and the differences between them.
///
///
public sealed class ModelsEndpoint : BaseEndPoint
diff --git a/OpenAI-DotNet/OpenAI-DotNet.csproj b/OpenAI-DotNet/OpenAI-DotNet.csproj
index fc0d8d55..1bc74194 100644
--- a/OpenAI-DotNet/OpenAI-DotNet.csproj
+++ b/OpenAI-DotNet/OpenAI-DotNet.csproj
@@ -17,7 +17,9 @@ More context [on Roger Pincombe's blog](https://rogerpincombe.com/openai-dotnet-
https://github.com/RageAgainstThePixel/OpenAI-DotNet
OpenAI, AI, ML, API, gpt-4, gpt-3.5-tubo, gpt-3, chatGPT, chat-gpt, gpt-2, gpt
OpenAI API
- Bump version to 6.4.2
+ Bump version to 6.4.3
+- Fixed support for Azure Active Directory authentication for Azure OpenAI
+Bump version to 6.4.2
- Misc fixes and added validation for OpenAICLientSettings
- Updated docs
- Decoupled proxy version from main package
@@ -92,7 +94,7 @@ Bump version to 4.4.0
OpenAI-DotNet.pfx
true
OpenAI-DotNet
- 6.4.2
+ 6.4.3
RageAgainstThePixel
README.md
Assets\OpenAI-DotNet-Icon.png
diff --git a/OpenAI-DotNet/OpenAIClient.cs b/OpenAI-DotNet/OpenAIClient.cs
index cdd8d411..34669d75 100644
--- a/OpenAI-DotNet/OpenAIClient.cs
+++ b/OpenAI-DotNet/OpenAIClient.cs
@@ -84,15 +84,16 @@ private HttpClient SetupClient(HttpClient client = null)
client ??= new HttpClient();
client.DefaultRequestHeaders.Add("User-Agent", "OpenAI-DotNet");
- if (!OpenAIClientSettings.BaseRequestUrlFormat.Contains(OpenAIClientSettings.AzureOpenAIDomain))
- {
- if (string.IsNullOrWhiteSpace(OpenAIAuthentication.ApiKey) ||
+ if (!OpenAIClientSettings.BaseRequestUrlFormat.Contains(OpenAIClientSettings.AzureOpenAIDomain)
+ && (string.IsNullOrWhiteSpace(OpenAIAuthentication.ApiKey) ||
(!OpenAIAuthentication.ApiKey.Contains(AuthInfo.SecretKeyPrefix) &&
- !OpenAIAuthentication.ApiKey.Contains(AuthInfo.SessionKeyPrefix)))
- {
- throw new InvalidCredentialException($"{OpenAIAuthentication.ApiKey} must start with '{AuthInfo.SecretKeyPrefix}'");
- }
+ !OpenAIAuthentication.ApiKey.Contains(AuthInfo.SessionKeyPrefix))))
+ {
+ throw new InvalidCredentialException($"{OpenAIAuthentication.ApiKey} must start with '{AuthInfo.SecretKeyPrefix}'");
+ }
+ if (OpenAIClientSettings.UseOAuthAuthentication)
+ {
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", OpenAIAuthentication.ApiKey);
}
else
@@ -130,6 +131,8 @@ private HttpClient SetupClient(HttpClient client = null)
///
/// List and describe the various models available in the API.
+ /// You can refer to the Models documentation to understand what are available and the differences between them.
+ ///
///
public ModelsEndpoint ModelsEndpoint { get; }
diff --git a/OpenAI-DotNet/OpenAIClientSettings.cs b/OpenAI-DotNet/OpenAIClientSettings.cs
index 603345d4..0dab6abb 100644
--- a/OpenAI-DotNet/OpenAIClientSettings.cs
+++ b/OpenAI-DotNet/OpenAIClientSettings.cs
@@ -22,6 +22,7 @@ public OpenAIClientSettings()
DeploymentId = string.Empty;
BaseRequest = $"/{ApiVersion}/";
BaseRequestUrlFormat = $"https://{ResourceName}{BaseRequest}{{0}}";
+ UseOAuthAuthentication = true;
}
///
@@ -52,6 +53,7 @@ public OpenAIClientSettings(string domain, string apiVersion = DefaultOpenAIApiV
DeploymentId = string.Empty;
BaseRequest = $"/{ApiVersion}/";
BaseRequestUrlFormat = $"https://{ResourceName}{BaseRequest}{{0}}";
+ UseOAuthAuthentication = true;
}
///
@@ -67,7 +69,10 @@ public OpenAIClientSettings(string domain, string apiVersion = DefaultOpenAIApiV
///
/// Optional, defaults to 2022-12-01
///
- public OpenAIClientSettings(string resourceName, string deploymentId, string apiVersion = DefaultAzureApiVersion)
+ ///
+ /// Optional, set to true if you want to use Azure Active Directory for Authentication.
+ ///
+ public OpenAIClientSettings(string resourceName, string deploymentId, string apiVersion = DefaultAzureApiVersion, bool useActiveDirectoryAuthentication = false)
{
if (string.IsNullOrWhiteSpace(resourceName))
{
@@ -90,6 +95,7 @@ public OpenAIClientSettings(string resourceName, string deploymentId, string api
ApiVersion = apiVersion;
BaseRequest = $"/openai/deployments/{DeploymentId}/";
BaseRequestUrlFormat = $"https://{ResourceName}.{AzureOpenAIDomain}{BaseRequest}{{0}}?api-version={ApiVersion}";
+ UseOAuthAuthentication = useActiveDirectoryAuthentication;
}
public string ResourceName { get; }
@@ -102,6 +108,8 @@ public OpenAIClientSettings(string resourceName, string deploymentId, string api
internal string BaseRequestUrlFormat { get; }
+ internal bool UseOAuthAuthentication { get; }
+
public static OpenAIClientSettings Default { get; } = new OpenAIClientSettings();
}
}
diff --git a/README.md b/README.md
index 23371ece..795bc80f 100644
--- a/README.md
+++ b/README.md
@@ -39,6 +39,7 @@ Install-Package OpenAI-DotNet
- [Authentication](#authentication)
- [Azure OpenAI](#azure-openai)
+ - [Azure Active Directory Authentication](#azure-active-directory-authentication) :new:
- [OpenAI API Proxy](#openai-api-proxy) :new:
- [Models](#models)
- [List Models](#list-models)
@@ -150,6 +151,20 @@ var settings = new OpenAIClientSettings(resourceName: "your-resource", deploymen
var api = new OpenAIClient(auth, settings);
```
+#### [Azure Active Directory Authentication](https://learn.microsoft.com/en-us/azure/cognitive-services/openai/reference#authentication)
+
+[Authenticate with MSAL](https://github.com/AzureAD/microsoft-authentication-library-for-dotnet) as usual and get access token, then use the access token when creating your `OpenAIAuthentication`. Then be sure to set useAzureActiveDirectory to true when creating your `OpenAIClientSettings`.
+
+[Tutorial: Desktop app that calls web APIs: Acquire a token](https://learn.microsoft.com/en-us/azure/active-directory/develop/scenario-desktop-acquire-token?tabs=dotnet)
+
+```csharp
+// get your access token using any of the MSAL methods
+var accessToken = result.AccessToken;
+var auth = new OpenAIAuthentication(accessToken);
+var settings = new OpenAIClientSettings(resourceName: "your-resource", deploymentId: "your-deployment-id", useActiveDirectoryAuthentication: true);
+var api = new OpenAIClient(auth, settings);
+```
+
### [OpenAI API Proxy](OpenAI-DotNet-Proxy/Readme.md)
[![NuGet version (OpenAI-DotNet-Proxy)](https://img.shields.io/nuget/v/OpenAI-DotNet-Proxy.svg?label=OpenAI-DotNet-Proxy&logo=nuget)](https://www.nuget.org/packages/OpenAI-DotNet-Proxy/)