네크 로맨싱.
제공된 답변이 불완전합니다.
첫째, 이미 말했듯이 지원되지 않는 여러 허용 호스트를 추가 할 수 없습니다.
둘째, HTTP 리퍼러에서 해당 값을 동적으로 추출해야합니다. 즉, 항상 같은 값이 아니기 때문에 Web.config에 값을 추가 할 수 없습니다.
브라우저가 Chrome 일 때 allow-from을 추가하지 않도록 브라우저 감지를 수행해야합니다 (디버그 콘솔에 오류가 발생하여 콘솔이 빠르게 채워지거나 애플리케이션 속도가 느려질 수 있음). 또한 Edge를 Chrome으로 잘못 식별하므로 ASP.NET 브라우저 감지를 수정해야합니다.
이것은 모든 요청에서 실행되는 HTTP 모듈을 작성하여 ASP.NET에서 수행 할 수 있으며 요청의 리퍼러에 따라 모든 응답에 http-header를 추가합니다. Chrome의 경우 Content-Security-Policy를 추가해야합니다.
// /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
HTTP 모듈 Init 함수에 context_EndRequest 함수를 등록해야합니다.
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
}
다음으로 애플리케이션에 모듈을 추가해야합니다. 다음과 같이 HttpApplication의 Init 함수를 재정 의하여 Global.asax에서 프로그래밍 방식으로이 작업을 수행 할 수 있습니다.
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)
{
}
}
}
또는 응용 프로그램 소스 코드를 소유하지 않은 경우 Web.config에 항목을 추가 할 수 있습니다.
<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>
system.webServer의 항목은 IIS7 + 용이고, system.web의 다른 항목은 IIS 6
용입니다. 제대로 작동하려면 runAllManagedModulesForAllRequests를 true로 설정해야합니다.
type의 문자열은 형식 "Namespace.Class, Assembly"
입니다. C # 대신 VB.NET에서 어셈블리를 작성하는 경우 VB는 각 프로젝트에 대한 기본 네임 스페이스를 생성하므로 문자열은 다음과 같습니다.
"[DefaultNameSpace.Namespace].Class, Assembly"
이 문제를 피하려면 DLL을 C #으로 작성하십시오.