Skip to content

Commit 334b22a

Browse files
mojanasglahayeshawncal
authored
.Net: Add support for custom authentication provider for OpenAPI (#2283)
### Motivation and Context <!-- Thank you for your contribution to the semantic-kernel repo! Please help reviewers and future users, providing the following information: 1. Why is this change required? 2. What problem does it solve? 3. What scenario does it contribute to? 4. If it fixes an open issue, please link to the issue here. --> 1. **Why is this change required?** This change adds support for other authentication methods defined in OpenAPI specs. 2. **What problem does it solve?** Some APIs use other authentication methods that define a value in a custom header. As an example, [many PlayFab APIs](https://learn.microsoft.com/en-us/gaming/playfab/api-references/#security) are authenticated using secret key or user token in a custom header. The current authentication providers are not sufficient for onboarding these APIs as skills. 3. **What scenario does it contribute to?** This change will enable APIs using custom header authentication to onboard their OpenAPI specs as skills in Semantic Kernel. 4. **If it fixes an open issue, please link to the issue here.** ### Description <!-- Describe your changes, the overall approach, the underlying design. These notes will help understanding how your code works. Thanks! --> This change adds a new OpenAPI authentication provider that enables specifying a custom header to supply the authentication key or value. ### Contribution Checklist <!-- Before submitting this PR, please make sure: --> - [x] The code builds clean without any errors or warnings - [x] The PR follows the [SK Contribution Guidelines](https://github.com/microsoft/semantic-kernel/blob/main/CONTRIBUTING.md) and the [pre-submission formatting script](https://github.com/microsoft/semantic-kernel/blob/main/CONTRIBUTING.md#development-scripts) raises no violations - [x] All unit tests pass, and I have added new tests where possible - [x] I didn't break anyone 😄 --------- Co-authored-by: Gil LaHaye <gillahaye@microsoft.com> Co-authored-by: Shawn Callegari <36091529+shawncal@users.noreply.github.com>
1 parent 4ea1d48 commit 334b22a

File tree

2 files changed

+71
-0
lines changed

2 files changed

+71
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
// Copyright (c) Microsoft. All rights reserved.
2+
3+
using System;
4+
using System.Net.Http;
5+
using System.Threading.Tasks;
6+
7+
namespace Microsoft.SemanticKernel.Skills.OpenAPI.Authentication;
8+
9+
/// <summary>
10+
/// Retrieves authentication content (scheme and value) via the provided delegate and applies it to HTTP requests.
11+
/// </summary>
12+
public sealed class CustomAuthenticationProvider
13+
{
14+
private readonly Func<Task<string>> _header;
15+
private readonly Func<Task<string>> _value;
16+
17+
/// <summary>
18+
/// Creates an instance of the <see cref="CustomAuthenticationProvider"/> class.
19+
/// </summary>
20+
/// <param name="header">Delegate for retrieving the header name.</param>
21+
/// <param name="value">Delegate for retrieving the value.</param>
22+
public CustomAuthenticationProvider(Func<Task<string>> header, Func<Task<string>> value)
23+
{
24+
this._header = header;
25+
this._value = value;
26+
}
27+
28+
/// <summary>
29+
/// Applies the header and value to the provided HTTP request message.
30+
/// </summary>
31+
/// <param name="request">The HTTP request message.</param>
32+
/// <returns></returns>
33+
public async Task AuthenticateRequestAsync(HttpRequestMessage request)
34+
{
35+
var header = await this._header().ConfigureAwait(false);
36+
var value = await this._value().ConfigureAwait(false);
37+
request.Headers.Add(header, value);
38+
}
39+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
// Copyright (c) Microsoft. All rights reserved.
2+
3+
using System;
4+
using System.Linq;
5+
using System.Net.Http;
6+
using System.Threading.Tasks;
7+
using Microsoft.SemanticKernel.Skills.OpenAPI.Authentication;
8+
using Xunit;
9+
10+
namespace SemanticKernel.Skills.UnitTests.OpenAPI.Authentication;
11+
12+
public class CustomAuthenticationProviderTests
13+
{
14+
[Fact]
15+
public async Task AuthenticateRequestAsyncSucceedsAsync()
16+
{
17+
// Arrange
18+
var header = "X-MyHeader";
19+
var value = Guid.NewGuid().ToString();
20+
21+
using var request = new HttpRequestMessage();
22+
23+
var target = new CustomAuthenticationProvider(() => Task.FromResult(header), () => Task.FromResult(value));
24+
25+
// Act
26+
await target.AuthenticateRequestAsync(request);
27+
28+
// Assert
29+
Assert.True(request.Headers.Contains(header));
30+
Assert.Equal(request.Headers.GetValues(header).FirstOrDefault(), value);
31+
}
32+
}

0 commit comments

Comments
 (0)