Cube/NewLife.Cube.Swagger/SwaggerService.cs

145 lines
6.5 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using Microsoft.AspNetCore.Mvc.ApiExplorer;
using Microsoft.AspNetCore.Mvc.Controllers;
using Microsoft.Extensions.Options;
using Microsoft.OpenApi.Models;
using NewLife.Cube.Entity;
using NewLife.Reflection;
using Swashbuckle.AspNetCore.SwaggerGen;
namespace NewLife.Cube.Swagger;
/// <summary>Swagger服务</summary>
public static class SwaggerService
{
/// <summary>添加魔方Swagger服务</summary>
/// <param name="services"></param>
/// <returns></returns>
public static IServiceCollection AddCubeSwagger(this IServiceCollection services)
{
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
services.AddEndpointsApiExplorer();
services.AddTransient<IConfigureOptions<SwaggerGenOptions>, SwaggerConfigureOptions>();
services.AddSwaggerGen(options =>
{
// 解决 NewLife.Setting 与 XCode.Setting 冲突的问题
options.CustomSchemaIds(type => type.FullName);
var xml = "NewLife.Cube.xml".GetFullPath();
if (File.Exists(xml)) options.IncludeXmlComments(xml, true);
var asm = AssemblyX.Entry;
options.SwaggerDoc("v1", new OpenApiInfo { Title = "第三代魔方", Description = "第三代魔方WebApi接口用于前后端分离。", Version = asm.FileVersion });
//options.SwaggerDoc("Basic", new OpenApiInfo { Version = "basic", Title = "基础模块" });
//options.SwaggerDoc("Admin", new OpenApiInfo { Version = "admin", Title = "系统管理" });
//options.SwaggerDoc("Cube", new OpenApiInfo { Version = "cube", Title = "魔方管理" });
options.DocInclusionPredicate((docName, apiDesc) =>
{
if (apiDesc.ActionDescriptor is not ControllerActionDescriptor controller) return false;
var groups = controller.ControllerTypeInfo.GetCustomAttributes(true).OfType<IApiDescriptionGroupNameProvider>().Select(e => e.GroupName).ToList();
if (docName == "v1" && (groups == null || groups.Count == 0)) return true;
return groups != null && groups.Any(e => e == docName);
});
var oauthConfigs = OAuthConfig.GetValids(GrantTypes.AuthorizationCode);
if (oauthConfigs.Count > 0)
{
var cfg = oauthConfigs[0];
var flow = new OpenApiOAuthFlow
{
AuthorizationUrl = new Uri(cfg.Server + "/authorize"),
TokenUrl = new Uri((!cfg.AccessServer.IsNullOrEmpty() ? cfg.AccessServer : cfg.Server) + "/access_token"),
//Scopes = new Dictionary<String, String>
//{
// { "api1", "Access to API #1" }
//}
};
options.AddSecurityDefinition("OAuth2", new OpenApiSecurityScheme
{
Type = SecuritySchemeType.OAuth2,
In = ParameterLocation.Query,
Flows = new OpenApiOAuthFlows { AuthorizationCode = flow }
});
// 声明一个Scheme注意下面的Id要和上面AddSecurityDefinition中的参数name一致
var scheme = new OpenApiSecurityScheme()
{
Reference = new OpenApiReference() { Type = ReferenceType.SecurityScheme, Id = "OAuth2" }
};
// 注册全局认证(所有的接口都可以使用认证)
options.AddSecurityRequirement(new OpenApiSecurityRequirement() { [scheme] = [] });
}
else
{
// 定义JwtBearer认证方式
options.AddSecurityDefinition("JwtBearer", new OpenApiSecurityScheme()
{
Description = "输入登录成功后取得的令牌",
Name = "Authorization",
In = ParameterLocation.Header,
Type = SecuritySchemeType.Http,
Scheme = "Bearer"
});
// 声明一个Scheme注意下面的Id要和上面AddSecurityDefinition中的参数name一致
var scheme = new OpenApiSecurityScheme()
{
Reference = new OpenApiReference() { Type = ReferenceType.SecurityScheme, Id = "JwtBearer" }
};
// 注册全局认证(所有的接口都可以使用认证)
options.AddSecurityRequirement(new OpenApiSecurityRequirement() { [scheme] = [] });
}
});
return services;
}
/// <summary>使用魔方Swagger服务</summary>
/// <param name="app"></param>
/// <returns></returns>
public static IApplicationBuilder UseCubeSwagger(this IApplicationBuilder app)
{
app.UseSwagger();
//app.UseSwaggerUI();
app.UseSwaggerUI(options =>
{
var asm = AssemblyX.Entry;
options.DocumentTitle = !asm.Title.IsNullOrEmpty() ? asm.Title : "魔方Web开发平台";
//options.SwaggerEndpoint("/swagger/Basic/swagger.json", "Basic");
//options.SwaggerEndpoint("/swagger/Admin/swagger.json", "Admin");
//options.SwaggerEndpoint("/swagger/Cube/swagger.json", "Cube");
//options.SwaggerEndpoint("/swagger/v1/swagger.json", "v1");
// 设置路由前缀为空直接访问站点根目录即可看到SwaggerUI
options.RoutePrefix = String.Empty;
var groups = app.ApplicationServices.GetRequiredService<IApiDescriptionGroupCollectionProvider>().ApiDescriptionGroups.Items;
foreach (var description in groups)
{
var group = description.GroupName;
if (group.IsNullOrEmpty()) group = "v1";
options.SwaggerEndpoint($"/swagger/{group}/swagger.json", group);
}
// 设置OAuth2认证
var oauthConfigs = OAuthConfig.GetValids(GrantTypes.AuthorizationCode);
if (oauthConfigs.Count > 0)
{
var cfg = oauthConfigs[0];
//options.OAuthConfigObject = new()
//{
// AppName = cfg.Name,
// ClientId = cfg.AppId,
// ClientSecret = cfg.Secret,
//};
options.OAuthClientId(cfg.AppId);
options.OAuthClientSecret(cfg.Secret);
if (!cfg.Scope.IsNullOrEmpty()) options.OAuthScopes(cfg.Scope.Split(","));
}
});
return app;
}
}