A Faster / More Scalable Approach to Twitter OAuth Dance in Rails? - ruby-on-rails

I'm running a Rails app on the Heroku Stack (complete with Memcached, DJ Asynchronous workers, MongoDB persistent storage).
Right now we use Twitter Oauth as the only authentication option on our site. (We plan to branch out to FB connect, OpenID, and/or Email/password eventually).
Ruby/Rails apps, as you probably know, don't support concurrency out of the box. On Heroku, you can spin up additional app instances (dynos), which increase your concurrency (concurrency capability = number of dynos), but each one costs $36/month.
In general, this hasn't been a problem, because the average request on the site takes <100 ms.
EXCEPT for Twitter OAuth. The OAuth-related requests to Twitter take, on average, around 3,500 ms.
So basically, when anyone logs in an entire app instance gets held up for 3-4 seconds.
Is there any decent way to mitigate this? Would it be weird to put these actions in asynchronous DJ workers? It could make logging in a little slower, but at least if a bunch of people are logging in at once and/or Twitter is being really slow, these processes do not affect the rest of the app / other web requests?
Any other ideas?

I would say that this advice is now superseded. I'd suggest you use OmniAuth instead, possibly with Devise if you need normal auth as well.
OmniAuth is a Rack app as suggested and you basically get all the "big" OAuth providers working in fell swoop.
There are 2 OmniAuth specific RailsCasts that walk you through exactly what's needed: OmniAuth Part 1 and OmniAuth Part 2

You could push the oAuth into a rack middleware app - then at least only a rack app gets spooled up instead of the whole rails stack. That should make it a little quicker (though it will still take up an instance).
That being said, there is no reason why you can't put authentication into it's own app, especially if it's all in the same domain (so any authentication cookies are still local to the domain). Though you'll have to be really careful of security issues - eg man-in-the-middle attacks etc. Better if somebody's already done the work/bugfixing for you :)
You can even have an authentication app on an independent app domain if you use rubyCAS: http://rubyglasses.blogspot.com/2009/12/rails-single-sign-on-with-rubycas.html

Related

New single page app needs to authenticate to legacy app using Shibboleth

I am creating a new React SPA. Users of a legacy app need be able to use the new app without re-authenticating. So I need to support SSO.
It's important to note that it is also required that users of other (currently unspecified) apps should also be able to use the new app without re-authenticating, so whatever approach I take needs to be sufficiently decoupled to potentially allow this.
The legacy app supports authentication via Shibboleth, the new app currently has no authentication method, but uses JWT for authorisation.
I'm wondering if anyone has any experience of such a scenario? It seems to me that I probably need to be create an OAuth2 authorisation server for the new app to talk to and I need to somehow bring Shibboleth into the mix for the authentication, maybe with the authorisation service acting as a Shibboleth Service Provider. Googling around hasn't revealed much useful info.
Is what I've described along the right lines? I know it's very high level and woolly, but I'm really not sure of the approach to take. Any advice, information or experience in this area would be gratefully received!
GOALS
It's a little bit of a subjective question, but the main goals are usually as follows:
Focus on building your UI and API security in a future facing manner
Also provide good Login Usability
Also deliver on non functional requirements such as availability / reliability
AUTHORIZATION SERVER
On the first point, the modern option is to integrate UIs and APIs with an Authorization Server - perhaps as in My Tutorial. Your architecture is then good, but the migration is not trivial.
FEDERATING TO SHIBBOLETH
The Authorization Server can then redirect to Shibboleth and talk SAML2.0 to achieve Single Sign On, as you suggest. It is a complex solution though, and may be a backwards step in some ways.
AVAILABILITY
This is usually a big concern, and most companies use a cloud provider such as Azure / AWS due to its high availability / low maintenance / low cost. Would this be a better option for you?

Is it a good idea to have frontend app share session on subdomain?

I'm working on breaking out a piece of my company's codebase (a monolithic Rails app) into a separate React application that communicates with the main application's API.
Originally, I was going to authorize requests with JSON web tokens. But then I realized that you can set up Rails apps to share sessions. So I put the React app inside of a Rails app that has no DB and configured it and the main app to share their sessions. The main app redirects users to this app living on a subdomain, and I don't have to worry about complicated login logic because the sessions are shared.
I'm curious if there are any drawbacks or reasons why this wouldn't be a good approach.
My humble feedback on this topic would be to attempt to intelligently, and of your own understanding, answer the below questions and see how you feel about those answers.
what does rails add to the process of session management? ie, encrypting the cookie and verification of that cookie.
how strong does this process 'seem' to you?
how could the process be exploited and or negatively manipulated in a subdomain like environment?
how much does exploitation matter (ie, sensitive financial data on an application at scale or a potential throw away prototype to learn about something)
JD

