我有一个使用 .Net 6 的自托管 Web API。它部署为窗口服务。我可以使用域名和端口从浏览器进行本地访问,但无法从另一台机器上进行访问。我已在防火墙设置中为端口定义了入站规则。这是程序.cs
var webApplicationOptions = new WebApplicationOptions() { ContentRootPath = AppContext.BaseDirectory, Args = args, ApplicationName = System.Diagnostics.Process.GetCurrentProcess().ProcessName };
var builder = WebApplication.CreateBuilder(webApplicationOptions);
builder.Host.UseWindowsService();
builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen(c =>
{
c.IncludeXmlComments(Path.Combine(AppContext.BaseDirectory,
$"{Assembly.GetExecutingAssembly().GetName().Name}.xml"));
c.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme
{
In = ParameterLocation.Header,
Description = "Please enter a valid token",
Name = "Authorization",
Type = SecuritySchemeType.Http,
BearerFormat = "JWT",
Scheme = "Bearer"
});
c.AddSecurityRequirement(new OpenApiSecurityRequirement
{
{
new OpenApiSecurityScheme
{
Reference = new OpenApiReference
{
Type=ReferenceType.SecurityScheme,
Id="Bearer"
}
},
new string[]{}
}
});
});
// generate lowercase URLs
builder.Services.Configure<RouteOptions>(options =>
{
options.LowercaseUrls = true;
});
var configurationBuilder = new ConfigurationBuilder()
.SetBasePath(AppDomain.CurrentDomain.BaseDirectory)
.AddJsonFile("appsettings.json")
.AddJsonFile($"appsettings.{builder.Environment.EnvironmentName}.json", optional: true);
var configuration = configurationBuilder.Build();
var loggerConfig = new LoggerConfiguration()
.ReadFrom.Configuration(configuration);
var logger = loggerConfig.CreateLogger();
var key = Encoding.ASCII.GetBytes(configuration["Jwt:Secret"]!);
builder.Services.AddLogging(loggingBuilder =>
{
loggingBuilder.ClearProviders();
loggingBuilder.AddSerilog(logger);
});
builder.Services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
})
// Adding Jwt Bearer
.AddJwtBearer(options =>
{
options.SaveToken = true;
options.RequireHttpsMetadata = false;
options.TokenValidationParameters = new TokenValidationParameters()
{
ValidateIssuer = true,
ValidateAudience = true,
ValidAudience = configuration["JWT:ValidAudience"],
ValidIssuer = configuration["JWT:ValidIssuer"],
IssuerSigningKey = new SymmetricSecurityKey(key)
};
options.Events = new JwtBearerEvents
{
OnChallenge = async context =>
{
// Call this to skip the default logic and avoid using the default response
context.HandleResponse();
context.Response.StatusCode = StatusCodes.Status401Unauthorized;
context.Response.ContentType = "application/json";
var result = JsonConvert.SerializeObject(new
{
code = ResponseCode.UnauthorizedDueToInvalidToken.ToCode(),
message = ResponseCode.UnauthorizedDueToInvalidToken.ToMessage(),
});
context.Response.WriteAsync(result);
}
};
});
var tokenValidationParameters = new TokenValidationParameters
{
ValidateIssuerSigningKey = true,
IssuerSigningKey = new SymmetricSecurityKey(key),
ValidateIssuer = false,
ValidateAudience = false,
ValidateLifetime = false,
RequireExpirationTime = false,
// Allow to use seconds for expiration of token
// Required only when token lifetime less than 5 minutes
// THIS ONE
ClockSkew = TimeSpan.Zero
};
builder.Services.AddSingleton(tokenValidationParameters);
var app = builder.Build();
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}
app.UseAuthentication();
app.UseAuthorization();
app.MapControllers();
app.Run();
这是 appsetting.json 中我的 Kestrel 部分
"Kestrel": {
"Endpoints": {
"Http": {
"Url": "http://0.0.0.0:7504"
},
"Https": {
"Url": "https://*:7503",
"Certificate": {
"Path": "D:/Certificates/Cert.pfx",
"Password": "********"
}
}
}
这不是任何配置或代码问题。这是主机网络上的网络安全问题。