Is there a way to avoid X-Frame-Options in a CEF Windows Chromium Desktop App? - reactjs

I created a simple app using the suggested "app init", then I dropped a pre-compiled ReactApp in place.
The app has a browser within it that uses an IFrame to host the navigated pages, but in some pages, it issues the following error:
Refused to display 'https://www.theverge.com/' in a frame because it set 'X-Frame-Options' to 'sameorigin'.", source: http://localhost:5000/#/
https://content-security-policy.com/
The page above has a series of ways to how this could be avoided, and Chromium has a flag that could help, where it disables security and as many suggested in other posts and questions, that may help with this issue.
Beyond those, there is the possibility of writing a reverse-proxy that could potentially take care of this.
Either way what I need to know is if there is a way to achieve that through parameters within the "app" tool, something like:
app --unsecure
app publish --unsecure
app publish-exe --unsecure
Thank you

I've tried a number of different options inclusing using a Custom .NET Core Desktop Apps that adds the disable-web-security switch which used to work:
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);
}
But no longer does so appears this security restriction is now embedded inside of Blink.
Using a Proxy to Remove Headers
The only solution I could get to work is to use a proxy that calls the internal .NET Core server which proxies the downstream URL but ignoring the X-Frame-Options header.
This is easy to do using ServiceStack's Proxy Feature where you can register a proxy to https://www.theverge.com that strips the X-Frame-Options header with:
Plugins.Add(new ProxyFeature(
matchingRequests: req => req.PathInfo.StartsWith("/theverge"),
resolveUrl: req => $"https://www.theverge.com" + req.RawUrl.Replace("/theverge", "/")) {
IgnoreResponseHeaders = {
"X-Frame-Options"
}
});
This will let you embed The Verge in your App with:
<iframe src="/theverge" style="width:100%; height:800px;" frameborder="0"></iframe>
Which will render TheVerge in an iframe as expected:
Working Demo
You can find a working example of this in 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" />
You'll also need to copy CEF binaries from the ServiceStack.CefGlue.Win64 NuGet package with:
<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>

Related

Communicating from react front-end with ASP.NET Core Web API on the same remote hosting panel

