We have a web application, say mysite.com.
Now users can come and create pages like, mysite.com/page/mypage. Here 'mypage' is unique identifier for the page he/she has created. So whenever mysite.com/page/mypage url is requested, it hits our 'pagerequestservlet', which gives out requested page data.
Now what I want is, whenever user hits, mypage.mysite.com, then also we give out the same page related info (that we give out on mysite.com/page/mypage). This would mean, I need to make all my *.mysite.com requests to be handled by 'pagerequestservlet' (or a similar servlet). Then I can just parse the request URL, identify the identifier 'mypage' and return the data.
Now my question is, how to make all my *.mysite.com requests to be handled by 'pagerequestservlet'? I am using GoDaddy as my domain registrar.
You must setup your DNS to allow such wildcards, I don't know wheter GoDaddy supports this.
A servlet is "DNS-agnostic", normally it does not need to know anything about its domain name. This way it's possible to deploy the same servlet on different environments or even with different context roots (example.com/a and example.com/b).
You still have access to the domain name via ServletRequest#getServerName(). You could implement a Filter that handles the subdomain part and redirect to the correct page. But be aware - if you run in a clustered environment or behind a load balancer, this would not return mypage.example.com, but the name of the host ther servlet was deployed to.
Related
I have a SaaS app where every user has a personal subdomain: username.domain.com. Every user has a personal blog at username.domain.com/blog.
Now I want to accept custom domains, e.g. www.mycustomblog.com would be an alias for username.domain.com/blog.
If someone browses to www.mycustomblog.com/123, the page username.domain.com/blog/123 should be served.
However, I do NOT want a redirect. The user should still see www.mycustomblog.com/123in their address bar.
How can I achieve this behaviour? I have looked into Nginx reverse proxies, DNS CNAME records... but nothing seems to suit my needs. I can access both the custom domain DNS settings and all of the server's config files.
I think what you're looking for is a rewrite. However your described logic doesn't work:
www.mycustomblog.com -> username.domain.com/blog
appears to be missing a piece of identifying information on the left side. Perhaps www.mycustomblog.com/username? After that, it's just a matter of writing out the match/map statements to change the request to match what you've got on the server.
I have an HTML5 app written in static html/js/css (it's actually written in Dart, but compiles down to javascript). I'm serving the application files via CDN, with the REST api hosted on a separate domain. The app uses client-side routing, so as the user goes about using the app, the url might change to be something like http://www.myapp.com/categories. The problem is, if the user refreshes the page, it results in a 404.
Are there any CDN's that would allow me to create a rule that, if the user requests a page that is a valid client-side route, it would just return the (in my case) client.html page?
More detailed explanation/example
The static files for my web app are stored on S3 and served via Amazon's CloudFront CDN. There is a single HTML file that bootstraps the application, client.html. This is the default file served when visiting the domain root, so if you go to www.mysite.com the browser is actually served www.mysite.com/client.html.
The web app uses client-side routing. Once the app loads and the user starts navigating, the URL is updated. These urls don't actually exist on the CDN. For example, if the user wanted to browse widgets, she would click a button, client-side routing would display the "widgets" view, and the browser's url would update to www.mysite.com/widgets/browse. On the CDN, /widgets/browse doesn't actually exist, so if the user hits the refresh button on the browser, they get a 404.
My question is whether or not any CDNs support looking at the request URI and rewriting it. So, I could see a request for /widgets/browse and rewrite it to /client.html. That way, the application would be served instead of returning a 404.
I realize there are other solutions to this problem, namely placing a server in front of the CDN, but it's less ideal.
I do this using CloudFront, but I use my own server running Apache to accomplish this. I realize you're using a server with Amazon, but since you didn't specify that you're restricted to that, I figured I'd answer with how to accomplish what you're looking to do anyway.
It's pretty simple. Any time you query something that isn't already in the cache on CloudFront, or exists in the Cache but is expired, CloudFront goes back to your web server asking it to serve up the content. At this point, you have total control over the request. I use the mod_rewrite in Apache to capture the request, then determine what content I'm going to serve depending on the request. In fact, there isn't a single file (spare one php script) on my server, yet cloudfront believes there are thousands. Pretty sure url rewriting is standard on most web servers, I can only confirm on lighttp and apache from my own experience though.
More Info
All you're doing here is just telling your server to rewrite incoming requests in order to satisfy them. This would not be considered a proxy or anything of the sort.
The flow of content between your app and your server, with cloudfront in between is like this:
appRequest->cloudFront
if cloudFront has file, return data to user without asking your server
for the file.
If cloudFront DOESN'T have the file (or it has expired), go back to
the origin server and ask it for a new copy to cache.
So basically, what is happening in your situation is this:
A)app->ask cloudfront for url cloud front doesn't have
B)cloudfront
then asks your source server for the file
C)file doesn't exist there,
so the server tells cloudFront to go fly a kite
D)cloudFront comes back empty handed and makes your app 404
E)app crashes and
burns, users run away and use something else.
So, all you're doing with mod_rewrite is telling your server how it can re-interpret certain formatted requests and act accordingly. You could point all .jpg requests to point to singleImage.jpg, then have your app ask for:
www.mydomain.com/image3.jpg
www.mydomain.com/naughtystuff.jpg
Neither of those images even have to exist on your server. Apache would just honor the request by sending back singleImage.jpg. But as far as cloudfront or your app is concerned, those are two different files residing at two different unique places on the server.
Hope this clears it up.
http://httpd.apache.org/docs/current/mod/mod_rewrite.html
I think you are using the URL structure in a wrong way. the path which is defined by forward slashes is supposed to bring you to a specific resource, in your example client.html. However, for routing beyond that point (within that resource) you should make use of the # - as is done in many javascript frameworks. This should tell your router what the state of the resource (your html page or app) is. if there are other resources referenced, e.g. images, then you should provide different paths for them which would go through the CDN.
I suspect the answer is no (or at least, not in an intelligent manner), but felt like asking.
Is it possible in an asp.net HttpModule to determine the page that is going to be returned to the user, taking default page settings of IIS into account (without hardcoding them outside of IIS). For example, if a user requests http://www.example.org/bar/, the real page might be http://www.example.org/bar/index.html -- but could just as easily be http://www.example.org/bar/foot.html , depending on the user's IIS settings.
You're correct: in cases where there was no file.ext available in the requested URL, the IIS settings would have to be available in order to determine the actual page that was returned.
Given that the module has to live on the IIS server, I think you could get the list of default pages configured in IIS by connecting via WMI. You'd then have to get the list of files in the requested folder to figure out which of the default pages was actually returned.
While I realise that this is usually related to cross site scripting attacks, what I'm wondering is how can a session remain valid throughout multiple subdomains belonging to a single domain (example: a user logging in only once, and being able to access both subdomain1.domain.com and subdomain2.domain.com with the same session). I guess I first need to understand how it works, but so far I haven't been able to find much that would be of any relevance.
But then again, maybe I wasn't asking the right question.
Thanks in advance :)
Inproc sessions cannot remain valid, however you can code your web application to allow cookies across multiple subdomains. You will need to set the domain equal to:
Response.Cookies("CookieName").Domain = ".mydomain.com"
Remember the period.
There are quite a few ways to share session data or cookie data across domains. The simplest is to share it on the server side through a shared data store. But you would not be asking this question if it were that easy.
The other way to do this is equally simple. The domain one.com contains some session data say name=aleem and id=123 and wishes to pass this along to two.com. It will follow these steps:
Make a call to two.com/api/?name=aleem&id=123
When two.com gets the data via query parameters, it creates a cookie with the data. This cookie will be stored under the two.com domain.
two.com will then redirect back to the REFERER which in this case happens to be one.com
This is a simplified scenario. The domain two.com needs to be able to trust one.com and not only that but it needs to know that the request is authentic and not just crafted by the user so you need to use public/private keys to mitigate this.
By default, all cookies for a site are stored together on the client, and all cookies are sent to the server with any request to that site. In other words, every page in a site gets all of the cookies for that site. However, you can set the scope of cookies in two ways:
Limit the scope of cookies to a folder on the server, which allows you to limit cookies to an application on the site.
Set scope to a domain, which allows you to specify which subdomains in a domain can access a cookie.
You can learn more here.
The comments about the cookie being set for the domain to allow subdomains to receive that cookie give you that side but what's missing is the consistency of session.
I think this is very much like the problem of maintaining state across servers in a farm and the solution is probably to ensure that your session store is consistent across both sites (if they are not server from the same 'web site' in IIS). You can move the Session store into SQL Server (HOW TO: Configure SQL Server to Store ASP.NET Session State) which would probably serve the purpose as each site would query the same store when looking for the session data related to the cookie they've been presented with.
I hope that gets you on the right track.
If you have the ability to set up a common subdomain, you can do this:
In your subdomain html files, include a javascript file at the top like this:
<script src="http: //common.domain.com/check.asp"></script>
In check.asp, look for your logged_in cookie and if not present, show a page say, http://common.domain.com/login.asp using something like
<%
if (cookie_not_found){
%>
location.href = "http: //common.domain.com/login.asp";
<%
}
%>
Once a person submits username password, submit it back to the same login.asp and set the session cookie, (which will be set in common.domain.com domain) and then redirect to http://subdomain1.domain.com.
What will happen now is, a call will be made to the embedded "common.domain.com/check.asp", and cookies for common.domain.com will be sent by the browser along with the request. So you will know whether your session is valid or not, even when you are in subdomain1.domain.com.
You can set a cookie for a specific domain.
In php, the setCookie() method contains a parameter in which you can specify the top-level domain, so the cookie is valid for all subdomains. Based on your tags, I see you are working in asp.net. Probably this also exists for asp...
after a little search for asp:
try this:
Response.Cookies("CookieName").Domain = ".mydomain.com"
or read this
Here is a solution which works:
http://anantgarg.com/2010/02/18/cross-domain-cookies-in-safari/
I implemented OpenID support for an ASP.Net 2.0 web application and everything seems to be working fine on my local machine.
I am using DotNetOpenId library. Before I redirect to the third party website I store the orginal OpenID in the session to use when the user is authenticated (standard practice I believe).
However I have a habit of not typing www when entering a URL into the address bar. When I was testing the login on the live server I was getting problems where the session was cleared. My return url was hard coded as www.mysite.com.
Is it possible that switching from mysite.com to www.mysite.com caused the session to switch?
Another issue is that www.mysite.com is not under the realm of mysite.com.
What is the standard solution to these problems. Should the website automatically redirect to www.mysite.com? I could just make my link to the log in page an absolute url with containing www? Or are these just hiding another problem?
Solve the realm problem that you mentioned is easy. Just set the realm to *.mysite.com instead of just mysite.com. If you're using one of the ASP.NET controls included in the library, you just set a property on the control to set the realm. If you're doing it programmatically, you set the property on the IAuthenticationRequest object before calling RedirectToProvider().
As far as the session/cookie problem goes with hopping between the www and non-www host name, you have two options:
Rather than storing the original identifier in the session, which is a bad idea anyway for a few reasons, use the IAuthenticationRequest.AddCallbackArguments(name, value) method to store the user's entered data and then use IAuthenticationResponse.GetCallbackArgument(name) to recall the data when the user has authenticated.
Forget it. There's a reason the dotnetopenid library doesn't automatically store this information for you. Directed identity is just one scenario: If the user types 'yahoo.com', you probably don't want to say to them 'Welcome, yahoo.com!' but rather 'Welcome, id.yahoo.com/andrewarnott'! The only way you're going to get the right behavior consistently is to use the IAuthenticationResponse.FriendlyIdentifierForDisplay property to decide what to display to the user as his logged in identifier. It gives more accurate information, and is easier than storing a value in the callback and getting it back. :)
I dunno how OpenID works, but LiveID gives you a token based on the combination of user and domain. I just would have forwarded www to mysite.com.
The cookies and sessions and everything else get lost between www.site.com and site.com. I don't have patience enough to thoroughly read all the specs, but http://www.w3.org/Protocols/rfc2109/rfc2109 states that
A is a FQDN string and has the form
NB, where N is a non-empty name
string, B has the form .B', and B' is
a FQDN string. (So, x.y.com
domain-matches .y.com but not y.com.)
Note that domain-match is not a
commutative operation: a.b.c.com
domain-matches .c.com, but not the
reverse.
I think that means yes, you do need to forward to www. I have always added domain correction code to my sites when cookies and sessions are being used.