asp.net-core - ASP.NET Core 3.1 图像 URL 错误代码 302 重定向
问题描述
ASP.NET Core 3.1 网站托管在使用 https 的 IIS 的 Windows 服务器上。
尝试访问特定文件夹中的图像时,图像无法显示,请求重定向到登录页面。
重定向失败的图像路径示例:
https://example.com/samadhi/staff/6890.jpg
https://example.com/samadhi/staff/logo2.jpg
有效的图像路径示例:
https://example.com/samadhi/mms/qrcode15.jpg
https://example.com/samadhi/body_map.jpg
- 我有其他文件夹中的图像可以正常工作 - 它仅发生在一个文件夹中的图像上。
- 我检查了文件夹和文件权限,但它们都具有完全访问权限。
- 我尝试删除文件夹和文件并重新上传它们,但没有任何变化。
- 最初托管该网站时,这些图像工作正常。
- 问题开始于几周前。
- 我在文件夹中添加了一个文本文件进行测试,但它也会重定向。
在 Plesk 控制面板中,我看到“IIS 访问”条目,如下所示:
302 GET /samadhi/staff/UserPic.jpg - HTTP/2
302 GET /samadhi/staff/318.jpg - HTTP/1.1
其他更详细的“ModSecurity”条目显示如下:
3891110101670432115 124.171.83.143 80 127.0.0.1 80
--6c3d0000-B--
GET /samadhi/staff/6890.jpg HTTP/1.1
Host: example.net.au
User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.2; WOW64; Trident/7.0; .NET4.0C; .NET4.0E; .NET CLR 2.0.50727; .NET CLR 3.0.30729; .NET CLR 3.5.30729; Tablet PC 2.0; Zoom 3.6.0)
--6c3d0000-F--
HTTP/1.1 500 Internal Server Error
--6c3d0000-H--
Message: Warning. Match of "pm AppleWebKit Android" against "REQUEST_HEADERS:User-Agent" required. [file "C:\/Program Files (x86)/Plesk/ModSecurity/rules/modsecurity_crs-plesk/rules/REQUEST-920-PROTOCOL-ENFORCEMENT.conf"] [line "1228"] [id "920300"] [msg "Request Missing an Accept Header"] [severity "NOTICE"] [ver "OWASP_CRS/3.3.0"] [tag "application-multi"] [tag "language-multi"] [tag "platform-multi"] [tag "attack-protocol"] [tag "OWASP_CRS"] [tag "capec/1000/210/272"] [tag "PCI/6.5.10"] [tag "paranoia-level/2"]
Apache-Handler: IIS
Stopwatch: 1632221945009248 4997 (- - -)
Stopwatch2: 1632221945009248 4997; combined=4997, p1=4997, p2=0, p3=0, p4=0, p5=0, sr=4997, sw=0, l=0, gc=0
Producer: ModSecurity for IIS (STABLE)/2.9.3 (http://www.modsecurity.org/); OWASP_CRS/3.3.0.
Server: ModSecurity Standalone
Engine-Mode: "ENABLED"
--6c3d0000-Z--
--84670000-A--
启动.cs
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
public void ConfigureServices(IServiceCollection services)
{
try
{
services.AddRazorPages()
.AddRazorRuntimeCompilation();
services.AddControllersWithViews();
services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
.AddCookie(CookieAuthenticationDefaults.AuthenticationScheme, o =>
{
o.ExpireTimeSpan = new TimeSpan(90, 0, 0, 0);
o.AccessDeniedPath = new PathString("/Samadhi/SignIn/");
o.LoginPath = new PathString("/Samadhi/SignIn/");
o.LogoutPath = new PathString("/Samadhi/SignOut/");
var defaultCallback = o.Events.OnRedirectToLogin;
o.Events.OnRedirectToLogin = context =>
{
if (context.Request.Path.StartsWithSegments(new PathString("/samadhi"), StringComparison.OrdinalIgnoreCase))
{
context.RedirectUri = "/Samadhi/SignIn/";
context.Response.Redirect(context.RedirectUri);
}
else if (context.Request.Path.StartsWithSegments(new PathString("/consultant"), StringComparison.OrdinalIgnoreCase))
{
context.RedirectUri = "/Consultant/SignIn/";
context.Response.Redirect(context.RedirectUri);
}
else if (context.Request.Path.StartsWithSegments(new PathString("/candidate"), StringComparison.OrdinalIgnoreCase))
{
context.RedirectUri = "/Candidate/SignIn/";
context.Response.Redirect(context.RedirectUri);
}
return defaultCallback(context);
};
o.Validate();
});
services.AddScoped<CustomCookieAuthenticationEvents>();
services.Configure<Microsoft.AspNetCore.Identity.IdentityOptions>(o =>
{
// Password settings
o.Password.RequireDigit = true;
o.Password.RequireLowercase = true;
o.Password.RequireNonAlphanumeric = true;
o.Password.RequireUppercase = true;
o.Password.RequiredLength = 8;
o.Password.RequiredUniqueChars = 1;
// Lockout settings
o.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromMinutes(5);
o.Lockout.MaxFailedAccessAttempts = 5;
o.Lockout.AllowedForNewUsers = true;
// User settings
o.User.AllowedUserNameCharacters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._@+";
o.User.RequireUniqueEmail = true;
});
// add detection services container and device resolver service
services.AddDetectionCore()
.AddDevice();
// google recaptcha
services.Configure<ReCAPTCHASettings>(Configuration.GetSection("GooglereCAPTCHA"))
.AddTransient<ReCAPTCHAService>();
// services.AddRouting(options => options.LowercaseUrls = true);
services.AddMvc();
services.AddAntiforgery();
services.Configure<MvcOptions>(options =>
{
options.Filters.Add(new RequireHttpsAttribute());
});
}
catch (Exception ex)
{
gFunc.ProcessError(ex);
}
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
try
{
// set file path
gFunc.SetLogFilePaths(Directory.GetCurrentDirectory());
// environment
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
app.UseHsts();
}
app.UseStaticFiles();
app.UseHttpsRedirection();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
});
var provider = new FileExtensionContentTypeProvider();
provider.Mappings.Add(".exe", "application/octect-stream");
app.UseStaticFiles(new StaticFileOptions
{
FileProvider = new PhysicalFileProvider(Path.Combine(Directory.GetCurrentDirectory(), "canvas")),
RequestPath = "/canvas",
ServeUnknownFileTypes = true,
DefaultContentType = "plain/text",
ContentTypeProvider = provider
});
provider = new FileExtensionContentTypeProvider();
provider.Mappings.Add(".exe", "application/octect-stream");
app.UseStaticFiles(new StaticFileOptions
{
FileProvider = new PhysicalFileProvider(Path.Combine(Directory.GetCurrentDirectory(), "samadhi")),
RequestPath = "/samadhi",
ServeUnknownFileTypes = true,
DefaultContentType = "plain/text",
ContentTypeProvider = provider
});
}
catch (Exception ex)
{
gFunc.ProcessError(ex);
}
}
}
网页配置
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<location path="." inheritInChildApplications="false">
<system.webServer>
<handlers>
<add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModuleV2" resourceType="Unspecified"/>
</handlers>
<aspNetCore processPath="dotnet" arguments=".\Samadhi.dll" stdoutLogEnabled="false" stdoutLogFile=".\logs\stdout" hostingModel="inprocess"/>
</system.webServer>
</location>
<system.web>
<compilation tempDirectory="C:\Inetpub\vhosts\example.com\tmp"/>
</system.web>
<system.webServer>
<tracing>
<traceFailedRequests>
<clear/>
</traceFailedRequests>
</tracing>
</system.webServer>
</configuration>
<!--ProjectGuid: b79c90dc-200d-42a3-a1c4-d3d389a66244-->
解决方案
傻我!
我站点的一个控制器(一个名为“Samadhi”的控制器)有一个简单地称为“Staff”的路由。我完全忘记了这条路线,当然它与图像路径冲突(静态文件路径:/samadhi/staff/001.jpg)
我将路线重命名为“ManageStaff”,现在图像 url 工作正常。
违规路线:
[HttpGet]
[Authorize(Roles = gFunc.CLAIM_ROLE_SAMADHI_SHOP)]
public async Task<ViewResult> Staff()
{
}
推荐阅读
- python - 用日期替换 Pandas 数据框值
- reactjs - 如何访问 React.Children 或 props.children 中的数据?
- architecture - Should Frontend or Backend handles currency conversions?
- python - Django EmailMessage.content_type = 'html' keep newlines?
- java - 字符串月-年到本地日期
- r - 在 R 中的多个文件中重复相同的操作
- sql - 如何选择在过去 30 天内登录的客户,current_date - 30 在 Oracle SQL、HiveQL 中不起作用?
- sql - SQL创建不同团队之间的胜率表?
- c# - 为什么当搜索词具有“-A”后缀时,DtSearch 找不到任何匹配项?
- python - psycopg2 不使用 Python 3.8.8 连接到 Greenplum PostgreSQL DB。OperationalError:收到对 GSSAPI 协商的无效响应: