using System; using System.Collections.Generic; using JetBrains.Annotations; using Microsoft.OpenApi; using Swashbuckle.AspNetCore.SwaggerGen; using Swashbuckle.AspNetCore.SwaggerUI; using Volo.Abp.Content; using Volo.Abp.MultiTenancy; using Volo.Abp.Swashbuckle; namespace Microsoft.Extensions.DependencyInjection; public static class AbpSwaggerGenServiceCollectionExtensions { public static IServiceCollection AddAbpSwaggerGen( this IServiceCollection services, Action? setupAction = null) { return services.AddSwaggerGen( options => { Func remoteStreamContentSchemaFactory = () => new OpenApiSchema() { Type = JsonSchemaType.String, Format = "binary" }; options.MapType(remoteStreamContentSchemaFactory); options.MapType(remoteStreamContentSchemaFactory); setupAction?.Invoke(options); }); } public static IServiceCollection AddAbpSwaggerGenWithOAuth( this IServiceCollection services, [NotNull] string authority, [NotNull] Dictionary scopes, Action? setupAction = null, string authorizationEndpoint = "/connect/authorize", string tokenEndpoint = "/connect/token") { var authorizationUrl = new Uri($"{authority.TrimEnd('/')}{authorizationEndpoint.EnsureStartsWith('/')}"); var tokenUrl = new Uri($"{authority.TrimEnd('/')}{tokenEndpoint.EnsureStartsWith('/')}"); return services .AddAbpSwaggerGen() .AddSwaggerGen( options => { options.AddSecurityDefinition("oauth2", new OpenApiSecurityScheme { Type = SecuritySchemeType.OAuth2, Flows = new OpenApiOAuthFlows { AuthorizationCode = new OpenApiOAuthFlow { AuthorizationUrl = authorizationUrl, Scopes = scopes, TokenUrl = tokenUrl } } }); options.AddSecurityRequirement(document => new OpenApiSecurityRequirement() { [new OpenApiSecuritySchemeReference("oauth2", document)] = [] }); setupAction?.Invoke(options); }); } public static IServiceCollection AddAbpSwaggerGenWithOidc( this IServiceCollection services, [NotNull] string authority, string[]? scopes = null, string[]? flows = null, string? discoveryEndpoint = null, Action? setupAction = null, string oidcAuthenticationScheme = "oidc") { var discoveryUrl = discoveryEndpoint != null ? $"{discoveryEndpoint.TrimEnd('/')}/.well-known/openid-configuration": $"{authority.TrimEnd('/')}/.well-known/openid-configuration"; flows ??= new [] { AbpSwaggerOidcFlows.AuthorizationCode }; services.Configure(swaggerUiOptions => { swaggerUiOptions.ConfigObject.AdditionalItems["oidcSupportedFlows"] = flows; swaggerUiOptions.ConfigObject.AdditionalItems["oidcSupportedScopes"] = scopes; swaggerUiOptions.ConfigObject.AdditionalItems["oidcDiscoveryEndpoint"] = discoveryUrl; }); return services .AddAbpSwaggerGen() .AddSwaggerGen( options => { options.AddSecurityDefinition(oidcAuthenticationScheme, new OpenApiSecurityScheme { Type = SecuritySchemeType.OpenIdConnect, OpenIdConnectUrl = new Uri(RemoveTenantPlaceholders(discoveryUrl)) }); options.AddSecurityRequirement(document => new OpenApiSecurityRequirement() { [new OpenApiSecuritySchemeReference(oidcAuthenticationScheme, document)] = [] }); setupAction?.Invoke(options); }); } private static string RemoveTenantPlaceholders(string url) { return url .Replace(MultiTenantUrlProvider.TenantPlaceHolder + ".", string.Empty) .Replace(MultiTenantUrlProvider.TenantIdPlaceHolder + ".", string.Empty) .Replace(MultiTenantUrlProvider.TenantNamePlaceHolder + ".", string.Empty); } }