Share session between two rails 4 application with different subdomain - ruby-on-rails-4

I have two rails 4 application running on shared parent domain example.com(pdf.example.com and studio.example.com). The applications are deployed on AWS and storing session in shared Memcached.
On a page of studio.example.com, a page of pdf.example.com is loaded in iframe which covers the entire visible area. Now when user interacts with iframe content, session created in studio.example.com should reset in a sense that timeout should not happen in studio.example.com while sitting in pdf.example.com` pages.
The studio.example.com application uses devise for authentication.
Here is the configuration used to store session in memcached in studio.example.com
config/initializers/session_store.rb
Rails.application.config.session_store ActionDispatch::Session::CacheStore, :expire_after => 30.minutes
config/environments/production.rb
config/environments/development.rb
config.cache_store = :dalli_store
There are many resources out there(few listed below) addressing this scenario but all of them are using CookieStore. What sort of configuration would be different for CacheStore?
http://dev.mikamai.com/post/75476602797/sharing-session-between-your-rails-4x-app-and
http://excid3.com/blog/sharing-a-devise-user-session-across-subdomains-with-rails-3/
https://robots.thoughtbot.com/how-to-share-a-session-between-sinatra-and-rails
EDIT
Exact scenario was discussed here earlier.

The solution suggested in http://dev.mikamai.com/post/75476602797/sharing-session-between-your-rails-4x-app-and worked.
In both applications do following
Set same secret_key_base in both applications
Configure same key and domain in session_store.rb
Rails.application.config.session_store ActionDispatch::Session::CacheStore, :expire_after => 30.minutes, key: '_common_key', domain: ".example.com"
Enable caching with dalli in production.rb Dalli::ElastiCache.new('tripartite.q1ssrz.cfg.usw2.cache.amazonaws.com:11211)
config.cache_store = :dalli_store, elasticache.servers

Related

Sandbox Cookies between environments

I have a production environment and a staging environment. I am wondering if I can sandbox cookies between the environments. My setup looks like
Production
domain.com - frontend SPA
api.domain.com - backend Node
Staging
staging.domain.com - frontend SPA
api.staging.domain.com - backend Node
My staging cookies use the domain .staging.domain.com so everything is fine there. But my production cookies use the domain .domain.com so these cookies show up in the staging environment.
I've read one possible solution is to use a separate domain for staging like staging-domain.com but I would like to avoid this if possible. Are there any other solutions or am I missing something about how cookies work?
There are multiple alternatives:
Set your production domains to be www.domain.com and api.www.domain.com and set your cookie to .www.domain.com
This way, your production cookie will not be seen in the staging environment.
or
Use .domain.com , but have your backend behave differently depending on which environment they receive the cookie in.
One solution would be to change the pass phrase used on staging environment to encrypt cookies.
Doing so will render cookies coming from the production invalid.
The method to do so is web server dependent, for example on Apache HTTP server:
http://httpd.apache.org/docs/current/mod/mod_session_crypto.html
Text from above link:
SessionCryptoPassphrase secret
The session will be encrypted with the given key. Different servers can be configured to share sessions by ensuring the same encryption key is used on each server.
If the encryption key is changed, sessions will be invalidated automatically.
So find how o change the passphrase on your web server on staging environment, and all cookies coming from production, along with all cookies (issued in the past) from staging will be considered invalid on staging.
Alternative option if you don't want to use separate domain or www subdomain: you can append staging environment name to the cookie name.
But personally, I would put an API gateway/proxy in front of backend and spa to keep both services under a single domain (domain.com and domain.com/api).
For staging: staging.domain.com and staging.domain.com/api or completely separate domain to avoid exposing a staging address in SSL certificate.
And I would not allow cookie sharing by omitting domain while setting the cookie. Probably, I would set the cookie path to /api.

Logged out of one spring app when using two spring boot apps at the same time

I have two spring boot applications.
module1 running on port 8080
module2 running on port 9090
I have set the ports using this property in application.properties file
server.port=${port:9090}
Both modules have /login, /signup which are accessible without authentication accomplished via the code below.
http.authorizeRequests()
.antMatchers("/signup", "/login").permitAll()
Any other request requires that the user be authenticated.
If i use one module at a time there is no problem,
But if try to use them back and forth at the same time then the problem is that i have to login again to the previous app every time i use the other one.
Eg.
Goto Login page to module1 - (Header response has set jsessionid=XX) ok
Login to module1 - ok
Browse secured content on module1 - ok
Goto Sign Up page on module2 - (Header response has set jsessionid=YY) ok
Try to browse to another secured content on module1 - I have to login again
I'm quite sure it's due to the jessionid being reset by module2.
Are HTTP cookies port specific?
I have read this article which states that cookies are not port specific.
But there must be a solution so that i don't have to login everytime i switch apps.
You need to use different cookie names for the two applications.
There are different ways to do these, the most simple one, for a spring-boot application with version >=1.3 is just setting a property :
server.session.cookie.name = MYSESSIONID
Other ways are described in this post .
Map your applications to different context paths, so the JSESSIONID cookies will be independent; otherwise, the cookie is for the same context, so there is effectively one cookie for both applications. Another solution would be to use different hosts.
Please note that you don't only change context path of the cookie here: if you change context path of your application, Servlet API implementation will handle cookie context path change for you.
I've experimented a bit with same host and different context paths.
I'm currently having two applications launched, both have Servlet API as their base (and JSESSIONID cookie is defined by Servlet API's session mechanics). The applications both run on localhost, on different ports, and with different contexts (/app1 and /app2). I've logged into both applications, and in Chrome's dialog which lists cookies I can see two JSESSIONID cookies: one for localhost and /app1 and another for localhost and /app2.
Then I logout in /app2. Its JSESSIONID is destroyed and recreated with different content (because I've been redirected to the login page again). (Please note that to see that change I had to close Cookies dialog and reopen it as Chrome did not update it on the fly). At the same time, JSESSIONID cookie which belongs to /app1 is intact, and I can proceed working in /app1 (so I was not logged out from it).
UPDATE
One more experiment. I've mapped both appilcation at the same context (/app1). They run on localhost:8084 and localhost:8085. I do the following:
I log into the first application (port 8084)
I log into the second application (port 8085)
I switch back to the first application tab, click any link and see that the session is destroyed (as I am being redirected to login page).
So even if applications run on different ports of the same host with the same context path, they use the same cookie. Basically, this is what was said in Are HTTP cookies port specific? : Cookies do not provide isolation by port
A little summary:
Different hosts: no problem, cookies are different
Different application contexts: no problem, cookies are different
Same host, same application context, different ports: there is only one cookie, and this causes a conflict.
So the recipe is the same as before:
Either use different hosts (that is host names, not including port)
Or use different context paths
Or (as another answer suggests) change cookie name to avoid the conflict

Persistent cookies are not being shared across subdomains

I have 2 asp .net applications running on the same domain (both in staging & production). Application A opens a page from Application B in a popup window. The cookie names for staging and production are different.
But strangely for some users, even though the request is for production, staging cookies are being appended to the request. Is it a cached request being pulled from somewhere? Where the production cookies going? In Application A the cookies are found and they are fine. But Application B is getting the staging/wrong cookies.
Sorry for not sharing any code for confidentiality issues. Here's an example:
In application A, following cookies are there:
BDT, path="/", domain=".sample.com" (this is production)
In application B, cookies are somewhat like this:
SBDT, path="/", domain=".sample.com" (this is staging cookie)
Is the request being cached (at the machine or some proxy server) and being issued repeatedly? Or can it be some mal-ware/virus?
User is using IE9 (in IE7 mode) on Windows 7
finally we cracked it.
We again carefully analyzed the HttpWatch logs and noticed that, the App B is being run in IE protected mode, where as App A is not.
We requested the client to clear the cache and launch the applications again. After that we found that,
App B is getting NO cookies at all
We made a guess that, they are running in IE protected mode with High security level enabled. And they have ONLY 'App A' in the trusted sites list i.e AppA.sample.com
We requested them to add *.sample.com instead and that FIXED the issue.
For more details check:
Persistent cookies are not shared between Internet Explorer and Office applications

Are cookies safe in a Heroku app on herokuapp.com?

I am developing an app, which I will deploy on Heroku. The app is only used within an iframe on another site, so I don't care about the domain name. I plan to deploy my app on example.herokuapp.com instead of using a custom domain on example.com.
My app uses cookies, and I want to be sure that others cannot manipulate my cookies to protect my app against session fixation and similar attacks. If attacker.herokuapp.com is able to set a cookie for herokuapp.com, browsers will not be able to protect me, since herokuapp.com is not a public suffix. See http://w2spconf.com/2011/papers/session-integrity.pdf for a detailed description of the issue.
My question is: When browsers can't protect my users, will Heroku do it by blocking cookies for herokuapp.com?
Just wanted to post an update for anyone who ran across this question as I did. I was working on a similar problem, except that I wanted to purposefully allow access to the same cookie from two different heroku apps.
"herokuapp.com" and "herokussl.com" are now on the Public Suffix List, so your cookies should be safe if they are set for one of those domains. I ended up having to use custom domains in order to share cookies across both apps.
Heroku also released an article on the topic: https://devcenter.heroku.com/articles/cookies-and-herokuapp-com
I just tried to add a cookie from my Heroku app with the response header Set-Cookie: name=value;Path=/;Domain=.herokuapp.com, and to my disappointment, I could see the header intact in my browser. So the Heroku infrastructure does not detect and remove this cross-app supercookie.
I see three possible ways to protect a Heroku app against cross-app supercookies:
Don't use cookies at all.
Use a custom domain.
Verify that each cookie was actually set by your app, and restrict it to the client's IP address by checking the X-Forwarded-For header.
My feature request to Heroku would be that they should filter HTTP responses that goes through their HTTP routing, such that applications hosted on their infrastructure cannot set cookies with Domain=herokuapp.com.
It seems to me that, as long as you set the cookie for example.herokuapp.com, then the cookie is safe from manipulation. The cookie will only be presented to the app running on example.herokuapp.com and to herokuapp.com (where no app runs).

Coherence - Cookie Session Sharing between Applications Hosted on Different Servers

Coherence - Cookie Session Sharing between Applications Hosted on Different Servers
i have some web application on different servers i need them to have shared cookie
session in browser.
i want to assign same domain to all of them with different urls.
how can i implement this?
is it actually gonna work?
i want to do it with virual host on a proxy server.
The first way that comes to mind is to create a symbolic link in your DocumentRoot to a mounted directory which exists on another server. If you do this cross-server and for each application, then no matter which server people arrive at (due to load balancing, etc.) each server has a 'complete' set as far as apache is concerned but actually you still have the different data in its respective place.
In your /html/ directory (example DocumentRoot) you would have:
application1/
application2 -> /mnt/application2/
application3 -> /mnt/application3/
Then you'd set up the mount - for example - so a df would have:
192.168.1.2:/var/www/html/application2 ... /mnt/application2
192.168.1.3:/var/www/html/application3 ... /mnt/application3
Doing it this way keeps the guy on the same site as far as apache and his browser, etc. are concerned and you are definitely using the same domain, but essentially just splitting the file system between servers based on url.