Problems with ASP.NET Core site using http.sys and Microsoft Edge - asp.net-core

I'm having a ton of problems getting an ASP.NET Core 2.1 web application up and running. I need it to run under http.sys (WebListener) on a shared port (80 or 443). I'd also like it to automatically redirect from http (80) to https (443). Of course, I don't want to hard code the listener addresses for http.sys - I need to pull those from a configuration file, but they're hard coded for now. I reserved the appropriate URLs with netsh, but when I run the app I get a warning:
warn: Microsoft.AspNetCore.Server.HttpSys.MessagePump[0]
Overriding address(es) 'http://sharedhost.vbcoa.com:80/app/, https://sharedhost.vbcoa.com:443/app/'. Binding to endpoints added to UrlPrefixes instead.
The app starts, but I can't browse to it with Microsoft Edge at all. Any other web browser is fine - as long as I disable HTTPS. For some reason, the application is forwarding to port 5001, instead of 443.

I figured all of this out. There are four problems. I'll address them each individually.
When configuring http.sys, a warning is issued about overriding local URLs
The UseHttpSys extension method of IWebHostBuilder accepts an options argument with a UrlPrefixes property. However, this is not where you should configure URLs - even if you're using http.sys. You can hardcode them with the UseUrls extension method of IWebHostBuilder, but it would be better to pull it from configuration, which leads to the second problem:
Configuration should be read from appsettings.json
To specify which URLs you want to run the application on, add them to the "urls" element in appsettings.json, as follows:
{
"Logging": {
"LogLevel": {
"Default": "Warning"
}
},
"AllowedHosts": "*",
"urls": "http://sharedhost.vbcoa.com:80/app/;https://sharedhost.vbcoa.com:443/app/"
}
Then you'll need to create a ConfigurationBuilder object, add the appsettings.json file to it, build the configuration (with the Build method) and tell IWebHostBuilder to use that configuration, with the UseConfiguration extension method:
public static void Main(string[] args)
{
var configBuilder = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.json");
var hostBuilder = WebHost.CreateDefaultBuilder(args)
.UseConfiguration(configBuilder.Build())
.UseHttpSys()
.UseStartup<Startup>();
hostBuilder.Build().Run();
}
Redirection goes to port 5001, not 443
HTTPS redirection is specified in the Configure method of Startup - that functionality comes out of the box. However, by default it will forward to port 5001, even if you have another port specified in your bound URLs from above. To override it, you need to inject HTTPS redirection options via a service. That's handled in the ConfigureServices method of Startup. Add the following line to that method:
services.AddHttpsRedirection(options => { options.HttpsPort = 443; });
Microsoft Edge won't show the web app, even though every other browser will
This is a problem with localhost loopback isolation in Windows Store apps. It seems to affect Windows 10 Enterprise, as discussed here: Microsoft Edge is not able to recognize localhost. To correct it, you need to do two things:
Make sure "Allow localhost loopback" is checked in Edge's "about:flags" page.
Launch a Command Prompt or Powershell Prompt as an Administrator and enter the following:
CheckNetIsolation LoopbackExempt -a -n=Microsoft.MicrosoftEdge_8wekyb3d8bbwe
That should do it!

Related

How to set up the remote host and Bearer configuration within Angular Template for .Net 6?

I can't find a way to figure out where is the host name configuration provided for the SPA application to connect to.
The command passed into the application from ASP.NET Core server while running the SPA is
ng serve --port 44472 --ssl --ssl-cert %APPDATA%\ASP.NET\https\%npm_package_name%.pem --ssl-key %APPDATA%\ASP.NET\https\%npm_package_name%.key
And I could not find any of the above strings localhost:7219, or 5219, or 7219 in the ClientApp / ClientApp/src folder (7219 and 5219 are the server ports and 44472 is the client npm port).
Do the server URLs passed from launchSettings.json asp project directly?
If so, if there a way to configure the server URLs directly from ClientApp if the client application is run from a different host, other than localhost (any where the settings (are | should be) stored)?
I can see the #Injected service everywhere but where does it store the settings is unclear (for how to configure this injected BASE_URL?):
constructor(http: HttpClient, #Inject('BASE_URL') baseUrl: string) {
http.get<WeatherForecast[]>(baseUrl + 'weatherforecast').subscribe((result : any) => {
this.forecasts = result;
}, (error : any) => console.error(error));
}
The derived question is: should by default the client Bearer authorization also work for a remote host?
The remote host for example is github pages. How to properly set the remote host configuration within client application for a particular webpack deployment with angular-cli-ghpages if the CORS hosts are configured within Program.cs? Should the client configuration for a remote host (apart from localhost) or server CORS configuration, include additional "Bearer-Cors" configuration (as for the certificate npm start script mentioned in the question above – should it be just skipped without any parameters passed in it)?
Are there any comprehensive guidelines on this subject?
Half of the answer to this question is that the template uses proxy config, which is described here https://angular.io/guide/build#proxying-to-a-backend-server and stores the configuration in proxy.conf.js within ClientApp folder. I will try to extend my answer with any found information in the future.
Update: The second part of the answer is to add the Cookie.SameSite = SameSiteMode.None; cookie authorization configuration in Startup.cs / Program.cs. Take a look at the solution: https://stackoverflow.com/a/75239406/6897369

