Nekromancja.
Podane odpowiedzi są niekompletne.
Po pierwsze, jak już powiedziano, nie można dodać wielu hostów z zezwoleniem, to nie jest obsługiwane.
Po drugie, musisz dynamicznie wyodrębnić tę wartość ze strony odsyłającej HTTP, co oznacza, że nie możesz dodać wartości do Web.config, ponieważ nie zawsze jest to ta sama wartość.
Konieczne będzie wykonanie wykrywania przeglądarki, aby uniknąć dodawania zezwalania z przeglądarki Chrome (powoduje to błąd w konsoli debugowania, która może szybko zapełnić konsolę lub spowolnić aplikację). Oznacza to również, że musisz zmodyfikować wykrywanie przeglądarki ASP.NET, ponieważ błędnie identyfikuje ona Edge jako Chrome.
Można to zrobić w ASP.NET, pisząc moduł HTTP, który działa na każde żądanie, który dołącza nagłówek http dla każdej odpowiedzi, w zależności od strony odsyłającej żądania. W przypadku Chrome musi dodać politykę bezpieczeństwa treści.
// /programming/31870789/check-whether-browser-is-chrome-or-edge
public class BrowserInfo
{
public System.Web.HttpBrowserCapabilities Browser { get; set; }
public string Name { get; set; }
public string Version { get; set; }
public string Platform { get; set; }
public bool IsMobileDevice { get; set; }
public string MobileBrand { get; set; }
public string MobileModel { get; set; }
public BrowserInfo(System.Web.HttpRequest request)
{
if (request.Browser != null)
{
if (request.UserAgent.Contains("Edge")
&& request.Browser.Browser != "Edge")
{
this.Name = "Edge";
}
else
{
this.Name = request.Browser.Browser;
this.Version = request.Browser.MajorVersion.ToString();
}
this.Browser = request.Browser;
this.Platform = request.Browser.Platform;
this.IsMobileDevice = request.Browser.IsMobileDevice;
if (IsMobileDevice)
{
this.Name = request.Browser.Browser;
}
}
}
}
void context_EndRequest(object sender, System.EventArgs e)
{
if (System.Web.HttpContext.Current != null && System.Web.HttpContext.Current.Response != null)
{
System.Web.HttpResponse response = System.Web.HttpContext.Current.Response;
try
{
// response.Headers["P3P"] = "CP=\\\"IDC DSP COR ADM DEVi TAIi PSA PSD IVAi IVDi CONi HIS OUR IND CNT\\\"":
// response.Headers.Set("P3P", "CP=\\\"IDC DSP COR ADM DEVi TAIi PSA PSD IVAi IVDi CONi HIS OUR IND CNT\\\"");
// response.AddHeader("P3P", "CP=\\\"IDC DSP COR ADM DEVi TAIi PSA PSD IVAi IVDi CONi HIS OUR IND CNT\\\"");
response.AppendHeader("P3P", "CP=\\\"IDC DSP COR ADM DEVi TAIi PSA PSD IVAi IVDi CONi HIS OUR IND CNT\\\"");
// response.AppendHeader("X-Frame-Options", "DENY");
// response.AppendHeader("X-Frame-Options", "SAMEORIGIN");
// response.AppendHeader("X-Frame-Options", "AllowAll");
if (System.Web.HttpContext.Current.Request.UrlReferrer != null)
{
// "X-Frame-Options": "ALLOW-FROM " Not recognized in Chrome
string host = System.Web.HttpContext.Current.Request.UrlReferrer.Scheme + System.Uri.SchemeDelimiter
+ System.Web.HttpContext.Current.Request.UrlReferrer.Authority
;
string selfAuth = System.Web.HttpContext.Current.Request.Url.Authority;
string refAuth = System.Web.HttpContext.Current.Request.UrlReferrer.Authority;
// SQL.Log(System.Web.HttpContext.Current.Request.RawUrl, System.Web.HttpContext.Current.Request.UrlReferrer.OriginalString, refAuth);
if (IsHostAllowed(refAuth))
{
BrowserInfo bi = new BrowserInfo(System.Web.HttpContext.Current.Request);
// bi.Name = Firefox
// bi.Name = InternetExplorer
// bi.Name = Chrome
// Chrome wants entire path...
if (!System.StringComparer.OrdinalIgnoreCase.Equals(bi.Name, "Chrome"))
response.AppendHeader("X-Frame-Options", "ALLOW-FROM " + host);
// unsafe-eval: invalid JSON https://github.com/keen/keen-js/issues/394
// unsafe-inline: styles
// data: url(data:image/png:...)
// https://www.owasp.org/index.php/Clickjacking_Defense_Cheat_Sheet
// https://www.ietf.org/rfc/rfc7034.txt
// https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Frame-Options
// https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP
// /programming/10205192/x-frame-options-allow-from-multiple-domains
// https://content-security-policy.com/
// http://rehansaeed.com/content-security-policy-for-asp-net-mvc/
// This is for Chrome:
// response.AppendHeader("Content-Security-Policy", "default-src 'self' 'unsafe-inline' 'unsafe-eval' data: *.msecnd.net vortex.data.microsoft.com " + selfAuth + " " + refAuth);
System.Collections.Generic.List<string> ls = new System.Collections.Generic.List<string>();
ls.Add("default-src");
ls.Add("'self'");
ls.Add("'unsafe-inline'");
ls.Add("'unsafe-eval'");
ls.Add("data:");
// http://az416426.vo.msecnd.net/scripts/a/ai.0.js
// ls.Add("*.msecnd.net");
// ls.Add("vortex.data.microsoft.com");
ls.Add(selfAuth);
ls.Add(refAuth);
string contentSecurityPolicy = string.Join(" ", ls.ToArray());
response.AppendHeader("Content-Security-Policy", contentSecurityPolicy);
}
else
{
response.AppendHeader("X-Frame-Options", "SAMEORIGIN");
}
}
else
response.AppendHeader("X-Frame-Options", "SAMEORIGIN");
}
catch (System.Exception ex)
{
// WTF ?
System.Console.WriteLine(ex.Message); // Suppress warning
}
} // End if (System.Web.HttpContext.Current != null && System.Web.HttpContext.Current.Response != null)
} // End Using context_EndRequest
private static string[] s_allowedHosts = new string[]
{
"localhost:49533"
,"localhost:52257"
,"vmcompany1"
,"vmcompany2"
,"vmpostalservices"
,"example.com"
};
public static bool IsHostAllowed(string host)
{
return Contains(s_allowedHosts, host);
} // End Function IsHostAllowed
public static bool Contains(string[] allowed, string current)
{
for (int i = 0; i < allowed.Length; ++i)
{
if (System.StringComparer.OrdinalIgnoreCase.Equals(allowed[i], current))
return true;
} // Next i
return false;
} // End Function Contains
Musisz zarejestrować funkcję context_EndRequest w funkcji Init modułu HTTP.
public class RequestLanguageChanger : System.Web.IHttpModule
{
void System.Web.IHttpModule.Dispose()
{
// throw new NotImplementedException();
}
void System.Web.IHttpModule.Init(System.Web.HttpApplication context)
{
// /programming/441421/httpmodule-event-execution-order
context.EndRequest += new System.EventHandler(context_EndRequest);
}
// context_EndRequest Code from above comes here
}
Następnie musisz dodać moduł do swojej aplikacji. Możesz to zrobić programowo w Global.asax, zastępując funkcję Init HttpApplication, na przykład:
namespace ChangeRequestLanguage
{
public class Global : System.Web.HttpApplication
{
System.Web.IHttpModule mod = new libRequestLanguageChanger.RequestLanguageChanger();
public override void Init()
{
mod.Init(this);
base.Init();
}
protected void Application_Start(object sender, System.EventArgs e)
{
}
protected void Session_Start(object sender, System.EventArgs e)
{
}
protected void Application_BeginRequest(object sender, System.EventArgs e)
{
}
protected void Application_AuthenticateRequest(object sender, System.EventArgs e)
{
}
protected void Application_Error(object sender, System.EventArgs e)
{
}
protected void Session_End(object sender, System.EventArgs e)
{
}
protected void Application_End(object sender, System.EventArgs e)
{
}
}
}
lub możesz dodać wpisy do Web.config, jeśli nie jesteś właścicielem kodu źródłowego aplikacji:
<httpModules>
<add name="RequestLanguageChanger" type= "libRequestLanguageChanger.RequestLanguageChanger, libRequestLanguageChanger" />
</httpModules>
</system.web>
<system.webServer>
<validation validateIntegratedModeConfiguration="false"/>
<modules runAllManagedModulesForAllRequests="true">
<add name="RequestLanguageChanger" type="libRequestLanguageChanger.RequestLanguageChanger, libRequestLanguageChanger" />
</modules>
</system.webServer>
</configuration>
Wpis w system.webServer jest przeznaczony dla IIS7 +, drugi w system.web dla IIS 6.
Należy pamiętać, że należy ustawić runAllManagedModulesForAllRequests na true, aby działał poprawnie.
Ciąg znaków w typie ma format "Namespace.Class, Assembly"
. Zauważ, że jeśli napiszesz swój zestaw w VB.NET zamiast w C #, VB utworzy domyślną przestrzeń nazw dla każdego projektu, więc twój ciąg będzie wyglądał jak
"[DefaultNameSpace.Namespace].Class, Assembly"
Jeśli chcesz uniknąć tego problemu, napisz bibliotekę DLL w języku C #.