I have an independent react front-end and ASP.NET Core Web API (back-end) working and communicating fine on localhost. i created ClientApp folder in webApi project and copied whole react app in it.
then followed #Ringo answer on similar problem which is here
I changed the urls in both the frontend and backend from https://localhost:3000 to https://www.virtualcollege.pk.
but it's not working on remote here is link
The program.cs is:
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Hosting;
namespace WebApi
{
public class Program
{
public static void Main(string[] args)
{
CreateHostBuilder(args).Build().Run();
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>()
.UseUrls("https://www.virtualcollege.pk");
});
}
}
The startup.cs:
using AutoMapper;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.SpaServices.ReactDevelopmentServer;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.IdentityModel.Tokens;
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;
using WebApi.Helpers;
using WebApi.Services;
namespace WebApi
{
public class Startup
{
private readonly IWebHostEnvironment _env;
private readonly IConfiguration _configuration;
public Startup(IWebHostEnvironment env, IConfiguration configuration)
{
_env = env;
_configuration = configuration;
}
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
// use sql server db in production and sqlite db in development
services.AddDbContext<DataContext>();
services.AddDbContext<CourseDbContext>();
services.AddCors();
services.AddControllers();
services.AddAutoMapper(AppDomain.CurrentDomain.GetAssemblies());
// configure strongly typed settings objects
var appSettingsSection = _configuration.GetSection("AppSettings");
services.Configure<AppSettings>(appSettingsSection);
// configure jwt authentication
var appSettings = appSettingsSection.Get<AppSettings>();
var key = Encoding.ASCII.GetBytes(appSettings.Secret);
services.AddAuthentication(x =>
{
x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
x.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(x =>
{
x.Events = new JwtBearerEvents
{
OnTokenValidated = context =>
{
var userService = context.HttpContext.RequestServices.GetRequiredService<IUserService>();
var userId = int.Parse(context.Principal.Identity.Name);
var user = userService.GetById(userId);
if (user == null)
{
// return unauthorized if user no longer exists
context.Fail("Unauthorized");
}
return Task.CompletedTask;
}
};
x.RequireHttpsMetadata = false;
x.SaveToken = true;
x.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuerSigningKey = true,
IssuerSigningKey = new SymmetricSecurityKey(key),
ValidateIssuer = false,
ValidateAudience = false
};
});
// In production, the React files will be served from this directory
services.AddSpaStaticFiles(configuration =>
{
configuration.RootPath = "ClientApp/dist";
});
// configure DI for application services
services.AddScoped<IUserService, UserService>();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env, DataContext dataContext)
{
// migrate any database changes on startup (includes initial db creation)
dataContext.Database.Migrate();
app.UseRouting();
// global cors policy
app.UseCors(x => x
.AllowAnyOrigin()
.AllowAnyMethod()
.AllowAnyHeader());
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints => endpoints.MapControllers());
//add this
app.UseStaticFiles();
if (!env.IsDevelopment())
{
app.UseSpaStaticFiles();
}
app.UseSpa(spa =>
{
// To learn more about options for serving an Angular SPA
// see https://go.microsoft.com/fwlink/?linkid=864501
spa.Options.SourcePath = "ClientApp";
if (_env.IsDevelopment())
{
spa.UseReactDevelopmentServer(npmScript: "start");
}
});
}
}
}
The front end webpack.config.json is:
var HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
mode: 'development',
resolve: {
extensions: ['.js', '.jsx']
},
module: {
rules: [
{
test: /\.jsx?$/,
loader: 'babel-loader'
}
]
},
plugins: [new HtmlWebpackPlugin({
template: './src/index.html'
})],
devServer: {
historyApiFallback: true
},
output:{
filename: '[name]-bundle.js',
},
externals: {
// global app config object
config: JSON.stringify({
apiUrl: 'https://www.virtualcollege.pk'
})
}
}
I have tried many ports, either front-end works or back-end.if i use following web.config file back-end works but no index.html is return by server.
web.config is here:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<location path="." inheritInChildApplications="false">
<system.webServer>
<handlers>
<add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModule" resourceType="Unspecified" />
</handlers>
<aspNetCore processPath=".\WebApi.exe" stdoutLogEnabled="false" stdoutLogFile=".\logs\stdout" hostingModel="outprocess" />
<httpErrors>
<remove statusCode="502" subStatusCode="-1" />
<remove statusCode="501" subStatusCode="-1" />
<remove statusCode="500" subStatusCode="-1" />
<remove statusCode="412" subStatusCode="-1" />
<remove statusCode="406" subStatusCode="-1" />
<remove statusCode="405" subStatusCode="-1" />
<remove statusCode="404" subStatusCode="-1" />
<remove statusCode="403" subStatusCode="-1" />
<remove statusCode="401" subStatusCode="-1" />
<remove statusCode="400" />
<error statusCode="400" path="D:\inutpub\virtualcollege.pk\error_docs\bad_request.html" />
<remove statusCode="407" />
<error statusCode="407" path="D:\inutpub\virtualcollege.pk\error_docs\proxy_authentication_required.html" />
<remove statusCode="414" />
<error statusCode="414" path="D:\inutpub\virtualcollege.pk\error_docs\request-uri_too_long.html" />
<remove statusCode="415" />
<error statusCode="415" path="D:\inutpub\virtualcollege.pk\error_docs\unsupported_media_type.html" />
<remove statusCode="503" />
<error statusCode="503" path="D:\inutpub\virtualcollege.pk\error_docs\maintenance.html" />
<error statusCode="401" prefixLanguageFilePath="" path="D:\inutpub\virtualcollege.pk\error_docs\unauthorized.html" />
<error statusCode="403" prefixLanguageFilePath="" path="D:\inutpub\virtualcollege.pk\error_docs\forbidden.html" />
<error statusCode="404" prefixLanguageFilePath="" path="D:\inutpub\virtualcollege.pk\error_docs\not_found.html" />
<error statusCode="405" prefixLanguageFilePath="" path="D:\inutpub\virtualcollege.pk\error_docs\method_not_allowed.html" />
<error statusCode="406" prefixLanguageFilePath="" path="D:\inutpub\virtualcollege.pk\error_docs\not_acceptable.html" />
<error statusCode="412" prefixLanguageFilePath="" path="D:\inutpub\virtualcollege.pk\error_docs\precondition_failed.html" />
<error statusCode="500" prefixLanguageFilePath="" path="D:\inutpub\virtualcollege.pk\error_docs\internal_server_error.html" />
<error statusCode="501" prefixLanguageFilePath="" path="D:\inutpub\virtualcollege.pk\error_docs\not_implemented.html" />
<error statusCode="502" prefixLanguageFilePath="" path="D:\inutpub\virtualcollege.pk\error_docs\bad_gateway.html" />
</httpErrors>
</system.webServer>
</location>
</configuration>
if i use default web.config file already present httpdocs the front-end works but api calls do no work.
Thanks in advance for any help
here i have added screenshot when started on localhost by using url:https:localhost:4000 it started working fine after showing following error:
but when deploy to remote server it shows :www.virtualcollege.pk is currently unable to handle this request.http error 500
here is the launchsettings.json:
{
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iis": {
"applicationUrl": "http://localhost/WebApi",
"sslPort": 0
},
"iisExpress": {
"applicationUrl": "http://localhost:61907/",
"sslPort": 0
}
},
"profiles": {
"Development": {
"commandName": "Project",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
}
}
i am sharing so that it may be helpful for others, after days of try and error i found that there is one extra step which should take to mix the react with asp.net webapi. that is ,edit the .cspoj file and put some extra code in it.
so , i created a new react with asp.net core app from visual studio template and opened the .csproj file and copied the stuff from there to my project .csproj. now it is working fine. here is link : here

