How do I enable IIS Express to serve external requests - visual-studio-2022

This is a re-post of an earlier issue. After a long hiatus with respect to this topic I am back to it again.
I need to make my local dev IIS Express instance available to colleagues for testing purposes. After much reading and many blind alleys, I managed to get a little bit further than I did when this was originally posted, in that I have managed to get VS 2022 to recognise the entries from the applicationHost.config that are needed, unfortunately when I debug the website, IIS Express (or rather MS Edge) responds with:
Hmmm... Cant reach this page
machinename.euro.org.local refused to connect
Note the URL is obfuscated for security reasons.
The applicationHost.config file contains the following entries:
...
<site name="appName" id="1">
<application path="/" applicationPool="Clr4IntegratedAppPool">
<virtualDirectory path="/" physicalPath="C:\appPath\appName" />
</application>
<bindings>
<binding protocol="http" bindingInformation="*:8080:machinename.euro.org.local" />
<binding protocol="https" bindingInformation="*:44379:machinename.euro.org.local" />
</bindings>
</site>
VS confirms that the virtual directory has been successfully created.
I have made the necessary additions to HTTP.SYS:
netsh http add urlacl url=http://machinename.euro.org.local:8080/ user=everyone
and to my firewall settings:
netsh firewall add portopening TCP 8080 IISExpressWeb enable ALL
Where am I going wrong?

Related

Visual Studio 2017 Enable SSL

