Skip to content
Merged
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
16 changes: 16 additions & 0 deletions src/Microsoft.OpenApi/Models/OpenApiSecurityScheme.cs
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,14 @@ private void SerializeInternal(IOpenApiWriter writer, OpenApiSpecVersion version
// openIdConnectUrl
writer.WriteProperty(OpenApiConstants.OpenIdConnectUrl, OpenIdConnectUrl?.ToString());
break;
case SecuritySchemeType.MutualTLS:
// No additional properties for mutualTLS
if (version < OpenApiSpecVersion.OpenApi3_1)
{
// mutualTLS is introduced in OpenAPI 3.1
throw new OpenApiException($"mutualTLS security scheme is only supported in OpenAPI 3.1 and later versions. Current version: {version}");
}
break;
}

// deprecated - serialize as native field for v3.2+ or as extension for earlier versions
Expand Down Expand Up @@ -170,6 +178,14 @@ public virtual void SerializeAsV2(IOpenApiWriter writer)
return;
}

if (Type == SecuritySchemeType.MutualTLS)
{
// Bail because V2 does not support mutualTLS
writer.WriteStartObject();
writer.WriteEndObject();
return;
}

writer.WriteStartObject();

// type
Expand Down
7 changes: 6 additions & 1 deletion src/Microsoft.OpenApi/Models/SecuritySchemeType.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,11 @@ public enum SecuritySchemeType
/// <summary>
/// Use OAuth2 with OpenId Connect URL to discover OAuth2 configuration value.
/// </summary>
[Display("openIdConnect")] OpenIdConnect
[Display("openIdConnect")] OpenIdConnect,

/// <summary>
/// Use mutual TLS authentication.
/// </summary>
[Display("mutualTLS")] MutualTLS
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,25 @@ public async Task ParseOpenIdConnectSecuritySchemeShouldSucceed()
}, securityScheme);
}

[Fact]
public async Task ParseMutualTlsSecuritySchemeShouldSucceed()
{
// Act
var securityScheme = await OpenApiModelFactory.LoadAsync<OpenApiSecurityScheme>(
Path.Combine(SampleFolderPath, "mutualTlsSecurityScheme.yaml"),
OpenApiSpecVersion.OpenApi3_2,
new(),
SettingsFixture.ReaderSettings);

// Assert
Assert.Equivalent(
new OpenApiSecurityScheme
{
Type = SecuritySchemeType.MutualTLS,
Description = "Sample Description"
}, securityScheme);
}

[Fact]
public async Task ParseOAuth2SecuritySchemeWithDeviceAuthorizationUrlShouldSucceed()
{
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
type: mutualTLS
description: Sample Description
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,12 @@ public class OpenApiSecuritySchemeTests
OpenIdConnectUrl = new("https://example.com/openIdConnect")
};

private static OpenApiSecurityScheme MutualTlsSecurityScheme => new()
{
Description = "description1",
Type = SecuritySchemeType.MutualTLS
};

private static OpenApiSecuritySchemeReference OpenApiSecuritySchemeReference => new("sampleSecurityScheme");
private static OpenApiSecurityScheme ReferencedSecurityScheme => new()
{
Expand Down Expand Up @@ -208,6 +214,19 @@ public async Task SerializeHttpBearerSecuritySchemeAsV3JsonWorks()
Assert.Equal(expected, actual);
}

[Fact]
public void SerializeMutualTlsSecuritySchemeAsV3Throws()
{
// Arrange
var outputStringWriter = new StringWriter(CultureInfo.InvariantCulture);
var writer = new OpenApiJsonWriter(outputStringWriter);

// Act & Assert
var exception = Assert.Throws<OpenApiException>(() => MutualTlsSecurityScheme.SerializeAsV3(writer));
Assert.Contains("mutualTLS security scheme is only supported in OpenAPI 3.1 and later versions", exception.Message);
Assert.Contains($"Current version: {OpenApiSpecVersion.OpenApi3_0}", exception.Message);
}

[Fact]
public async Task SerializeOAuthSingleFlowSecuritySchemeAsV3JsonWorks()
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1933,6 +1933,8 @@ namespace Microsoft.OpenApi
OAuth2 = 2,
[Microsoft.OpenApi.Display("openIdConnect")]
OpenIdConnect = 3,
[Microsoft.OpenApi.Display("mutualTLS")]
MutualTLS = 4,
}
public abstract class SourceExpression : Microsoft.OpenApi.RuntimeExpression
{
Expand Down