Skip to content

Commit 33a968b

Browse files
committed
feat(securityscheme): introduce IOAuth2MetadataProvider for OAuth2 metadata URL support
1 parent 14b73bf commit 33a968b

File tree

5 files changed

+38
-13
lines changed

5 files changed

+38
-13
lines changed
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
using System;
2+
3+
namespace Microsoft.OpenApi;
4+
5+
/// <summary>
6+
/// TEMPORARY compatibility interface for accessing OAuth2 metadata URL support introduced for OpenAPI 3.2.
7+
/// This exists to avoid adding new members to <see cref="IOpenApiSecurityScheme"/> in a minor release, which is binary breaking for existing compiled consumers.
8+
/// </summary>
9+
// TODO: Remove this temporary interface and collapse this member into IOpenApiSecurityScheme in the next major version.
10+
public interface IOAuth2MetadataProvider
11+
{
12+
/// <summary>
13+
/// URL to the OAuth2 Authorization Server Metadata document (RFC 8414).
14+
/// Note: This field is supported in OpenAPI 3.2.0+ only.
15+
/// </summary>
16+
public Uri? OAuth2MetadataUrl { get; }
17+
}

src/Microsoft.OpenApi/Models/Interfaces/IOpenApiSecurityScheme.cs

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,15 @@ namespace Microsoft.OpenApi;
55
/// <summary>
66
/// Defines the base properties for the security scheme object.
77
/// This interface is provided for type assertions but should not be implemented by package consumers beyond automatic mocking.
8+
///
9+
/// To preserve binary compatibility in minor releases, properties introduced after this interface shipped may be exposed through temporary companion interfaces.
10+
/// For OAuth2 metadata URL support, cast to <see cref="IOAuth2MetadataProvider"/>:
11+
/// <code>
12+
/// if (securityScheme is IOAuth2MetadataProvider provider)
13+
/// {
14+
/// var oauth2MetadataUrl = provider.OAuth2MetadataUrl;
15+
/// }
16+
/// </code>
817
/// </summary>
918
public interface IOpenApiSecurityScheme : IOpenApiDescribedElement, IOpenApiReadOnlyExtensible, IShallowCopyable<IOpenApiSecurityScheme>, IOpenApiReferenceable
1019
{
@@ -46,12 +55,6 @@ public interface IOpenApiSecurityScheme : IOpenApiDescribedElement, IOpenApiRead
4655
/// </summary>
4756
public Uri? OpenIdConnectUrl { get; }
4857

49-
/// <summary>
50-
/// URL to the OAuth2 Authorization Server Metadata document (RFC 8414).
51-
/// Note: This field is supported in OpenAPI 3.2.0+ only.
52-
/// </summary>
53-
public Uri? OAuth2MetadataUrl { get; }
54-
5558
/// <summary>
5659
/// Specifies that a security scheme is deprecated and SHOULD be transitioned out of usage.
5760
/// Note: This field is supported in OpenAPI 3.2.0+. For earlier versions, it will be serialized as x-oai-deprecated extension.

src/Microsoft.OpenApi/Models/OpenApiSecurityScheme.cs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ namespace Microsoft.OpenApi
99
/// <summary>
1010
/// Security Scheme Object.
1111
/// </summary>
12-
public class OpenApiSecurityScheme : IOpenApiExtensible, IOpenApiSecurityScheme
12+
public class OpenApiSecurityScheme : IOpenApiExtensible, IOpenApiSecurityScheme, IOAuth2MetadataProvider
1313
{
1414
/// <inheritdoc/>
1515
public SecuritySchemeType? Type { get; set; }
@@ -63,7 +63,9 @@ internal OpenApiSecurityScheme(IOpenApiSecurityScheme securityScheme)
6363
BearerFormat = securityScheme.BearerFormat ?? BearerFormat;
6464
Flows = securityScheme.Flows != null ? new(securityScheme.Flows) : null;
6565
OpenIdConnectUrl = securityScheme.OpenIdConnectUrl != null ? new Uri(securityScheme.OpenIdConnectUrl.OriginalString, UriKind.RelativeOrAbsolute) : null;
66-
OAuth2MetadataUrl = securityScheme.OAuth2MetadataUrl != null ? new Uri(securityScheme.OAuth2MetadataUrl.OriginalString, UriKind.RelativeOrAbsolute) : null;
66+
OAuth2MetadataUrl = securityScheme is IOAuth2MetadataProvider oauth2MetadataProvider && oauth2MetadataProvider.OAuth2MetadataUrl != null
67+
? new Uri(oauth2MetadataProvider.OAuth2MetadataUrl.OriginalString, UriKind.RelativeOrAbsolute)
68+
: null;
6769
Deprecated = securityScheme.Deprecated;
6870
Extensions = securityScheme.Extensions != null ? new Dictionary<string, IOpenApiExtension>(securityScheme.Extensions) : null;
6971
}

src/Microsoft.OpenApi/Models/References/OpenApiSecuritySchemeReference.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ namespace Microsoft.OpenApi
99
/// <summary>
1010
/// Security Scheme Object Reference.
1111
/// </summary>
12-
public class OpenApiSecuritySchemeReference : BaseOpenApiReferenceHolder<OpenApiSecurityScheme, IOpenApiSecurityScheme, OpenApiReferenceWithDescription>, IOpenApiSecurityScheme
12+
public class OpenApiSecuritySchemeReference : BaseOpenApiReferenceHolder<OpenApiSecurityScheme, IOpenApiSecurityScheme, OpenApiReferenceWithDescription>, IOpenApiSecurityScheme, IOAuth2MetadataProvider
1313
{
1414
/// <summary>
1515
/// Constructor initializing the reference object.
@@ -55,7 +55,7 @@ public string? Description
5555
public Uri? OpenIdConnectUrl { get => Target?.OpenIdConnectUrl; }
5656

5757
/// <inheritdoc/>
58-
public Uri? OAuth2MetadataUrl { get => Target?.OAuth2MetadataUrl; }
58+
public Uri? OAuth2MetadataUrl { get => Target is IOAuth2MetadataProvider oauth2MetadataProvider ? oauth2MetadataProvider.OAuth2MetadataUrl : null; }
5959

6060
/// <inheritdoc/>
6161
public IDictionary<string, IOpenApiExtension>? Extensions { get => Target?.Extensions; }

test/Microsoft.OpenApi.Tests/PublicApi/PublicApi.approved.txt

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,10 @@ namespace Microsoft.OpenApi
105105
{
106106
System.Collections.Generic.IDictionary<string, object>? Metadata { get; set; }
107107
}
108+
public interface IOAuth2MetadataProvider
109+
{
110+
System.Uri? OAuth2MetadataUrl { get; }
111+
}
108112
public interface IOpenApiCallback : Microsoft.OpenApi.IOpenApiElement, Microsoft.OpenApi.IOpenApiReadOnlyExtensible, Microsoft.OpenApi.IOpenApiReferenceable, Microsoft.OpenApi.IOpenApiSerializable, Microsoft.OpenApi.IShallowCopyable<Microsoft.OpenApi.IOpenApiCallback>
109113
{
110114
System.Collections.Generic.Dictionary<Microsoft.OpenApi.RuntimeExpression, Microsoft.OpenApi.IOpenApiPathItem>? PathItems { get; }
@@ -288,7 +292,6 @@ namespace Microsoft.OpenApi
288292
Microsoft.OpenApi.OpenApiOAuthFlows? Flows { get; }
289293
Microsoft.OpenApi.ParameterLocation? In { get; }
290294
string? Name { get; }
291-
System.Uri? OAuth2MetadataUrl { get; }
292295
System.Uri? OpenIdConnectUrl { get; }
293296
string? Scheme { get; }
294297
Microsoft.OpenApi.SecuritySchemeType? Type { get; }
@@ -1373,7 +1376,7 @@ namespace Microsoft.OpenApi
13731376
public virtual void SerializeAsV31(Microsoft.OpenApi.IOpenApiWriter writer) { }
13741377
public virtual void SerializeAsV32(Microsoft.OpenApi.IOpenApiWriter writer) { }
13751378
}
1376-
public class OpenApiSecurityScheme : Microsoft.OpenApi.IOpenApiDescribedElement, Microsoft.OpenApi.IOpenApiElement, Microsoft.OpenApi.IOpenApiExtensible, Microsoft.OpenApi.IOpenApiReadOnlyExtensible, Microsoft.OpenApi.IOpenApiReferenceable, Microsoft.OpenApi.IOpenApiSecurityScheme, Microsoft.OpenApi.IOpenApiSerializable, Microsoft.OpenApi.IShallowCopyable<Microsoft.OpenApi.IOpenApiSecurityScheme>
1379+
public class OpenApiSecurityScheme : Microsoft.OpenApi.IOAuth2MetadataProvider, Microsoft.OpenApi.IOpenApiDescribedElement, Microsoft.OpenApi.IOpenApiElement, Microsoft.OpenApi.IOpenApiExtensible, Microsoft.OpenApi.IOpenApiReadOnlyExtensible, Microsoft.OpenApi.IOpenApiReferenceable, Microsoft.OpenApi.IOpenApiSecurityScheme, Microsoft.OpenApi.IOpenApiSerializable, Microsoft.OpenApi.IShallowCopyable<Microsoft.OpenApi.IOpenApiSecurityScheme>
13771380
{
13781381
public OpenApiSecurityScheme() { }
13791382
public string? BearerFormat { get; set; }
@@ -1393,7 +1396,7 @@ namespace Microsoft.OpenApi
13931396
public virtual void SerializeAsV31(Microsoft.OpenApi.IOpenApiWriter writer) { }
13941397
public virtual void SerializeAsV32(Microsoft.OpenApi.IOpenApiWriter writer) { }
13951398
}
1396-
public class OpenApiSecuritySchemeReference : Microsoft.OpenApi.BaseOpenApiReferenceHolder<Microsoft.OpenApi.OpenApiSecurityScheme, Microsoft.OpenApi.IOpenApiSecurityScheme, Microsoft.OpenApi.OpenApiReferenceWithDescription>, Microsoft.OpenApi.IOpenApiDescribedElement, Microsoft.OpenApi.IOpenApiElement, Microsoft.OpenApi.IOpenApiReadOnlyExtensible, Microsoft.OpenApi.IOpenApiReferenceable, Microsoft.OpenApi.IOpenApiSecurityScheme, Microsoft.OpenApi.IOpenApiSerializable, Microsoft.OpenApi.IShallowCopyable<Microsoft.OpenApi.IOpenApiSecurityScheme>
1399+
public class OpenApiSecuritySchemeReference : Microsoft.OpenApi.BaseOpenApiReferenceHolder<Microsoft.OpenApi.OpenApiSecurityScheme, Microsoft.OpenApi.IOpenApiSecurityScheme, Microsoft.OpenApi.OpenApiReferenceWithDescription>, Microsoft.OpenApi.IOAuth2MetadataProvider, Microsoft.OpenApi.IOpenApiDescribedElement, Microsoft.OpenApi.IOpenApiElement, Microsoft.OpenApi.IOpenApiReadOnlyExtensible, Microsoft.OpenApi.IOpenApiReferenceable, Microsoft.OpenApi.IOpenApiSecurityScheme, Microsoft.OpenApi.IOpenApiSerializable, Microsoft.OpenApi.IShallowCopyable<Microsoft.OpenApi.IOpenApiSecurityScheme>
13971400
{
13981401
public OpenApiSecuritySchemeReference(string referenceId, Microsoft.OpenApi.OpenApiDocument? hostDocument = null, string? externalResource = null) { }
13991402
public string? BearerFormat { get; }

0 commit comments

Comments
 (0)