'Microsoft.OpenAPI examples or documentation?
Just tried to use Swashbuckle 5 rc2 + Microsoft OpenAPI implementation but struggling to make sense of how to inject the security requirements using the OpenApiSecurityRequirement via an OperationFilter
I'm converting the OperationFilter from Swashbuckle 4 to Swashbuckle 5 rc2 which makes use of Microsoft's OpenApi. WIthin the Swashbuckle 4 implementation I had OperationFilter (and this allowed me to use both oauth2 implicit flow scopes as well as api_key where I would explicitly set a bearer JTW token in the SwaggerUI:
// Swashbuckle 4 code
operation.Security = new List<Dictionary<String, IEnumerable<String>>>
{
new Dictionary<string, IEnumerable<string>>
{
{ "Bearer", new string[] { } }
},
new Dictionary<string, IEnumerable<string>>
{
{ "oauth2", requiredScopes }
}
};
Not very sure how to use OpenAPI for describing the same security requirements, but in the converted OperationFilter implementation I've basically sought out the endpoints which have the Authorize attribute and read the policy to retrieve the scopes:
if (requiredScopes.Any())
{
operation.Responses.Add("401", new OpenApiResponse { Description = "Unauthorized" });
operation.Responses.Add("403", new OpenApiResponse { Description = "Forbidden" });
OpenApiSecurityRequirement bearerSecurityRequirement = new OpenApiSecurityRequirement();
bearerSecurityRequirement[new OpenApiSecurityScheme()
{
Type = SecuritySchemeType.Http,
Scheme = "Bearer",
BearerFormat = "JWT",
In = ParameterLocation.Header,
Name = "api_key",
}] = new List<String>();
OpenApiSecurityRequirement oauth2SecurityRequirement = new OpenApiSecurityRequirement();
oauth2SecurityRequirement[new OpenApiSecurityScheme()
{
Type = SecuritySchemeType.OAuth2,
Flows = new OpenApiOAuthFlows()
{
Implicit = new OpenApiOAuthFlow()
{
AuthorizationUrl = new Uri("<authorization url here>"),
TokenUrl = new Uri("<token url here>"),
Scopes = requiredScopes.ToDictionary(x => x) // TODO: Fix descriptions
}
},
In = ParameterLocation.Header,
Name = "oauth2"
}] = new List<String>(requiredScopes);
operation.Security = new List<OpenApiSecurityRequirement>
{
bearerSecurityRequirement,
oauth2SecurityRequirement
};
}
In the json output of the generated swagger doc/openapi doc for the operation I'm just seeing:
"security" : [
{"api_key": []},
{
"oauth2": [
"",
""
]
}
]
I think I am aiming to generate the following json in terms OpenAPI standard, where api_key and oauth2 are just the names of my security schemes.
"security" : [
{"api_key": []},
{
"oauth2": [
"<scope1>",
"<scope2>"
]
}
]
Are there any docs coming or perhaps some fuller examples that actually demonstrate how to declare protected endpoints for oauth2 and api key approaches?
Solution 1:[1]
You need to set the Reference
of the OpenApiSecurityScheme
.
I ended up with a result just like you, just an empty object.
I tried to add HTTP basic authentication like in the example:
openapi: 3.0.0
...
components:
securitySchemes:
basicAuth: # <-- arbitrary name for the security scheme
type: http
scheme: basic
security:
- basicAuth: [] # <-- use the same name here
And to do that with Microsoft.OpenApi:
var document = new OpenApiDocument
{
Components = new OpenApiComponents
{
SecuritySchemes =
{
{
"basicAuth", new OpenApiSecurityScheme
{
Type = SecuritySchemeType.Http,
Scheme = "basic"
}
}
}
},
SecurityRequirements =
{
new OpenApiSecurityRequirement
{
{
new OpenApiSecurityScheme
{
Reference = new OpenApiReference()
{
Type = ReferenceType.SecurityScheme,
Id = "basicAuth"
}
},
new List<string>()
}
}
}
};
By looking at the source code of OpenApiSecurityRequirement
one can see that it's checking OpenApiSecurityScheme.Reference
and not Name
:
foreach (var securitySchemeAndScopesValuePair in this)
{
var securityScheme = securitySchemeAndScopesValuePair.Key;
var scopes = securitySchemeAndScopesValuePair.Value;
if (securityScheme.Reference == null)
{
// Reaching this point means the reference to a specific OpenApiSecurityScheme fails.
// We are not able to serialize this SecurityScheme/Scopes key value pair since we do not know what
// string to output.
continue;
}
securityScheme.SerializeAsV3(writer);
writer.WriteStartArray();
foreach (var scope in scopes)
{
writer.WriteValue(scope);
}
writer.WriteEndArray();
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Mikael Dúi Bolinder |