We are designing an application that will use Rails and Wordpress to interact with each other. We would like to have a universal logout where you could logout from either application and it would delete cookies from the other app. They will share the same host and toplevel domain. Is there a way to do this?
Access to a cookie is dependent on the domain of the server attempting to read the request -- and potentially the domain specified in the cookie. So assuming the domains match (e.g. www.example.com and www.example.com on both blog and Rails app) either should have access to a cookie set by the other.
If this is not the case (e.g. blog.example.com, www.example.com), you'll need to make sure when the cookie is set in either place, it's set for the entire domain (e.g. .example.com). But this doesn't help: while Rails can delete WP's cookie, and vice-versa, the method for creating (and using) them needs to be mutually understood.
So there's a twist here, since this is a session cookie; in this case, the cookie (which either app should have access to) is setting a value that is used and interpreted on the server side, where sessions are managed. WordPress and Rails both different methods and look for different cookies.
A solution (idea) would be to have one or the other subsystem catch incoming requests (most likely WP, and probably through some .htaccess RewriteRule, assuming you're using Apache) and create an intermediate cookie that the other could check that provides sufficient proof that the user has logged in correctly. WP's PHP for this is pretty good, and easily extended -- you just need to create some token that's a shared secret between the two apps (one of the values in wp-config.php such as LOGGED_IN_KEY might be a good option).
Maybe a solution would be to take the publicly available value from the WP cookie for username, and append the shared secret value and (in both systems) create an MD5 hash to store in a cookie. In this case, Rails' authentication would subordinate to WP's, so you would need to make sure Rails knew to delegate things like forgotten password, changed password, etc, to WP's mechanisms.
Obviously I am thinking aloud, but maybe this is a path to consider.
In any case, this is preferable to having both systems know how to trust the other's authentication.
Fiddling with cookie deletion appears to be dirty and error prone.
You might rather want to have a look at auth providers and the according plugins such as:
OAuth (WP - Rails; maybe make either side an OAuth provider)
CAS (WP - Rails)
LDAP (WP - Rails)
...
Maybe it's an option to switch from WP to one of Rail's CMS like:
Refinery CMS
Typo
...
Related
In an environment where a very big online application/web is divided into subdomains:
app1.mydomain.com
app2.mydomain.com
Each app is able to handle its subdomain session cookie.
However, in order to mantain certain data live through all apps, like session provider and account information in a multi-single-sign-on environment, it would be useful to also store/access session cookies at a domain level:
mydomain.com
What would be the best approach to handle simultaneously domain level and subdomain session cookies in Ruby on Rails? One issue would also be that this domain level cookie should be encrypted with the same hash across all applications/subdomains, which can be done, but doesn't fully integrate with Rails session design, unless all application share their secret token.
Best I could think of is use Rails default session handler for subdomain cookies, and create manually a domain level cookie handler, however it would be cool to be able to use session and domain_session as it is designed to be used more easily, though this is not a common issue.
I'm trying to figure out how ASP.NET internally validates that a cookie will allow the user to access the application.
CookieAuthenticationMiddleware will set .AspNet.Cookies with an encrypted value. After .NET successfully decrypts the cookie on a request, what validation occurs then?
Developing locally with IISExpress if I have an application (#1) that sets an authentication Cookie after the user logs in, and I create a complete new application (#2) also running on localhost, that is also using CookieAuthentication. When I access #2 it will read the cookie from #1 and allows the user to access the application as well.
I'm trying to understand what the limits are for cookie authentication.
There's not really any "validation" per se. The cookie's encrypted key is used to reference the user that should be "logged in". It works in a very similar way to sessions, where the session cookie holds an encrypted session id that the server can use to look up and restore the session via.
The encryption/decryption is based on the machine key, which either may be explicitly set in the Web.config or generated automatically by ASP.NET. Only applications that share the same machine key may decrypt the cookie, which is why it's so important to protect your machine key.
Anyways, there's two factors involved here. First, cookies are domain bound: only the domain or subdomains of the domain the cookie is set on will be given the cookie. This is handled by the client (i.e. browser). Your two applications currently are able to both see the cookie because they're both running on localhost. However, if you were to deploy one at foo.com and the other at bar.com, then they would no longer be able to see each other's cookies.
Second, the machine key is typically by server (unless you explicitly set it in the Web.config per app). As a result, sites running on the same machine can usually decrypt each other's cookies (assuming they see them in the first place, which again, is based on their domain).
It's not clear whether you're happy or not about this arrangement. If your goal is to segregate the two sites running locally, such that they don't share cookies, you have a couple of options.
You can explicitly set a different machine key for each site in their respective Web.config files. They'll still receive any cookies set by the other site, but they'll no longer be able to decrypt them, which basically results in them being ignored.
You can customize the auth cookie name. Instead of using the default cookie name you can make one .Site1.Auth and the other .Site2.Auth. Then, even though either site will also receive the cookie for the other site, it will simply ignore it, because it's not the auth cookie for it.
If, however, you're intending to rely on this behavior in production as well (i.e. you actually want logging into one site to log you into the other as well), then you'll need to explicitly set the machine key to the same value in both site's Web.config files. Additionally, you'll need to deploy them on the same domain, or at least subdomains of that domain. In the case of subdomains, you'll need to set the cookie domain to be the wildcard domain .mydomain.com for both. Then, you could have one at foo.mydomain.com and another at bar.mydomain.com, and they'd both see the cookie because it was set on .mydomain.com. If you leave it the default, set on the actual domain of the site, then bar.mydomain.com could not see a cookie set by foo.mydomain.com because that cookie would be explicitly set only for foo.mydomain.com.
The primary validations are encryption and expiration. If apps share an encryption context (e.g. machine key) then they can share auth cookies (providing other client side sharing rules like domains and paths are satisfied). So yes it's expected that two apps using IIS Express localhost on the same machine would share cookies by default.
The expiration is also embedded in the encrypted value so the client can't tamper with it.
My understanding of the session lifecycle in Ruby on Rails (specifically v3 and upwards) is that a session is created at the start of a request, for each and every request, and if that request doesn't carry an existing session cookie a new one will be created, otherwise the session cookie is deserialized and stored in the session hash.
The purpose of this, of course, supports a number of security features such as CSRF etc.
However, this poses a bit of an issue when it comes to caching of pages in a site with HTTP cache services and proxies such as Varnish, as most of the configurations tend to strip out these (generally all) cookies on both the request and response end (as the cache is usually intended for a generalized audience).
I know that it is possible to setup Varnish etc to create the object hash with the cookie details included, and this would scope the cached data to that session (and therefor that user), however I am wondering if this is completely necessary.
I have an application which is fairly 'static' in nature - content is pulled from a database, rendered into a page which can then be cached - there are a few elements (such as comment count, 'recent' items etc) which can be added in with an ESI, but for every request Rails still tends to want to setup a new session, and when a user already has a session this stuff is stripped out by the cache server.
I am wondering if it might be possible (via pre-existing functionality, or building the functionality myself) to allow the developer to control when a session is required, and only when that is specified is the back-and-forwards with cookies, session initialization/deserialization etc necessary.
That, or I am thinking about this problem the wrong way and need to address the issue from another angle...
From what I know rails sessions can be controlled fairly in-depth via ActionController::SessionManagement
http://ap.rubyonrails.org/classes/ActionController/SessionManagement/ClassMethods.html#M000070
There are examples in the API docs of disabling it per action, per controller, etc.
If your site is mostly static then you may want to use full page caching. This takes Rails out of the request entirely and let's the web server deal with it once the content has been generated. Might cause some serious headaches depending on your exact needs as far as the comment counts and user-specifics though.
I'm running into an issue with getting the right cookies for the current subdomain. I have two different instances of the same application, one running at the www subdomain and the other running at the test subdomain, but it seems like the test app is pulling in cookies from the www instead, even if there are explicit cookies for .test.domain.com (because it's different instances the same application, the cookie name is the same, but I am not looking to share sessions or cookies between the two instances).
Is there any way to specify what domain Rails should be looking for its cookies for? I have config.cookies.domain and config.action_controller.session[:domain] both set to "test.domain.com" (on the test app), but it doesn't seem to make any difference (and, as well, the cookies being set by the test domain are for some reason ending up with the domain .test.domain.com instead of test.domain.com and I'm not sure why, or if it's relevant).
Update: To make this more complex, I realized I do actually need the dot-prefaced cookie domains (ie. .test.domain.com and .domain.com), because in general, subdomains are supposed to share the main domain's cookies and session (it's only that the test subdomain is actually it's own application rather than being a subdomain of the main application). Obviously .domain.com cookies will apply to test.domain.com, but is there any way to make the explicitly test.domain.com ones take priority?
[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.