How do you enable SSL for a project in Visual Studio 2017?
In VS15, I could select Project -> Properties -> Debug -> Enable SSL. This option is not available in VS2017. Where has it moved to?
Edit:
I've even tried editing .\vs\config\applicationhost.config to no avail:
<listenerAdapters>
<add name="http" />
<add name="https" />
</listenerAdapters>
<sites>
<site name="WebSite1" id="1" serverAutoStart="true">
<application path="/">
<virtualDirectory path="/" physicalPath="%IIS_SITES_HOME%\WebSite1" />
</application>
<bindings>
<binding protocol="http" bindingInformation=":8080:localhost" />
</bindings>
</site>
<site name="Filters" id="2">
<application path="/" applicationPool="Clr4IntegratedAppPool">
<virtualDirectory path="/" physicalPath="c:\Users\Ashley\documents\visual studio 2017\Projects\Filters\src\Filters" />
</application>
<bindings>
<binding protocol="http" bindingInformation="*:51107:localhost" />
<binding protocol="https" bindingInformation="*:43107:localhost" />
</bindings>
</site>
<siteDefaults>
<logFile logFormat="W3C" directory="%IIS_USER_HOME%\Logs" />
<traceFailedRequestsLogging directory="%IIS_USER_HOME%\TraceLogFiles" enabled="true" maxLogFileSizeKB="1024" />
</siteDefaults>
<applicationDefaults applicationPool="Clr4IntegratedAppPool" />
<virtualDirectoryDefaults allowSubDirConfig="true" />
</sites>
<webLimits />
Edit:
Another option I've tried, which just feels clunky, and kind of defeats the point of an IDE, is to configure Kestrel to use HTTPS. This isn't ideal since I had to export a copy of a certificate for localhost from IIS, and IIS Express still tries to load the site on a different port.
public class Program
{
public static void Main(string[] args)
{
var host = new WebHostBuilder()
.UseKestrel(options =>
options.UseHttps(new X509Certificate2("path/to/cert.pfx", "password")))
.UseContentRoot(Directory.GetCurrentDirectory())
.UseUrls("http://localhost:5100", "https://localhost:4300")
.UseIISIntegration()
.UseStartup<Startup>()
.Build();
host.Run();
}
}
Sadly, this doesn't work when run from VS17. The first time around I got a 502.2 (I think) error, now all I get is an unable to connect error in Chrome. I can run dotnet run from PowerShell and it works fine.
As a workaround, it does the trick. But it doesn't seem neat.
Ports are locked down in IIS Express so that it doesn't have to be run as Administrator...
Valid Ports are 44300 - 44399
Check out the Dev Community article
https://developercommunity.visualstudio.com/content/problem/39430/changing-port-number-in-a-web-project-does-not-imm.html
You can edit launchSettings.json, but the ssl ports must fall in this range.
This is for an Asp.Net MVC .Net Framework Project
Select your Project by highlighting it.
Then hit F4 to open its Properties pane.
Find the SSL Enabled item on list and set its value to True, and
copy SSL URL value onto your clipboard.
Whilst your Project is highlighted, hit Alt + Enter to open
the Properties dialogue - paste the copied SSL URL into the project url
under the Web menu input box.
For Visual Studio 2019 and 2017:
In Solution Explorer, right click the project > Properties
Select the Debug Tab
Check Enable SSL
In Solution Explorer right click on your website name and select "Properties Window", or simply hit F4. Under the Developer Web Server section change SSL Enabled from False to True.
For those running asp.net core 1.x in Visual Studio 2017 RC, you should be able to change the "sslPort": 0 line in the launchSettings.json file to whatever port number you would like to use for SSL. This effectively changes the bindings in the .\vs\config\applicationhost.config file mentioned in the previous answers.
This is for an Asp.Net Core 2.0:
Open up your Solution Explorer in VS2017.
Doubleclick Properties (yes, it's an object itself too, not just a folder)
Open Debug on the left side
Scroll down and select Enable SSL
If it's already enabled, open up launchSettings.json (unfold Properties) and set "sslPort" to 0, then do the steps again.
VS2017 should now ask you if you want to add an SSL certificate (something it doesn't do if you changed launchSettings.json on your own) and it'll set a port for you.
Editing the .\vs\config\applicationhost.config actually worked for me.
<site name="Filters" id="2">
<application path="/" applicationPool="Clr4IntegratedAppPool">
<virtualDirectory path="/" physicalPath="c:\Users\Ashley\documents\visual studio 2017\Projects\Filters\src\Filters" />
</application>
<bindings>
<binding protocol="http" bindingInformation="*:51107:localhost" />
**<binding protocol="https" bindingInformation="*:43107:localhost" />**
</bindings>
</site>
It does however load the app up in the browser using the non-https port by default. If you manually point your browser to the 43107 port it should work.
Edit
This worked for me a few times but stopped working. Subsequent testing revealed that whenever I would click the button to start debugging in VS 2017 RC it would remove the binding I manually added.
I fixed that by making the file read-only now it's starting with HTTPS support again.
I unfortunately had the same issue, couldn't see the "enable SSL" checkbox in the Debug tab of the Project's properties...
Finally found it! --> Set the launch on "IIS Express", then you will be able to select it ;-)
One important point you may be missing is that you have to Run Visual Studio as adminsitrator (right vlick VS icon and select 'Run as Administrator'.
I have been strugling with this SSL problem and after by running VS as adminstrator I made it work.
If you see the SSL Enabled option under the project's Properties window, but it is greyed out
Close Visual Studio
Edit the vwd.webinfo file and add the sslPort="44317" attribute to the iisExpressSettings element.
Alternatively, you can delete the vwd.webinfo file and Visual Studio will create a new one when you open the project

Visual Studio 2015. Failed to register URL for site access is denied IIS Express. Access denied 0x80070005

I enabled SSL in Visual Studio 2015 in order to implement Facebook and Google login locally.
I changed the project URL in the Web tab of the project's properties to https://localhost:44300/ and decorated the controller with the RequireHttps attribute - ref #msdn.
Everything worked fine locally.
I reverted settings to HTTP to test something else and that caused me a problem when I tried to get back to HTTPS.
I found this SO question and tried almost every suggested solution.
Error detail:
Failed to register URL "url" for site "site" application "path".
Error description: Access is denied. (0x80070005).
I had to issue this command in DOS to solve the problem in VS 2015:
netsh http add urlacl url=http://{ip_addr}:{port}/ user=everyone
Strangely this was only needed when I moved the project to a different PC. On the original PC I didn't need it.
Turned out this very answer on the same question thread by Cayne led me to the solution.
The port change didn't work because applicationhost.config file, located in .vs folder specific for VS2015, kept bindings combo of old port for Http and Https as a default setting. No matter how many times did I change port to something else while trying with Http (only got clogged with mass of new web site bindings in the config file) as soon as I wanted to switch back to SSL it ended up with the first bindings combo. The port it complained about that can't be registered any more.
Once I deleted that first bindings combo everything was fine.
I hope this will help someone in the future.
Go to C:\Users{username}\Documents\IISExpress\config and open the applicationhost.config file.
Search for the <sites> tag in the document. You will see some lines similar to the following.
<site name="WebSite1" id="1" serverAutoStart="true">
<application path="/">
<virtualDirectory path="/" physicalPath="%IIS_SITES_HOME%\WebSite1" />
</application>
<bindings>
<binding protocol="http" bindingInformation="*:8080:localhost" />
</bindings>
</site>
Replace the line <binding protocol="http" bindingInformation="*:8080:localhost" /> as follows.
<binding protocol="http" bindingInformation="*:{required_port_number}:*" />
I think you can even remove the * marks in bindingInformation.
Then restart IIS Server (remove all IIS server related operations using Task Manager and go to C:\Program Files\IIS Express folder and run iisexpress.exe: you might need to Run as Administrator).
A console will open and if all went well, following lines will be displayed.
Successfully registered URL "http://*:{required_port_number}/" for site "Website1" application "/"
...
Also check in browser whether the required URL works now.
Here's a very useful resource...

WCF service with Ssl Certificate in Azure emulator

I have setup my my cloud using the following
http://azure.microsoft.com/en-us/documentation/articles/cloud-services-configure-ssl-certificate/
and the web role using the following http://msdn.microsoft.com/en-us/library/ms731074%28v=vs.110%29.aspx
My problem that when I use emulator I get an error That the there is a name mismatch between a certificate and the website in this case(127.0.0.1)
What can be done to solve it.
So there are two approaches you could take:
Create a separate cloud project for each environment - This way you could create a self-signed certificate for your development environment and live with the warning that the certificate is not trusted.
Get a wildcard certificate for your application - This is the approach we have taken for our application (along with the 1st one). Basically we took a wildcard SSL certificate and used that certificate in our application. Then we added an entry in hosts file located in C:\Windows\System32\drivers\etc like this:
127.0.0.1 dev.cloudportam.com
Next, we added hosts header in our dev cloud project's csdef file.
<Sites>
<Site name="Web">
<Bindings>
<Binding name="Endpoint1" endpointName="Endpoint1" hostHeader="dev.cloudportam.com" />
<Binding name="Endpoint2" endpointName="SSL" />
</Bindings>
</Site>
</Sites>
<Endpoints>
<InputEndpoint name="Endpoint1" protocol="http" port="8080" />
<InputEndpoint name="SSL" protocol="https" port="8082" certificate="SSL" />
</Endpoints>
Now when we launch the application, it opens up https://localhost:8082/ and we just change the address to https://dev.cloudportam.com:8082 and everything works well.

Multiple SSL certificates in one azure deployment

I have a problem similar to (but not the same) as this:
Azure web role - Multiple ssl certs pointing to a single endpoint
My azure package contains multiple sites. Some of these sites are on domain abc and others are on domain def. I need to secure both domains with SSL but can't figure out how (if it's possible) to do this.
Here's an example of my config:
<Sites>
<Site name="sub1.abc" physicalDirectory="***">
<Bindings>
<Binding name="HttpIn" endpointName="HttpIn" hostHeader="sub1-staging.abc.com" />
<Binding name="HttpsInABC" endpointName="HttpsInABC" hostHeader="sub1.abc.com" />
</Bindings>
</Site>
<Site name="sub1.def" physicalDirectory="***">
<Bindings>
<Binding name="HttpIn" endpointName="HttpIn" hostHeader="sub1-staging.def.com" />
<Binding name="HttpsInDEF" endpointName="HttpsInDEF" hostHeader="sub1.def.com" />
</Bindings>
</Site>
</Sites>
<Endpoints>
<InputEndpoint name="HttpIn" protocol="http" port="80" />
<InputEndpoint name="HttpsInABC" protocol="https" port="443" certificate="abc" />
<InputEndpoint name="HttpsInDEF" protocol="https" port="443" certificate="def" />
</Endpoints>
<Certificates>
<Certificate name="abc" storeLocation="LocalMachine" storeName="My" />
<Certificate name="def" storeLocation="LocalMachine" storeName="My" />
</Certificates>
This configuration gives me the following error:
The same local port '443' is assigned to endpoints HttpsInABC and
HttpsInDEF in role ***.
Any suggestions on how I can work around this without having to host them separately?
Based on #JoelDSouza's answer:
Will using different ports work for you
What are the implications of SSL on ports 444/445/446 etc. in Windows Azure?
You can use multiple SSL certificates and add them all to the same endpoint by automating the process of installing the certificates on the machine and add HTTPS bindings to IIS.
IIS 8 (Windows Server 2012) supports SNI, which enables you to add a "hostheader" to the HTTPS binding.
I'm a Microsoft Technical Evangelist and I have posted a detailed explanation and a sample "plug & play" source-code at:
http://www.vic.ms/microsoft/windows-azure/multiples-ssl-certificates-on-windows-azure-cloud-services/
I fear you are out of luck - as noted in the article you linked to, one SSL certificate per server IP. I guess by hosting them separately (that feels odd to say considering it's cloud based) you will get two IPs and therefore can add an SSL certificate to each IP address.
You could perhaps move everything to one domain and use folders within that domain to host the separate sites - that's the only way you will be able to secure everything with your SSL certificate without having two hosting packages:
ie instead of:
www.domain1.com and www.domain2.com use www.mydomain.com/domain1/ and www.mydomain.com/domain2/
Will using different ports work for you? You can use SSL cert 1 with myapp.cloudapp.net:443 and SSL cert 2 with myapp.cloudapp.net:8443
If you don't need wildcard certificates you can use a multi-domain certificate. This way you only need one certificate. The downside is that each sub-domain needs to be specified, which can get expensive if you have a lot.

Using WCF on Localhost on Azure

In summary
How do I acces a WCF service on localhost when hosted in IIS on Azure? Azure does not bind localhost or 127.0.0.1 to my website.
Details
I have an ASP.Net application hosted on Azure. I have added a .svc and some workflows that I want to use via WCF. To keep matters simple, my web app simply calls the service on localhost, so I have endpoints like these in web.config;
<client>
<endpoint address="http://localhost:8080/Router.svc/Case" binding="basicHttpBinding" contract="NewOrbit.ExVerifier.Model.Workflow.Case.ICaseWorkflow" name="Case" />
<endpoint address="http://localhost:8080/Workflow/Case/Case_default1.xamlx" binding="basicHttpBinding" contract="*" name="Case_default1" />
</client>
This works just fine on my local machine. The problem is that when I publish this to Azure, the Website in IIS does not get a binding to localhost, instead the bindings are always to the actual IP address of the server.
It ends up looking like this in applicationHost.config:
<bindings>
<binding protocol="http" bindingInformation="10.61.90.44:80:" />
<binding protocol="https" bindingInformation="10.61.90.44:443:" />
<binding protocol="http" bindingInformation="10.61.90.44:8081:" />
</bindings>
So, as soon as my web app tries to call the service on localhost (or 127.0.0.1 for that matter) it fails instantly.
Needless to say, if I rdp on to the server and change the binding then all is fine.
What I find really odd is that there are tons of examples out there where people are accessing WCF services on localhost on Azure so I can't figure out why this is so. I have set the osFamily to 2 and in order to debug this I have enabled web publishing and remote desktop access which I guess, in theory, could mess things up.
What I have already looked at
I can rewrite the end-point address in my code at runtime to substitute localhost for the actual address or create the endpoint dynamically as described by Ron in the answers. Unfortunately I am using the WCF Routing service so I can version workflows. This means that my code calls the Router endpoint and the WCF Router in turns calls the actual service/workflow using an endpoint specified in web.config. I don't have control over the Routing services endpoint resolution without, I think, writing a whole set of routing logic which just seems to be a lot of work when all I want is to call localhost :)
Switching to using named pipes; Alas, it causes some strange issues with workflows, probably due to duplexing, and I am on a deadline so haven't got time to get to the bottom of that at the minute.
You have to build the endpoint address dynamically.
Step 1:
In your ServiceDefinition.csdef you need to declare an Endpoint.
<ServiceDefinition name="MyFirstAzureWorkflow" xmlns="http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceDefinition">
<WebRole name="WorkflowWeb" vmsize="ExtraSmall">
<Sites>
<Site name="Web">
<Bindings>
<Binding name="Endpoint1" endpointName="WorkflowService" />
</Bindings>
</Site>
</Sites>
<Endpoints>
<InputEndpoint name="WorkflowService" protocol="http" port="80" />
</Endpoints>
<Imports>
<Import moduleName="Diagnostics" />
</Imports>
</WebRole>
</ServiceDefinition>
Step 2:
When you want to call the service
var endpoint = RoleEnvironment.CurrentRoleInstance.InstanceEndpoints["WorkflowService"].IPEndpoint;
var uri = new Uri(string.Format(
"http://{0}:{1}/MyService.xamlx",
endpoint.Address,
endpoint.Port));
var proxy = new ServiceClient(
new BasicHttpBinding(),
new EndpointAddress(uri));
Okay, so this is how I solved it. IMHO it's a hack but at least it works.
Basically, I need to add a "*" binding, so I can do this in Powershell. The general recipe is here: http://blogs.msdn.com/b/tomholl/archive/2011/06/28/hosting-services-with-was-and-iis-on-windows-azure.aspx
That deals with adding Named Pipes support, but the principle is the same. I just changed the Powershell script to:
import-module WebAdministration
# Set up a binding to 8080 for the services
Get-WebSite "*Web*" | Foreach-Object {
$site = $_;
$siteref = "IIS:/Sites/" + $site.Name;
New-ItemProperty $siteref -name bindings -value #{protocol="http";bindingInformation="*:8080:"}
}
This now allows me to use http://127.0.0.1:8080/service.svc to access my service.
Note: You do need to follow the rest of the recipe to set elevated execution context and change the powershell execution mode, so do follow it carefully