We are trying to migrate our aspnetcore web apps from our own Windows/IIS server to AWS using ECS and API Gateway. We have everything working but ran into an unexpected issue with redirects inside our web applications. Our web site is setup like this in IIS:
/ => the root website is pointing to another web app
/app1 => app1 is setup as a virtual directory pointing to an empty folder
/app1/v1 => v1 is setup as an application pointing to an aspnetcore app
/app2/v1 => again v1 is setup as an application pointing to a different aspnetcore app
I have a very simple out of the box aspnetcore application that is setup as a virtual directory under /app1/v1. The routes in the aspnetcore application are:
/Web
/Web/Login
/Web/Home
When a user first visits the site (http://localhost/app1/v1/Web) they are redirected to the login page using:
Redirect("~/Web/Login")
When the application is run by IIS that results in the browser being redirected to:
http://localhost/app1/v1/Web/Login
However when I use a reverse proxy, like AWS API Gateway, that has been setup with the same virtual path it redirects to:
http://localhost/Web/Login
I'm guessing that there must be a configuration value that I need to pass into Kestrel during startup or as a request header to tell it to add "/app1/v1/" to any ~/ redirects that it performs?. Does anyone know how IIS is telling Kestrel the full path and how I can replicate that behavior?
Whenever asp.net runtime redirects,it will always use the base path
from the root .In your case the problem is ~ passed.This is telling
the browser to redirect from the base path which is /.
You can do remove the ~ and try giving Redirect("Web/Login").But I have seen asp.net runtime always add Reidrect Response wiht Location Header as "~/Web/Login".
So if removing the ~ does not work,you can try with
Response.RedirectToAbsoluteUrl("Web/Login");
Edit:
To explain the scenario why this may be happening when you do reverse proxy
Normally you setup a reverse proxy like this
www.example.com => servername:8080
When the proxy forwards the request,server(asp.net) does not know anything about the www.example.com ,to that asp.net runtime the request hostname is servername.
Now when you do redirect, what the asp.net runtime sends is a 302 response
This will look like this
Client request:
GET /app1/v1/Webl HTTP/1.1
Host: localhost
Server response:
HTTP/1.1 302 Found
Location: ~/Web/Login
Please check out this with a fiddler if you would like to confirm
Now when behind a reverse proxy where you may have setup like this
www.example.com/myapp => servername:8080
www.example.com/anotherapp => servername2:8080
You can double check how is the reverse proxy setup.Now imagine the same 302 response but your application does not know what is the relative path (www.example.com/myapp) .This causes problem with the what Location header is send in the response(if it has ~,this causes problems with relative paths in the original URL .
Hope this helps!.
The only place on the entire internet I could find an explanation is on MSDN:
Specifies an alternative path for the application root URL. Use this
option if the Web application root is not the root of your project.
From here I understood that "application root" is the path that retrieves when using tilde in ASP.NET. So I would expect that if I go to project's properties - Web - "Override application root" and specify another url then the tilde would map to that url.
But it doesn't. For example my web is on a virtual directory - http://localhost/WebApplication1
and on "Override application root" I try to specify http://localhost/WebApplication2 or http://localhost or http://WebApplication2 (which all exist on my local IIS). Now when I write
Response.Redirect("~/test2/login");
I expect it to redirect me to http://localhost/WebApplication2/test2/login.
But instead it redirects me to http://localhost/WebApplication1/test2/login as if I didn't override the "application root".
So what does this feature really suppose to do? Or maybe it's not working because I'm missing something and didn't define it properly?
Override application root URL doesn't change where the Application root is within your application. It changes the URL used to reach the application root. Because IIS does some hostname verification it's used to specify if you want to reach your application by a means other than localhost:[PORT].
For instance, if you override it to www.myapp.com you can then reach your application by adding this to your hosts file:
127.0.0.1 www.myapp.com
This might be especially useful if you're making your application available to a remote device (a virtual machine on your computer, or a mobile device on your network) because they would be unable to navigate to localhost as the application address.
Currently I have an internal server serv that has an application app.
It is running MVC 5 and has 2 pages Account/Logon which maps to controller and an action.
And Orders/Display (again controller/action)
In order for internet users in the outside world to see I have a host server host running IIS. It maps host URLs to the internal app like so
host/Account/Logon -->serv/app/Account/Logon
So basically anything after host/... gets changed to serv/app/....
My problem is if I do RedirectToAction("Display","Orders");
(there are lots of these redirects because there's lots of controller/action combos.
The internal server grabs the host portion but also tacks on "app" in order
to switch to the next page or route
So,host/app/Orders/Display
My problem is that the host IIS maps this URL to host/app/app/Orders/Display
because that what it's mapping is set to do. always add "app"
How can I solve this issue? Is there any way for serv do
a relative mapping? In order words it only sees the original host/Account/Logon
so on switch it would be host/Orders/Display?
Use Redirect() instead of RedirectToAction() and pass in the url.
Just wanted to know if there is any way I could develop Facebook applications in localhost.
Edit: 2-15-2012 This is how to use FB authentication for a localhost website.
I find it more scalable and convenient to set up a second Facebook app. If I'm building MyApp, then I'll make a second one called MyApp-dev.
Create a new app at https://developers.facebook.com/apps
(New 2/15/2012) Click the Website checkbox under 'Select how your application integrates with Facebook'
(In the recent Facebook version you can find this under Settings > Basic > Add Platform - Then select website)
Set the Site URL field (NOT the App Domains field) to http://www.localhost:3000 (this address is for Ruby on Rails, change as needed)
In your application initializer, put in code to detect the environment
Sample Rails 3 code
if Rails.env == 'development' || Rails.env == 'test'
Rails.application.config.middleware.use OmniAuth::Builder do
provider :facebook, 'DEV_APP_ID', 'DEV_APP_SECRET'
end
else
# Production
Rails.application.config.middleware.use OmniAuth::Builder do
provider :facebook, 'PRODUCTION_APP_ID', 'PRODUCTION_APP_SECRET'
end
end
I prefer this method because once it's set up, coworkers and other machines don't have additional setup.
Of course you can, just add the url localhost (without "http") in your app_domain and then add in your site_url http://localhost (with http)
Update
Facebook change the things a little now, just go to the app settings and in the site url just add http: //localhost and leave the App Domain empty
Here is my config and it works fine for PHP API:
app domain
http://localhost
Site URL
http://localhost:8082/
NOTE: As of 2012 Facebook allows registration of "localhost" as return Url. You still may need similar workaround for other providers (i.e. Microsoft one).
If you need real domain name registered with Facebook (like my.really.own.domain.com) you can locally redirect requests to this domain to your machine. Easiest out of box approach on any OS is to change "hosts" file to map the domain to 127.0.0.1 (see http://technet.microsoft.com/en-us/library/bb727005.aspx#EDAA and https://serverfault.com/questions/118290/cname-record-alias-in-windows-hosts-file).
I usually use Fiddler to do it for me (on Windows with local IIS) - see samples on http://www.fiddler2.com/Fiddler/Dev/ScriptSamples.asp.
if (oSession.HostnameIs("my.really.own.domain.com")) {
oSession.host="localhost:80";
}
Hosts file approach of approaches does not work with Visual Studio Development Server as it requires incoming Urls to be localhost/127.0.0.1. If you need to work with it (or possibly with IIS express) to override host - Using Fiddler with IIS7 Express
Facebook no longer allowed a 'localhost' callback URL for FBML Facebook applications
With the new development center it is now easier:
1) Leave app domains blank.
2) Click Add Platform
3) Site URL should equal the full path of your local host.
4) Save Changes
I just discovered a workaround: You can make your local machine accessible by using http://localtunnel.com . You'll need to (temporarily) change some URLs used in your app code / html so links point to the temporary domain, but at least facebook can reach your machine.
In your app's basic settings (https://developers.facebook.com/apps)
under Settings->Basic->Select how your app integrates with Facebook...
Use "Site URL:" and "Mobile Site URL:" to hold your production and development URLs respectively. Both sites will be allowed to authenticate. I'm just using Facebook for authentication so I don't need any of the mobile site redirection features. I usually change the "Mobile Site URL:" to my "localhost:12345" site while I'm testing the authentication, and then set it back to normal when I'm done.
You have to choose Facebook product 'facebook login' and enable
Client OAuth Login , 'Web OAuth Login' and 'Embedded Browser OAuth Login'
then even if you give localhost url It will work
There is ! My solution works when you create an app, but you want to use facebook authentification on your website. This solution below is NOT needed when you want to create an app integrated to FB page.
The thing is that you can't put "localhost" as a domain in the facebook configuration page of your app. Security reasons ?
You need to go to your host file, in OSX / Linux etc/hosts and add the following line :
127.0.0.1 dev.yourdomain.com
The domain you put whatever you want. One mistake is to add this line :
localhost dev.yourdomain.com (at least on osx snow leopard in doesnt work).
Then you have to clear your dns cache. On OSX : type dscacheutil -flushcache in the terminal.
Finally, go back to the online facebook developer website, and in the configuration page of your app, you can add the domain "dev.yourdomain.com".
If you use a program such as Mamp, Easyphp or whatever, make sure the port for Apache is 80.
This solution should work for Windows because it also has a hosts file. Nevertheless, as far as I remember Windows 7 doesnt use this file anymore, but this trick should work if you find a way to force windows to use a hosts file.
this works June 2018, even after the HTTPS requirement. It appears a test app does not require https:
create a test app:
https://developers.facebook.com/docs/apps/test-apps/
then within the test app, follow the simple steps in this video:
https://www.youtube.com/watch?v=7DuRvf7Jtkg
I think you should be able to develop applications using the visual studio development web server: Start a new FaceBook application on: http://www.facebook.com/developers/. Then set the settings for the site Url and the canvas url to the running instance of your website for example:http://localhost:1062/
Here are a couple of links that should help you out on starting with FaceBook:
http://thinkdiff.net/facebook/graph-api-iframe-base-facebook-application-development/,
http://nagbaba.blogspot.com/2010/05/experiencing-facebook-javascript-sdk.html,
http://apps.facebook.com/thinkdiffdemo/
Hope this helps.
Try this ---
https://www.facebook.com/help/community/question/?id=589302607826562
1 - Click Apps and then select your app.
2 - Click the Settings button on the left side of the screen.
3 - In the Basic settings, click the Add Platform button below the
settings configuration.
4 - Select Website in the platform dialog.
5 - Enter your URL (localhost works here).
6 - In the App Domains text input, add your domain that matches the one in the URL.
7 - Save your settings.
Suppose that you have registered your app as:
app.domain.com
You just need to modify the /etc/hosts file by adding
127.0.0.1 dev01.app.domain.com
Then, modify your apache configuration
ServerName dev01.app.domain.com
and restart apache.
You'll need to put your URL in a variable in order to use it as XML parameter on some calls:
<fb:login-button registration-url="http://<?=$URL?>/register" />
Don't have enough cred to comment on the top voted answer, but at least in my rails environment (running 4), rails s is at http://localhost:3000, not http://www.localhost:3000. When I changed it to http://localhost:3000, it worked just fine. No need to edit any hosts file.
app domain : localhost
site URL : http://localhost:4440/
worked for me with the new UI.
Latest update:
You don't have to give any urls if you are testing it in development. You can leave the fields empty. Make sure your app is in development mode. If not turn off status from live.
No need to provide site url, app domains or valid redirect oauth uri.
My Solution works fine in localhost.....
For Site URLS use http://localhost/
and for App domains use localhost/folder_name
Rest everything is same .......it works fine
(though its shows redflag in App Domain..App is working fine)
It's easy go to the app dashboard under the facebook login tab click settings
then select Enforce HTTPs No, save settings
The application will run just fine in localhost: 3000, you just need to specify the https address on which the application will be live when it be in production mode.
Option 2 is provide the url or you heroku website which lets you have sample application in production mode.
I have created a SharePoint Event Receiver, that fires on Item Update.
The receiver needs access AfterProperties and ListItem.
When firing the event receiver from a SharePoint web application using an IP address (http://10.0.4.50/sites/), it throws a FileNotFoundException, when accessing SiteId And WebUrl in SPItemEventProperties.
The Web application at http://10.0.4.50/sites/companyName could not be found. Verify that you have typed the URL correctly.
When firing the event receiver using the hostname, specified at setup of Site Collection http://computerhostname/sites/companyName. This works fine, no exception is thrown.
//Combine Both AfterProperties And ListItem
var ListProperties = new List<KeyValuePair<string, object>>();
ListProperties.AddRange(properties.AfterProperties.ToKeyValue());
ListProperties.AddRange(properties.ListItem.ToKeyValue(p => !p.Sealed));
var AvaliableProperties = ListProperties.Distinct(new KeyValueComparer<object>());
This isn't necessarily a SharePoint problem, but is most likely down to the way that IIS is configured on the host. A particular site can be "bound" to an IP address and a host name, and if the host name isn't present in the HTTP GET sent by the browser then IIS will return a 404 NOT FOUND.
You can verify this by using a browser to see whether you can access the site by IP address.
You can add additional bindings if necessary, but there can only be one "default" binding per IP address, so only one site can be present at (in your case) 10.0.4.50.
A possible way around the situation where multiple sites are present but you can't use a hostname might be to add a binding to a port other than port 80 for this IP, so your URL would become something like http://10.0.4.50:8080/sites/companyName.
This is not just an IIS problem, but Sharepoint related as well. A lot of referencing in SharePoint is done by using a url as a starting point (just look at the constructor of SPSite). The url is then compared to known url's in SharePoint's Config database. (and ofr files etc in the site's content database).
SharePoint uses a system called Alternate Access Mappings to assign different urls to a Web Application's "Zones" (default, intranet, internet, ... custom definition). If it does not find the 'exact' Url, internally stuff will fail (And especially search is very "Url sensitive").
Then comes the IIS part into play: Since IIS probably has no other site running on the 80 port, and without a specific hostheader (so it defaults to machinename), or with the hostheader set to the machine name, IIS will pick up the request and since SharePoint is tied into this webapp, SharePoint will try to process it, looks up the url, Sharepoint does not find the Url and thne "breaks".
The no hostheader occurs when you leave the hostheader field empty when you create a new web app in SharePoint.