How to stop fake web traffic from internet?

I have a website that pays users for showing advertising on shortened links. I recently have someone who is trying to boost his earnings by sending fake traffic to the site. It is not only smashing my site (ie. slowing it down) but is also skewing my Google Analytics data.
Is the only solution here really to deploy a WAF, or roll my own Rack based request inspection code? I not sure how this would work or best practices in a Heroku/Ruby on Rails environment.
Any one have experience on this or have any ideas?
If the requests are being sent at a much higher rate than regular visitors do, the rack-attack gem might be very useful to you.
It allows throttling requests, so if a user visits some page at a higher frequency than allowed for a while, you can (temporarily) block any further requests.
From the gem's README:
Rack middleware for blocking & throttling abusive requests
Rack::Attack is a rack middleware to protect your web app from bad clients. It allows whitelisting, blacklisting, throttling, and tracking based on arbitrary properties of the request.
Do define the rules with a safe margin, so your application won't be blocking regular users who aren't spamming your site.

omniauth vs. oauth-plugin

I'm trying to figure out the differences between omniauth (https://github.com/intridea/omniauth) and oauth-plugin - (https://github.com/pelle/oauth-plugin)
I'm simply looking for a way to allow my users to authenticate with (Twitter, Facebook, etc) within my app.
I know omniauth provides this, but I'm running rails 2.3.10 which I don't believe is supported by omniauth. Can I use oauth-plugin? It also seems to have a lot fewer dependencies. Any thoughts are appreciated.
I have to disagree with the previous answers.
oauth-plugin is
a plugin for implementing OAuth Providers and Consumers in Rails applications. 1
It provides two generators (one for implementing an OAuth provider, one for the consumer) which create the models, the views and the controllers. The way the controllers work, is that they are subclasses of controllers defined in the gem. It's tied into Rails pretty deeply, and can only do OAuth.
omniauth, on the other hand, is a modular, framework-agnostic library that allows you to provide authentication via a multitude of providers.
Concretely, it means that you set up two endpoints (/auth/:provider and /auth/:provider/callback), have your user authenticate with the provider, and receive a hash with the user's info in return.
TL;DR
If you only need to provide authentication via Facebook/Twitter/OAuth/etc (i.e. you want to be an OAuth consumer), then omniauth is definitely more lightweight.
If you want to run an OAuth provider, oauth-plugin might be more straightforward, but it tends to be a lot more bloated, in my opinion, since it injects a lot of boiler-plate code into your app.
Omniauth is a mega-authorization gem, giving you access to the OAuth processes for a whole list of web services (Twitter, Facebook, Foursquare, Gowalla, Netflix, YouTube, etc, etc), so you can call specific functions for each service and get it set up quickly.
The oauth-plugin you mention appears to just set you up with an OAuth general setup, and you'd have to do the API hookups for each service yourself. More lightweight, so if you only need Twitter services, for example, that might be a better way to go, although I'd still probably check out Omniauth to see how big of a performance drain it is, because it's going to be a lot easier to use overall.

Using Merb for Facebook Application

Since Rails is not multithreaded (yet), it seems like a threaded web framework would be a better choice for a Facebook application. (reason being is cuz each Rails process can only handle one request at a time, and facebook actions tend to be slow, because there is a lot of network communication between your app and facebook)
Has anyone used Merb to write a Facebook application? Is there a port of Facebooker (the Facebook plugin for Rails) to Merb?
We've used merb_facebooker in one of our projects (Rock the Vote), and it worked out pretty well. Testing Facebook apps is quite annoying, as you don't have control of the middleware, so watch out for your expectations of the FB API and make sure you validate as much of them as possible early in the development stages (not trying out all the things we needed to do with fbML early on brought a few headaches).
Behold, merb_facebooker.
In addition, if you want to use Facebooker directly (like for a desktop app,) just install the gem:
gem install facebooker
Have you looked at Starling? It's the server used by twitter to handle their messages. It's a persistent queue server that allows you to delegate jobs to workers.
You can run passenger on Apache which will start up as many Rails instances as it needs up to a certain limit (I think the default is 30). It will also kill them as required, so if you're not getting as many hits as you were 5 minutes ago, it will release the system resources back to the system.
Learn more about passenger at http://modrails.com

Resources