Rails: one app with 2 domains - share authentication - ruby-on-rails

My site is at mydomain.com on Heroku with Devise authentication.
I bought a short url me.do that I also point to my same Heroku app.
When a user is signed in on mydomain.com I also need them to be signed in on me.do so when they go to me.do after signing in at mydomain.com they don't have to sign in again.
How can I share authentication sessions using Devise on both mydomain.com and me.do?

There is no easy way to share authentication across domains, since the authentication usually is bound to cookies (sessions) which only bind to one domain and are not accessible across domains.
The only way you can manage to have something like this is to make sure you set cookies on both domains on login. You can do this via a redirect loop:
login request arrives at domain1 (from login form for example)
you set the session cookie for domain1
then make a redirect to domain2 and set a session cookie there
and then redirect the user back to domain1 (proceeding where he originally was going)
to make sure this is not an endless loop you have to add some parameters in the redirects to know how to handle the situation.
BUT if at all possible to avoid it, i would advise you not to implement this. It is really bad practice to have not unique domains. even allowing domains with www and without can lead to quite a bit of confusion for the user and a lot of headaches to the developer - in your case it will be even worse.
The sessions are not as useful as they would normally be. Setting additional cookies or session values does NOT work anymore (unless you do the loop every time again). And until the user actually uses the second domain his session there might even have expired (depending how your authentication framework handles it).
Those are just some of the issues you might run into.

Related

Problems with per-user subdomain sessions & Google OAuth2

We're developing an application that hosts each user account under their own subdomain. Separate users may access their application through a domain such as usera.myapp.com and userb.myapp.com.
To enhance security between application accounts, the session cookies are scoped to the subdomain of the account (ex. usera.myapp.com instead of .myapp.com). This seems to pose a problem with Google's OAuth2 implementation. Since Google OAuth will only allow you redirect back to the set redirect_uri in their settings, we cannot redirect the user back to their custom subdomain after authorizing our app. We're forced to redirect them back a single generic subdomain such as oauth.myapp.com.
Once they're redirected, we no longer have access to the session (sessions are scoped to a different subdomain now). Since we no longer have access to the session, we cannot check the CSRF token we set to the "state" parameter when requesting the OAuth token. Most other implementations of OAuth2 will allow us to redirect back to a wildcard subdomain, so this isn't an issue.
Now we are left with 2 possible solutions to fix this issue...
Skip checking the CSRF token in the "state" parameter, which opens us up to clikjacking attacks. Or...
Open up our session cookies to use the entire domain, instead of scoping them to the the account subdomain. This opens it's own can of worms and security issues, but it is something that we can deal with.
Option #2 seems like the lesser of the two evils, but I'd like some input before we proceed with doing that.
Thoughts?
Hm, might it be possible to construct the state value by hashing up a bunch of pieces of state so you don't have to retrieve the desired value from a cookie? E.g. hash up the subdomain, the time of day, and some internal system state from your app. Then you can recompute the value you expect when they show up at oauth.myapp.com, no need to fetch it from the session. Should be effective against clickjacking I’d think.

Rails, Devise, and multiple domains

Let's say I have an application that's going to be accessed from completely different domains that all point at the same server*:
example.com, example.net, foobar.com, ...
I have a Devise based authentication system that's worked fine before. However, the goal is now to add HTTPS to the sign in system. The problem is, as it turns out, there is no way to host more than one HTTPS website on the same IP address**. To resolve this problem, I set up the login pages to always POST to https://secure.example.com. As far as I can tell, this is working fine. Devise seems to have no qualm with it. However, the tricky part is that the user now needs to be redirected to foobar.com, which also needs to understand that the user is logged in. I pass the site to return to in a hidden parameter in the login form, and the redirection works fine. I still have no way to inform foobar.com that the user is now logged in.
I've managed to set it up so that, upon being returned to foobar.com, it copies the user's session cookie for secure.example.com into a new cookie for foobar.com. This part is working fine. However, in the Rails console, the web requests for secure.example.com and foobar.com - with the same cookie sent for each - produce two completely different sessions and therefore, it's no wonder Devise acts like the user was never logged in to foobar.com
Does anyone know why this wouldn't work - why two identical web requests (only the domain of the request URI was different - I tried it in Firebug, too) would produce two completely different sessions in a Rails 3 app with different, yet consistent, session ids? More to the point, does anyone know how to MAKE this work?
* assume, for the purposes of this exercise, that this is unavoidable and the sites cannot be hosted all under different subdomains, and that the number of domains required is too great to get a separate IP address for each.
** unless they're subdomains and you have an *.example.com cert, but that's beside the point.
If you're already using Devise, I suggest you try using token authenticatable. You can generate a token for the user in question, redirect them with the token to sign in, and then quickly expire the token after they have signed in.
You could also try rolling your own OAuth provider with doorkeeper.

Preparing my ASP.NET / MVC site to use SSL?