Error while use custom class when implement IProfileService. The type 'IProfileService' is defined in an assembly that is not referenced

I'm updating IdentityServer from 2.2 to 2.4. I have two projects one its entry point and another for services.
I updated both projects to 2.4 and facing an issue with:
The type 'IProfileService' is defined in an assembly that is not
referenced.
Also, I have another error:
The type 'ClaimsProfileService' cannot be used as type parameter 'T'
in the generic type or method
'IdentityServerBuilderExtensionsAdditional.AddProfileService(IIdentityServerBuilder)'.
There is no implicit reference conversion from 'ClaimsProfileService'
to 'IdentityServer4.Services.IProfileService'.
The class ClaimsProfileService implemented the interface IProfileService. It looks weird, 'cause when I downgrade IdentityServer to 2.2 it's work properly.
Actually, there present strange behavior, when I created a nested class in my Startup.cs than implemented IProfileService I got no errors.
This is my identity server confiration.
var identityServer = services.AddIdentityServer(options =>
{
options.Events.RaiseErrorEvents = true;
options.Events.RaiseInformationEvents = true;
options.Events.RaiseFailureEvents = true;
options.Events.RaiseSuccessEvents = true;
options.Authentication.CookieLifetime = TimeSpan.FromSeconds(7200);
})
// this adds the config data from DB (clients, resources, CORS)
.AddConfigurationStore(options =>
{
options.ConfigureDbContext = builder =>
builder.UseSqlServer(connectionString,
sql => sql.MigrationsAssembly(migrationsAssembly));
})
// this adds the operational data from DB (codes, tokens, consents)
.AddOperationalStore(options =>
{
options.ConfigureDbContext = builder =>
builder.UseSqlServer(connectionString,
sql => sql.MigrationsAssembly(migrationsAssembly));
// this enables automatic token cleanup. this is optional.
options.EnableTokenCleanup = true;
// options.TokenCleanupInterval = 15; // interval in seconds. 15 seconds useful for debugging
})
.AddAspNetIdentity<ApplicationUser>()
.AddProfileService<ClaimsProfileService>()
.AddExtensionGrantValidator<DelegationGrantValidator>();
This is PackageReferences for main app project.
<ItemGroup>
<PackageReference Include="IdentityServer4" Version="2.4.0" />
<PackageReference Include="IdentityServer4.AccessTokenValidation" Version="2.7.0" />
<PackageReference Include="IdentityServer4.AspNetIdentity" Version="2.4.0" />
<PackageReference Include="IdentityServer4.EntityFramework" Version="2.4.0" />
<PackageReference Include="jQuery" Version="3.3.1" />
<PackageReference Include="jQuery.Validation" Version="1.17.0" />
<PackageReference Include="Microsoft.AspNetCore.App" Version="2.2.2" />
<PackageReference Include="Microsoft.jQuery.Unobtrusive.Validation" Version="3.2.11" />
<PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="2.2.2" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="4.0.1" />
</ItemGroup>
This is PackageReferences for Services project.
<ItemGroup>
<PackageReference Include="IdentityServer4" Version="2.4.0" />
<PackageReference Include="Microsoft.AspNetCore.Identity" Version="2.2.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="2.2.2" />
</ItemGroup>
Thank for any help with this issue.
Already fixed. Just deleted from NuGet folder version 2.2 manually. Then I reinstalled IdentityServer and all work properly.

asp.net core Index.html not shows as default?

namespace MyQuotesApp
{
public class Startup
{
// This method gets called by the runtime. Use this method to add services to the container.
// For more information on how to configure your application, visit http://go.microsoft.com/fwlink/?LinkID=398940
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
loggerFactory.AddConsole();
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseDefaultFiles();
app.UseStaticFiles();
//app.Run(async (context) =>
//{
// await context.Response.WriteAsync("Hello World!");
//});
app.UseMvc();
}
}
}
UseDefaultFiles pick these files by default.
default.htm
default.html
index.htm
index.html
If that not worked in your case. You can specify name of your default file with DefaultFilesOptions.
DefaultFilesOptions options = new DefaultFilesOptions();
options.DefaultFileNames.Clear();
options.DefaultFileNames.Add("index.html");
app.UseDefaultFiles(options);
You can also use app.UseFileServer();, it combines the functionality of
app.UseDefaultFiles();
app.UseStaticFiles();
Note: UseDefaultFiles must be called before UseStaticFiles to serve the default file. UseDefaultFiles is a URL re-writer that doesn't actually serve the file. You must enable the static file middleware (UseStaticFiles) to serve the file.
P.S. also update your packages to most latest.
Try this.
app.UseMvc(config =>
{
config.MapRoute(
name: "Default",
template: "{controller=*YourControllerName*}/{action=Index}/{id?}"
);
});