Which values does WebHost read from appsettings.json

In .Net Core you can self host a web server using WebHost. There is a method called CreateDefaultBuilder(), to which the Microsoft documentation states the following:
CreateDefaultBuilder performs the following tasks:
Loads app configuration from:
appsettings.json.
However, there doesn't seem to be any documentation on which parameters you can put into appsettings.json to have the WebHost automatically get configuration values other than the default values.
For example, I tried adding the following to my appsettings.json, but the server is started with http://localhost:5000 regardless:
{
"Kestrel" : {
"urls" : "http://*:8080"
},
"server" : {
"urls" : "http://*:8080"
}
}
I know I can read appsettings.json myself using ConfigurationBuilder, but that sort of defeats the purpose of the documentation
So, what do I need to put into my appsettings.json file to have CreateDefaultBuilder() not use the default values? A list of all possible values to put into appsettings.json would be welcome as well.
Why does CreateDefaultBuilder not configure the host with appsettings.json values?
Part of the answer is to distinguish between host and app configuration. The documentation says that CreateDefaultBuilder...
Loads host configuration from:
Environment variables prefixed with ASPNETCORE_ ...
Command-line arguments.
Loads app configuration from:
appsettings.json.
appsettings.{Environment}.json.
From within CreateDefaultBuilder, the reason that appsettings.json does not automatically affect the host, is that those settings are configuring the app, and the app config does not affect the host config. The documentation indicates that when it says:
IWebHostBuilder configuration is added to the app's configuration, but the converse isn't true — ConfigureAppConfiguration doesn't affect the IWebHostBuilder configuration.
Looking at the source code shows that the CreateDefaultBuilder method only adds the appsettings.json values from within its call to ConfigureAppConfiguration. That is why those values are not automatically impacting the host.
How can we configure the host with values from a *.json file?
CreateDefaultBuilder does not automatically configure the host with a *.json file. We need to do that manually, and the documentation specifies how. In the example the file is named hostsettings.json, and the example adds it explicitly like this:
var config = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("hostsettings.json")
.Build();
return WebHost.CreateDefaultBuilder(args)
// this impacts *both* host and app config
.UseConfiguration(config)
.UseStartup<Startup>();
There is no magic in the name hostsettings.json. In fact, we could combine our host settings and our app settings into one file named appsettings.json. The way CreateDefaultBuilder works encourages us to keep those settings somewhat separate.
What keys can we put in a *.json file to configure the host?
This is the list of keys that we can use to configure the host:
"applicationName"
"startupAssembly"
"hostingStartupAssemblies"
"hostingStartupExcludeAssemblies"
"detailedErrors"
"environment"
"webroot"
"captureStartupErrors"
"urls"
"contentRoot"
"preferHostingUrls"
"preventHostingStartup"
"suppressStatusMessages"
"shutdownTimeoutSeconds"

Unable To Bind To Other Port with UseUrls