I'm getting ready to have an SSL cert installed on my hosting.
It is my understanding that (and correct me if I'm wrong...):
Once the hosting guys install the cert, I will be able to browse my site on Http or Https (nothing will stop me from continuing to use Http)?
The only thing I need to do, is add logic (in the case of MVC, Controller attributes/filters) to force certain pages, of my choosing, to redirect to Https (for instance, adding a [RequiresHttps] attribute sparingly).
Do I have to worry about doing anything extra with these things to make sure I'm using SSL properly? I'm not sure if I need to change something with logic having to do with:
Cookies
PayPal Express integration
Also, I plan on adding [RequiresHttps] only on the shopping cart, checkout, login, account, and administration pages. I wish to leave my product browsing/shopping pages on Http since I heard there is more overhead for using Https. Is this normal/acceptable/ok?
One more question... I know ASP.NET stores some login information in the form of an Auth cookie. It is okay that a user logs in within an Https page, but then can go back and browse in an Http page? I'm wondering if that creates a security weakness since the user is logged in and browsing in Http again. Does that ruin the point of using SSL?
I'm kind of a newb at this... so help would be appreciated.
Starting with your questions, on one, (1) yes nothing will stop you to use for the same pages http ether https.
and (2) Yes you need to add your logic on what page will be show only as https and what as http. If some one wondering, why not show all as https the reason is the speed, when you send them as https the page are bigger and the encode/decode is take a little bit more, so if you do not need https, just switch it to http.
Switching Between HTTP and HTTPS Automatically is a very good code to use for the implementation of switching logic fast and easy.
Cookies
When the cookie have to do with the credential of the user then you need to force it to be transmitted only with secure page. What this mean, mean that if you set a cookie with https, this cookie is NOT transmitted on non secure page, so is stay secure and a man in the middle can not steal it. The tip here is that this cookie can not be read on http pages - so you can know that the user is A, or B only on secure page.
Cart - Products
Yes this is normal : to leave the products and the cart on unsecured connection because the information is not so special. You start the https page when you be on user real data, like name, email, address etc.
Auth cookie
If you set it as secure only, then this cookies not show/read/exist on unsecured page. It is an issue if you not make it secure only.
Response.Cookies[s].Secure = true;
Few more words
What we do with secure and non secure page is that we actually split the user data in two parts. One that is secure and one that is not. So we use actually two cookies, one secure and one not secure.
The not secure cookie is for example the one that connect all the products on the cart, or maybe the history of the user (what products see) This is also that we do not actually care if some one get it because even a proxy can see from the url the user history, or what user see.
The secure cookie is the authentication, that keep some critical information for the user. So the non secure cookie is with the user everywhere on the pages, the secure is only on check out, on logged in, etc.
Related
MSDN, How To: Protect Forms Authentication in ASP.NET 2.0
Setting up SSL page only on login page
Can some hacker steal the cookie from a user and login with that name on a web site?
1) Yes, you are right.
2) Yes. You can optionally handle HTTP 403.4 code (SSL required) more gracefully, by automatically redirecting the client to the HTTPS version of the page.
As for authentication cookies, I've found this MSDN article for you. Basically, you can set up your website (and the client's browser) to only transmit authentication cookie via HTTPS. This way it won't be subject to network snooping over unencrypted channel.
Of course, this is only possible if all of your [Authorize] actions are HTTPS-only.

Copying cookies from main domain to subdomain

My application has a userspace which used to be accessed by a url like domain.com/~username, but I am in the process of converting that to using subdomains instead (username.domain.com). However, I am running into an issue that I'm hoping someone might have an idea of how to get around.
Currently, visitors to a user's site get a cookie of the form user<id>_authentication (where <id> is the user ID of the site they're visiting), which is set to have the domain www.domain.com. However, now that I'm switching to subdomains, I want to find those cookies and transfer them to a new cookie called authentication per subdomain, using the subdomain as the cookie domain. However, the rails cookies array does not find the main domain cookies.
I know that if the old cookies were using .domain.com as the domain instead, they'd apply to the subdomain and would be present in cookies, but these cookies are already existing, and I'm trying to make the change as seamless for a user as possible -- so if they had an authentication cookie already for a site, I want them to not have to reauthenticate if at all possible.
Is there any way I can get the cookies from the main domain or does anyone have another suggestion of how I can transfer the cookies?
Update: Sorry, I didn't make it clear before, the cookie is only set if the visitor actively authenticates themselves by submitting a form on the user's site.
If you change the cookie domain to be more permissive (applying to more sub domains) you have no way to read the old, more restricted cookies except from the top level domain that used to work.
You will have to read the cookie, authenticate, and then write a new more permissive cookie before the cookie can be read by the subdomain.
You can roll out your migration logic in advance of the feature and hope you get most people. The rest will have to re-authenticate manually.
Personally I think they should have to re-authenticate.. it will only happen once, then they'll have the new ".domain.com" cookie.
But... One way to achieve this would be to check for the new cookie and when failing to find it, redirect to a new page on the main domain, providing the return url.
In that new page, check for the old style cookie, set the new style cookie, and redirect to the original url. if they don't have the old style cookie, redirect to the login area.
hope this helps.

How do I let a user sign in from a different domain on Authlogic?

[This is slightly different than a previous question about having multiple domains share the same cookie. It seemed like there wasn't an easy way to do that.]
I have a application at application.com. A customer has app.customer.com pointed at my site on Heroku, and I have everything set up so that it renders a specific version of app correctly. The issue is that I want a user at app.customer.com to be able to login. I believe authlogic is now setting the cookie on application.com, so while it verifies the credentials, no session on customer.com is ever created.
Since cookies cannot be shared across domains, you probably need to save an identifier in a database and also pass it through the url so when the client browser hits the new domain, it sends the token for the new domain session to see and match.
It should be a long cryptographically safe token, like a UUID to keep it from being guessed by attackers.
I'm not sure how the authlogic piece fits in though.

Resources