FileTransfer is undefined in Cordova

I am working on Cordova tool in Visual studio.
I want to download files via given url, So for that I have installed File and FileTransfer plugins in application.
But it is giving me eror that,
FileTransfer is undefined.
I am writing it after device load.
I read somewhere that I need to activate requestFileSystem first, so I have also tried this code, but fail.
window.requestFileSystem(window.PERSISTENT, 0,
function onFileSystemSuccess(fileSystem) {
fileSystem.root.getFile(
//create a dummy file to get paths
"dummy.html", { create: true, exclusive: false },
function gotFileEntry(fileEntry) {
var sPath = fileEntry.toURL().replace("dummy.html", "");
alert("Path = " + sPath);
//invoke the method to transfer files
var fileTransfer = new FileTransfer();
//remove the dummy file
fileEntry.remove();
//and now, we can download
fileTransfer.download("http://192.168.2.32:8080/MOBILEHRServices/leaveNotifications/getAttachments/2833739", sPath,
function (theFile) {
alert("Succ");
},
function (error) {
alert("Err");
}
);
},
fail);
},
fail);
Second code is,
alert("Start");
var fileTransfer = new FileTransfer();
fileTransfer.download("http://192.168.2.32:8080/MOBILEHRServices/leaveNotifications/getAttachments/2833739", sPath,
function (theFile) {
alert("Succ");
},
function (error) {
alert("Err");
}
);
In both above code FileTransfer() undefined...
Do I need to add anyrhing else too in solution. ?
My config file is,
in visual studio, We can add plugins via wizard...
File and FileTransfer plugins...
<?xml version="1.0" encoding="utf-8"?>
<widget xmlns:cdv="http://cordova.apache.org/ns/1.0" xmlns:vs="http://schemas.microsoft.com/appx/2014/htmlapps" id="io.cordova.down" version="1.0.0.0" xmlns="http://www.w3.org/ns/widgets">
<name>down</name>
<description>A blank project that uses Apache Cordova to help you build an app that targets multiple mobile platforms: Android, iOS, Windows, and Windows Phone.</description>
<author href="http://cordova.io" email="dev#cordova.apache.org">Apache Cordova Team </author>
<content src="index.html" />
<access origin="*" />
<preference name="SplashScreen" value="screen" />
<preference name="windows-target-version" value="8.0" />
<preference name="windows-phone-target-version" value="8.1" />
<vs:plugin name="org.apache.cordova.file" version="1.3.1" />
<vs:plugin name="org.apache.cordova.file-transfer" version="0.4.6" />
<vs:platformSpecificValues />
</widget>
Thank you.

Cassette.Nancy unbundled files returning 404

I've added Cassette.Nancy to an existing Nancy web project. This works fine when I set CassetteNancyStartup.OptimizeOutput = true; but when this is set to false I get 404 on the unbundled resources.
Here's my set up.
I'm using the following packages:
Cassette.Nancy version="2.1.1"
Cassette version="2.4.1"
Nancy version="0.22.2"
Nancy.Owin version="0.22.2"
Nancy.Viewengines.Razor version="0.22.2"
The files are like so:
Content
file1.css
file2.css
Scripts
script1.js
script2.js
CassetteBundleConfiguration:
public class CassetteBundleConfiguration : IConfiguration<BundleCollection>
{
public void Configure(BundleCollection bundles)
{
bundles.AddPerSubDirectory<StylesheetBundle>("Content");
bundles.Add<ScriptBundle>("Scripts");
}
}
in my _Layout.cshtml:
#{
Bundles.Reference("Content");
Bundles.Reference("Scripts");
}
#Bundles.RenderStylesheets()
#Bundles.RenderScripts()
And finally in Bootstrapper:
public Bootstrapper()
{
CassetteNancyStartup.OptimizeOutput = false;
}
Like I say this works fine when CassetteNancyStartup.OptimizeOutput is set to true but when false each of the resources return a 404 like this one:
GET http://localhost:10005/_cassette/asset/Content/file1.css?cf7a7edf515a8184a0c53ec498c583cc64bb0e63 404 (Not Found)
Any suggestions?
This issue was down to me not adding the Owin handler in the web.config. Adding this fixed it.
<system.webServer>
<handlers>
<add name="Owin" verb="*" path="*" type="Microsoft.Owin.Host.SystemWeb.OwinHttpHandler, Microsoft.Owin.Host.SystemWeb" />
</handlers>
</system.webServer>

Resources