I have an ASP.NET Core Api where it is required to use multiple authentication schemes for one operation. I am trying to document those operations with displaying all required authentication schemes in Swagger UI.
Therefore I use the Swashbuckle.AspNetCore (5.1.0) library for a dynamic adding of OpenApiSecurityRequirement
to the OpenApiOperation
in an IOperationFilter
:
if (authorizeAttributes.Any(x => x.AuthenticationSchemes.Contains(InternalControllerBasicAuthentication.AuthenticationScheme)))
{
requirements.Add(new OpenApiSecurityRequirement
{
{
new OpenApiSecurityScheme {
Reference = new OpenApiReference {
Type = ReferenceType.SecurityScheme,
Id = "credentials"
}
},
new [] { "Basic <credentials-value>" }
}
});
}
if (authorizeAttributes.Any(x => x.AuthenticationSchemes.Contains(OneTimePasswordAuthentication.AuthenticationScheme)))
{
requirements.Add(new OpenApiSecurityRequirement
{
{
new OpenApiSecurityScheme {
Reference = new OpenApiReference {
Type = ReferenceType.SecurityScheme,
Id = "one-time-password"
}
},
new [] { "Basic <one-time-password-value>" }
}
});
}
operation.Security = new List<OpenApiSecurityRequirement>(requirements);
Furthemore I use the SwaggerGenOptions
to register all possible schemes:
var oneTimePasswordScheme = new OpenApiSecurityScheme
{
Name = "one-time-password",
In = ParameterLocation.Header,
Scheme = "one-time-password",
Type = SecuritySchemeType.ApiKey
};
options.AddSecurityDefinition("one-time-password", oneTimePasswordScheme);
var credentialsScheme = new OpenApiSecurityScheme
{
Name = "credentials",
In = ParameterLocation.Header,
Scheme = "credentials",
Type = SecuritySchemeType.ApiKey
};
options.AddSecurityDefinition("credentials", credentialsScheme);
Everything works fine except for Swagger using the OR
connector in the UI:
Is there a way to configure Swagger using the AND
connector?
Any help will be highly appreciated!
Instead of adding a OpenApiSecurityRequirement
for each OpenApiSecurityScheme
, it is necessary to put all OpenApiSecurityScheme
objects into a single OpenApiSecurityRequirement
.
Connects security requirements with OR:
var requirements = new List<OpenApiSecurityRequirement>();
requirements.Add(new OpenApiSecurityRequirement
{
{
new OpenApiSecurityScheme {
Reference = new OpenApiReference {
Type = ReferenceType.SecurityScheme,
Id = "scheme-1"
}
},
new [] { "scheme-1-value" }
}
});
requirements.Add(new OpenApiSecurityRequirement
{
{
new OpenApiSecurityScheme {
Reference = new OpenApiReference {
Type = ReferenceType.SecurityScheme,
Id = "scheme-2"
}
},
new [] { "scheme-2-value" }
}
});
operation.Security = new List<OpenApiSecurityRequirement>(requirements);
Connects security requirements with AND:
var requirement = new OpenApiSecurityRequirement();
requirement.Add(new OpenApiSecurityScheme {
Reference = new OpenApiReference {
Type = ReferenceType.SecurityScheme,
Id = "scheme-1"
}
},
new [] { "scheme-1-value" }
);
requirement.Add(new OpenApiSecurityScheme {
Reference = new OpenApiReference {
Type = ReferenceType.SecurityScheme,
Id = "scheme-2"
}
},
new [] { "scheme-2-value" }
);
operation.Security = new List<OpenApiSecurityRequirement> { requirement };