Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -197,17 +197,15 @@ private static string ResolveConfiguredAuthNScheme(string? configuredProviderNam
{
return UnauthenticatedAuthenticationDefaults.AUTHENTICATIONSCHEME;
}
else if (string.Equals(configuredProviderName, SupportedAuthNProviders.AZURE_AD, StringComparison.OrdinalIgnoreCase) ||
string.Equals(configuredProviderName, SupportedAuthNProviders.ENTRA_ID, StringComparison.OrdinalIgnoreCase))
{
return JwtBearerDefaults.AuthenticationScheme;
}
else
{
// Changing this value is a breaking change because non-out of box
// authentication provider names supplied in dab-config.json indicate
// that JWT bearer authentication should be used.
return GenericOAuthDefaults.AUTHENTICATIONSCHEME;
// Every non-EasyAuth/Simulator/Unauthenticated provider (AzureAD, EntraID, and any
// custom OAuth/JWT provider such as "Custom") is authenticated via JWT bearer. The JWT
// handler is always registered under JwtBearerDefaults.AuthenticationScheme ("Bearer")
// in Startup's ConfigureAuthentication/ConfigureAuthenticationV2, so the resolved scheme
Comment on lines 201 to +205

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I noticed this as well, but I dont think it is an issue that will arise, as I doubt anyone it taking dependencies on this. We could document it however just so that it is made clear.

// must match that registration - otherwise AuthenticateAsync throws
// "No authentication handler is registered for the scheme ...".
return JwtBearerDefaults.AuthenticationScheme;
}
}
}
Expand Down
12 changes: 0 additions & 12 deletions src/Core/AuthenticationHelpers/GenericOAuthDefaults.cs

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,46 @@ await SendRequestAndGetHttpContextState(
ignoreCase: true);
}

/// <summary>
/// Regression test for https://github.com/Azure/data-api-builder/issues/3541
/// A JWT-configured provider whose name is not an out-of-box provider (e.g. "Custom") must
/// resolve to the same "Bearer" scheme the JWT handler is registered under. Previously this
/// resolved to the unregistered "OAuthAuthentication" scheme, causing AuthenticateAsync to
/// throw "No authentication handler is registered for the scheme 'OAuthAuthentication'".
/// </summary>
[DataTestMethod]
[DataRow("Custom", DisplayName = "Custom JWT provider authenticates via the Bearer scheme")]
[DataRow("AzureAD", DisplayName = "AzureAD JWT provider authenticates via the Bearer scheme")]
[DataRow("EntraID", DisplayName = "EntraID JWT provider authenticates via the Bearer scheme")]
[TestMethod]
public async Task TestValidToken_JwtConfiguredProviders(string provider)
{
RsaSecurityKey key = new(RSA.Create(2048));
string token = CreateJwt(
audience: AUDIENCE,
issuer: LOCAL_ISSUER,
notBefore: DateTime.UtcNow.AddDays(-1),
expirationTime: DateTime.UtcNow.AddDays(1),
signingKey: key
);

HttpContext postMiddlewareContext =
await SendRequestAndGetHttpContextState(
key,
token,
clientRoleHeader: null,
provider: provider);

Assert.IsTrue(postMiddlewareContext.User.Identity.IsAuthenticated);
Assert.AreEqual(
expected: (int)HttpStatusCode.OK,
actual: postMiddlewareContext.Response.StatusCode);
Assert.AreEqual(
expected: AuthorizationType.Authenticated.ToString(),
actual: postMiddlewareContext.Request.Headers[AuthorizationResolver.CLIENT_ROLE_HEADER],
ignoreCase: true);
}

/// <summary>
/// Test to validate that the user request is treated with anonymous role when
/// the jwt token is missing.
Expand Down Expand Up @@ -302,15 +342,17 @@ public async Task TestInvalidToken_NoSignature()
/// and configures Authentication options with passed in SecurityKey
/// </summary>
/// <param name="key"></param>
/// <param name="provider">Runtime configured identity provider name (e.g. "AzureAD" or a
/// custom OAuth/JWT provider such as "Custom"). All resolve to JWT bearer authentication.</param>
/// <returns>IHost</returns>
private static async Task<IHost> CreateWebHostCustomIssuer(SecurityKey key)
private static async Task<IHost> CreateWebHostCustomIssuer(SecurityKey key, string provider = "AzureAD")
{
// Setup RuntimeConfigProvider object for the pipeline.
MockFileSystem fileSystem = new();
FileSystemRuntimeConfigLoader fileSystemRuntimeConfigLoader = new(new MockFileSystem());
AuthenticationOptions authOptions = new()
{
Provider = "AzureAD"
Provider = provider
};

RuntimeConfig runtimeConfig = RuntimeConfigAuthHelper.CreateTestConfigWithAuthNProvider(authOptions);
Expand Down Expand Up @@ -384,9 +426,10 @@ private static async Task<IHost> CreateWebHostCustomIssuer(SecurityKey key)
private static async Task<HttpContext> SendRequestAndGetHttpContextState(
SecurityKey key,
string token,
string clientRoleHeader = null)
string clientRoleHeader = null,
string provider = "AzureAD")
{
using IHost host = await CreateWebHostCustomIssuer(key);
using IHost host = await CreateWebHostCustomIssuer(key, provider);
TestServer server = host.GetTestServer();

return await server.SendAsync(context =>
Expand Down