【问题标题】:Is there a way to avoid X-Frame-Options in a CEF Windows Chromium Desktop App?有没有办法在 CEF Windows Chromium 桌面应用程序中避免 X-Frame-Options?
【发布时间】:2019-04-11 22:10:54
【问题描述】:

我使用建议的“app init”创建了一个简单的应用程序,然后我删除了一个预编译的 ReactApp。 该应用程序中有一个浏览器,它使用 IFrame 来托管导航页面,但在某些页面中,它会发出以下错误:

拒绝在框架中显示 'https://www.theverge.com/',因为它将 'X-Frame-Options' 设置为 'sameorigin'。”,来源:http://localhost:5000/#/

https://content-security-policy.com/

上面的页面有一系列方法可以避免这种情况,Chromium 有一个可以提供帮助的标志,它会禁用安全性,并且正如其他帖子和问题中所建议的那样,这可能有助于解决这个问题。

除此之外,还有可能编写一个反向代理来解决这个问题。

无论哪种方式,我都需要知道是否有办法通过“app”工具中的参数来实现这一点,例如:

app --unsecure
app publish --unsecure
app publish-exe --unsecure

谢谢

【问题讨论】:

标签: reactjs windows servicestack chromium-embedded


【解决方案1】:

我尝试了许多不同的选项,包括使用 Custom .NET Core Desktop Apps 添加过去工作的 disable-web-security 开关:

static int Main(string[] args)
{
    var host = new WebHostBuilder()
        .UseKestrel()
        .UseContentRoot(Directory.GetCurrentDirectory())
        .UseStartup<Startup>()
        .UseUrls("http://localhost:5000/")
        .Build();

    host.StartAsync();

    var config = new CefConfig(Debug)
    {
        Args = args,
        StartUrl = startUrl,
        HideConsoleWindow = false,
        OnBeforeCommandLineProcessing = (processType, commandLine) => {
            commandLine.AppendSwitch("disable-web-security");                    
        }
    };

    return CefPlatformWindows.Start(config);
}

但现在看来,此安全限制已嵌入 Blink 内部,但不再这样做了。

使用代理删除标头

我可以开始工作的唯一解决方案是使用调用内部 .NET Core 服务器的代理,该服务器代理下游 URL,但忽略 X-Frame-Options 标头。

使用 ServiceStack 的 Proxy Feature 很容易做到这一点,您可以在其中向 https://www.theverge.com 注册一个代理,该代理使用以下内容去除 X-Frame-Options 标头:

Plugins.Add(new ProxyFeature(
    matchingRequests: req => req.PathInfo.StartsWith("/theverge"),
    resolveUrl: req => $"https://www.theverge.com" + req.RawUrl.Replace("/theverge", "/")) {
    IgnoreResponseHeaders = {
        "X-Frame-Options"
    }
});

这将让您将 The Verge 嵌入到您的应用中:

<iframe src="/theverge" style="width:100%; height:800px;" frameborder="0"></iframe>

这将按预期在 iframe 中呈现 TheVerge:

工作演示

您可以在 ServiceStack.CefGlue.Win64.AspNetCore 中找到一个工作示例:

Startup.cs

public class Startup
{
    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
        app.UseServiceStack(new AppHost());

        app.Run(context =>
        {
            context.Response.Redirect("/metadata");
            return Task.FromResult(0);
        });
    }
}

public class AppHost : AppHostBase
{
    public AppHost() : base("MyApp", typeof(MyServices).Assembly) { }

    public override void Configure(Container container)
    {
        Plugins.Add(new SharpPagesFeature());

        Plugins.Add(new ProxyFeature(
            matchingRequests: req => req.PathInfo.StartsWith("/theverge"),
            resolveUrl: req => "https://www.theverge.com" + 
                                req.RawUrl.Replace("/theverge", "/")) {
            IgnoreResponseHeaders = {
                "X-Frame-Options"
            }
        });
    }
}

[Route("/hello")]
public class Hello : IReturn<HelloResponse>
{
    public string Name { get; set; }
}

public class HelloResponse
{
    public string Result { get; set; }
}

public class MyServices : Service
{
    public object Any(Hello request) => 
        new HelloResponse { Result = $"Hello, {request.Name}!" };
}

ServiceStack.CefGlue.Win64.AspNetCore.csproj

<PackageReference Include="Microsoft.AspNetCore.Server.Kestrel" Version="2.*" />
<PackageReference Include="ServiceStack.CefGlue.Win64" Version="5.*" />
<PackageReference Include="ServiceStack" Version="5.*" />
<PackageReference Include="ServiceStack.CefGlue" Version="5.*" />
<PackageReference Include="ServiceStack.CefGlue.Win64" Version="5.*" />
<PackageReference Include="WinApi" Version="4.0.0" />

您还需要从ServiceStack.CefGlue.Win64 NuGet 包中复制 CEF 二进制文件:

<ItemGroup>
    <Content Include="locales\*.*">
        <CopyToOutputDirectory>Always</CopyToOutputDirectory>
    </Content>
    <Content Include="swiftshader\*.*">
        <CopyToOutputDirectory>Always</CopyToOutputDirectory>
    </Content>
    <Content Include="*.pak">
        <CopyToOutputDirectory>Always</CopyToOutputDirectory>
    </Content>
    <Content Include="*.lib">
        <CopyToOutputDirectory>Always</CopyToOutputDirectory>
    </Content>
    <Content Include="*.dat">
        <CopyToOutputDirectory>Always</CopyToOutputDirectory>
    </Content>
    <Content Include="*.dll">
        <CopyToOutputDirectory>Always</CopyToOutputDirectory>
    </Content>
    <Content Include="*.bin">
        <CopyToOutputDirectory>Always</CopyToOutputDirectory>
    </Content>
    <Content Include="*.exe">
        <CopyToOutputDirectory>Always</CopyToOutputDirectory>
    </Content>
    </ItemGroup>

    <Target Name="CopyLinkedContentFiles" BeforeTargets="Build">
    <Copy SourceFiles="%(Content.Identity)"
            DestinationFiles="$(OutputPath)\%(Content.Link)"
            SkipUnchangedFiles="true"
            OverwriteReadOnlyFiles="true" />
</Target>

index.html

<!DOCTYPE html>
<html lang="en">
<body>
    <h1>X-Frame-Options Proxy Test</h1>
    <iframe src="/theverge" style="width:100%; height:800px;" frameborder="0"></iframe>
</body>
</html>

【讨论】:

  • 今天晚些时候我会试试这个,如果它成功了,会告诉你。它可能不会,因为用户可以导航到任何页面,它是一个浏览器,边缘只是问题的一个例子,但我会看看我如何适应它。谢谢。
  • 尝试运行该应用程序,但我得到的只是一个空白页面,似乎它永远无法到达 index.html 页面
猜你喜欢
  • 2014-08-15
  • 1970-01-01
  • 2012-05-30
  • 1970-01-01
  • 1970-01-01
  • 2017-11-18
  • 2020-06-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多