我试图根据登录的用户隐藏哪些端点以大摇大摆的方式显示。这是行不通的,我不明白为什么。我使用微软身份和 swashbuckle 在 HideEndpointsBasedOnUserFilter 类中,代码点击“if (!isUserInRole)”并进入此内容,但内部命令并未删除 swagger endbpoint 。这是我的代码:
[SwaggerHide("Admin")]
[HttpGet]
[Route("cabinetGatewaySvc/accesscontrol/{clientId}/{cardId}")]
public async Task<ActionResult<string>> AccessControl(string clientId, string cardId)
{
_twoTraceLogger.LogTrace("CabinetController gets called");
var result = await _canOpenPort.ValidateWearerAsync(clientId, cardId);
return Ok(result);
}
namespace MsCabinetGateway.SwaggerConfig
{
public class SwaggerHideAttribute : Attribute
{
public string RequiredRole { get; set; }
public SwaggerHideAttribute(string requiredRole)
{
RequiredRole = requiredRole;
}
}
}
public class HideEndpointsBasedOnUserFilter : IOperationFilter
{
private readonly IHttpContextAccessor _httpContextAccessor;
public HideEndpointsBasedOnUserFilter(IHttpContextAccessor httpContextAccessor)
{
_httpContextAccessor = httpContextAccessor;
}
public void Apply(OpenApiOperation operation, OperationFilterContext context)
{
var user = _httpContextAccessor.HttpContext?.User;
if (user == null || !user.Identity.IsAuthenticated)
{
return; // No authenticated user, skip filtering
}
// Check if the action has the SwaggerHideAttribute
var hideAttribute = context.MethodInfo.GetCustomAttribute<SwaggerHideAttribute
();
if (hideAttribute != null)
{
var requiredRole = hideAttribute.RequiredRole;
var isUserInRole = user.IsInRole(requiredRole);
// Log the roles and required role
Console.WriteLine($"Required role: {requiredRole}, Is user in role:
{isUserInRole}");
// If the user doesn't have the required role, hide the endpoint
if (!isUserInRole)
{
operation.Tags.Clear(); // Hide operation by removing tags
operation.Summary = null; // Optionally clear the summary
operation.Description = null; // Optionally clear the description
operation.Responses.Clear(); // Optionally clear responses
}
}
}
}
}
public class Program
{
private static AppSettings? ApplicationSettings { get; set; }
public static void Main(string[] args)
{
var builder = WebApplication.CreateBuilder(args);
var connectionString =
builder.Configuration.GetConnectionString("MsCabinetGatewayContextConnection") ??
throw
new InvalidOperationException("Connection string
'MsCabinetGatewayContextConnection'
not
found.");
builder.Services.AddDbContext<MsCabinetGatewayContext>(options =>
options.UseSqlServer(connectionString));
builder.Services.AddHttpContextAccessor();
builder.Services.AddDefaultIdentity<Areas.Identity.Data.MsCabinetGatewayUser>
(options => options.SignIn.RequireConfirmedAccount =
true).AddEntityFrameworkStores<MsCabinetGatewayContext>();
IConfiguration configuration = builder.Configuration;
ApplicationSettings = new AppSettings();
configuration.Bind(ApplicationSettings);
builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at
https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen(c => {
c.SwaggerDoc("v1", new OpenApiInfo
{
Title = "Cabinet gateway",
Version = "v1",
Description = "Cabinet gateway documentation."
});
c.OperationFilter<HideEndpointsBasedOnUserFilter>();
// Set the comments path for the Swagger JSON and UI.
var xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";
var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile);
c.IncludeXmlComments(xmlPath);
c.EnableAnnotations();
c.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme()
{
Name = "Authorization",
Type = SecuritySchemeType.ApiKey,
Scheme = "Bearer",
BearerFormat = "JWT",
In = ParameterLocation.Header,
Description =
Adapters.RestApiAdapter.Constants.RestProperties.Description,
});
c.AddSecurityRequirement(new OpenApiSecurityRequirement {
{
new OpenApiSecurityScheme {
Reference = new OpenApiReference {
Type = ReferenceType.SecurityScheme,
Id = "Bearer"
}
},
new string[] {}
}
});
builder.Services.AddHttpContextAccessor();
});
builder.Services.AddCustomConfiguration(configuration);
if (ApplicationSettings.AppInsightConfig is null)
{
ApplicationSettings.AppInsightConfig = new();
ApplicationSettings.AppInsightConfig.InstrumentationKey =
configuration.GetSection("ApplicationInsights").GetSection("InstrumentationKey").Value;
ApplicationSettings.AppInsightConfig.ConnectionString =
configuration.GetSection("ApplicationInsights").GetSection("ConnectionString").Value;
}
builder.Services.AddServiceDependencies(ApplicationSettings);
//builder.WebHost.ConfigureKestrel((context, serverOptions) =>
//{
// serverOptions.Listen(IPAddress.Any, 5000);
//});
builder.Services.AddLogging(builder =>
{
// Only Application Insights is registered as a logger provider
builder.AddApplicationInsights(
configureTelemetryConfiguration:
(config) => config.ConnectionString =
configuration["ApplicationInsights:ConnectionString"],
configureApplicationInsightsLoggerOptions: (options) => { }
);
});
var app = builder.Build();
GrpcAdapterExtention.AddServiceConfigurations(app);
//app.Use(async (context, next) =>
//{
// if (context.Request.Path.StartsWithSegments("/swagger")
// && !context.User.Identity.IsAuthenticated)
// {
// context.Response.Redirect("/Identity/Account/Login");
// return;
// }
// await next();
//});
app.UseAuthentication();
app.UseAuthorization();
app.MapRazorPages();
app.UseStaticFiles();
app.UseSwagger();
app.UseSwaggerUI();
app.UseSwagger(c =>
{
c.RouteTemplate = "cabinetGatewaySvc/swagger/{documentname}/swagger.json";
});
app.UseSwaggerUI(c =>
{
c.SwaggerEndpoint("/cabinetGatewaySvc/swagger/v1/swagger.json", "Cabinet
Gateway Microservice");
c.RoutePrefix = "cabinetGatewaySvc/swagger";
});
app.UseRouting();
app.UseEndpoints(endpoints =>
{
_ = endpoints.MapControllers();
});
app.Run();
}
}
按照@Ralf 的建议,您需要使用 IDocumentFilter 而不是 IOperationFilter 来删除 swagger 端点。