The following code just won't change the port to 9874. It stays the same in Project -> Debug -> Web Server Settings -> App URL -> "http://localhost:56021/", which uses the 56021 port. I am using VS 2017 to create .net core webapi project.
public static IWebHost BuildWebHost(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>()
.UseUrls("http://localhost:9874")
.Build();
It is the same even i change to Release mode.
Solve it by changing launchSettings.json.
If the setting is set in the above file, then what is the point to have UseUrls as it always refer to launchsettings.json setting?
In Project -> Debug -> Web Server Settings you see is a project profile that is used only when you try to run app from VS.
And in VS this is the responsibility of launchSettings.json to store and retrieve project configuration settings needed to run a project from VS only. In other words, launchSettings.json is ignored if you run app outside of VS (let's say from command line for example).
And back to .UseUrls method: it doesn't (and cannot, mainly because your app doesn't know about profiles at all) change above project profiles. Yes, this method indicates the IP addresses or host addresses with ports and protocols that the server should listen on for requests. But those settings will be applied to the Server instance that will be created on app start.

SSL meteor Not Working.. Stuck in Spinner (loads nav bar and sidebar but nothing else)

I've been having an issue for days and I don't know how to fix it.
I am trying to setup my SSL certificate, and for some reason the site works on http, and then when I try to load https, it loads only the navbar and sidebar, and then it's stuck on the spinner.
When I examine at the network connections on chrome, it keeps trying to load xhr and websockets.
In safari I get this error in the console
WebSocket connection to 'wss://mysite/sockjs/530/72iokiqa/websocket' failed: WebSocket is closed before the connection is established
I am trying to set the headers, in particular the x-forwarded-proto header, but I can't figure out how to do that.
I am using mup.
// Configure environment
"env": {
"ROOT_URL": "https://inslim.com"
},
"ssl": {
"pem": "./ssl.pem"
}
For some reason, when I try to add a por to the env variable, it won't allow me to do mup deploy. It will break and the site will go down.
I am also confused with nginx. I installed it and I set it up, but I don't think it's making any difference. If I run 'service nginx stop' or service nginx start, it doesn't make any difference.
Can someone help me? Any advice or anything would help. Or if you need any other info please let me know.
Here's a screenshot of my spinner of death
The ssl part of your configuration JSON looks fine, but your env part needs a little modification. The env part of the configuration JSON should at least look something like this:
"env": {
"PORT": 80, // Defaults to 80, but could be different if app is configured differently
"ROOT_URL": "http://inslim.com"
}
If you do not have the force-ssl package already added to your application, I would suggest adding that (don't worry, it is a core Meteor package). If you do not also have the spiderable package added to your application, then your ROOT_URL element in your JSON can remain prefixed with http, but if you do have the spiderable package added to your application, you will need to change that ROOT_URL element prefix in your JSON to be https. All of this information is per the documentation for Meteor Up, which can be found here. Also, I can confirm that this setup with the JSON works because I have a production application that is running with this exact setup without any issues.

Grails generating proper links when deployed behind proxy

Consider the following setup for a deployed Grails application.
the Grails application is deployed on a Tomcat server (tomcat7)
in front of Tomcat an Apache webserver is deployed
Apache does SSL offloading, and acts as a proxy for Tomcat
So far a quite standard setup, which I have used succesfully many times. My issue is now with the links generated by the Grails application, especially those for the redirects (the standard controller redirects, which occur all the time e.g. after succesfully posting a form).
One configuration is different from all the other applications so far: in this Grails application no serverURL is configured. The application is a multi-tenant application, where each tenant is given it's own subdomain. (So if the application in general is running under https://www.example.com, a tenant can use https://tenant.example.com.) Subdomains are set automagically, that is without any configuration at DNS or Apache level. Grails can do so perfectly, by leaving out the serverURL property in Config.groovy: it then resolves all url's by inspecting the client host.
However: when generating redirect-url's, Grails is not aware the website is running under https. All redirect url's start with http... I guess this is no surprise, because nowhere in the application it is configured we are using https: there is no serverURL config, and technically the application is running on the standard http port of Tomcat, because of the SSL offloading and proxying by Apache.
So, bottom line: what can I do to make Grails generate proper redirects?
I have tried to extend the DefaultLinkGenerator and override the makeServerURL() method. Like this:
class MyLinkGenerator extends DefaultLinkGenerator {
MyLinkGenerator(String serverBaseURL, String contextPath) {
super(serverBaseURL, contextPath)
}
MyLinkGenerator(String serverBaseURL) {
super(serverBaseURL)
}
def grailsApplication
/**
* #return serverURL adapted to deployed scheme
*/
String makeServerURL() {
// get configured protocol
def scheme = grailsApplication.config.grails.twt.baseProtocol ?: 'https://'
println "Application running under protocol $scheme"
// get url from super
String surl = super.makeServerURL()
println "> super.makeServerURL(): $surl"
if (surl) {
// if super url not matching scheme, change scheme
if (scheme=='https://' && surl?.startsWith('http://')) {
surl = scheme + surl?.substring(7)
println "> re-written: $surl"
}
}
return surl
}
}
(Maybe not the most beautiful code, but I hope it explains what I'd like to do. And I left out the bit about configuring this class in resources.groovy.)
When running this code strange things happen:
In the log you see the code being executed, and a changed url (http > https) being produced, but...
The redirect sent to the browser is the unchanged url (http)
And even worse: all the resources in the generated views are crippled: they now all start with // (so what should be a relative "/css/myapp.css" is now "//css/myapp.css")
Any help or insight would be appreciated!
Grails version is 2.1.1 by the way (running a bit behind on upgrades...).
It seems you're always talking https to the outside world, so your cleanest option is to solve the problem where it originates, at your Apache webserver. Add to httpd.conf Header edit Location ^http://(.*)$ https://$1, and you're done.
If you have limitations that force you to solve this in your application you could do the rewrite of the Location header field in a Grails after interceptor. Details of that solution are in this post.
Some years have past since this question was written, but problems remain the same or at least similar ;-)
Just in case anyone hits the same/similar issue (that Grails redirect-URLs are http instead of https) ... We had this issue with a Grails 3.3.9 application running on OpenShift. The application was running in HTTP mode (on Port 8080) and the OpenShift Loadbalancer was doing the SSL-Termination.
We solved it by putting
server:
use-forward-headers: true
into our application.yml. After that Grails works perfect and all the redirects created were correct with https://.
Hint: We have do not use grails.serverURL in our configuration