Authentication and Authorization experiences, designs and demos


#1

It would be nice with some good tutorials, demos and design ideas for how to go about authentication and authorization for an app (perhaps as part of official documentation as well). I have seen various approaches and plugins out there, but still feel hesitant to jump into the deep water…

I would imagine that the most common way is via auth_tickets, preferably via an external auth provider such as facebook, google etc. I have seen an ember-oauth2 library on github but who has used it with success?

I assume you have to have a callback handler on the server (fx a Rails controller action) and then take the user info and store it in the User database if not there, or retrieve the user if already previously registered. Then set the auth_ticket, and pass it on each Ajax request (fx in the header) to keep the user session going. Then perhaps a before_filter on the server controller (or clock/timer on the client side) to terminate the session/auth_ticket. Am I on the right track here?

How about authorization? I have seen discussions on how to do it, either controlled purely from the client side, or alternatively by making server-side calls (via custom ajax) and then have the server respond with the permissions for the particular action (fx using cancan lib, hooked into ActiveModel::Serializers for rails).

What are the current best-practices and experiences out there? any good demo apps showing off these techniques. Thanks!


#2

I had a good experience this weekend with heartsentwined/ember-auth - hooks in really nicely with Devise & ActiveModel::Serializers. They also have a tutorial showing how to use it - it’s a bit of CoC and then it’s super-simple to use.


#3

Awesome! I’m planning to use Sorcery and Mongoid however, so not so “out of the box” for my tech stack I think :wink: But I will check out that tutorial for sure. Would be nice if there was one for Sorcery as well… I will sure post my experience (or tutorial) if I get it up and running… How about Oauth2 with Ember?


#4

I know the hardcore RESTful folks think you should only use token based authentication, but I was able to get basic Sorcery authentication working with Ember pretty quickly using plain old standard session techniques.

As far as I know, Sorcery does not offer token based authentication yet (although there is a pull request waiting).

It’s dirty, but what I ended up doing was basically dumping some user information into the global javascript namespace (from my Rails app) and then using the ApplicationRoute to pull in and set the info for my app.

App.ApplicationRoute = Ember.Route.extend({
  setupController: function(controller, model) {
    controller.loggedIn = window.loggedIn;
    controller.isAdmin = window.isAdmin;
    this._super(controller, model);
  }
});

My login and logout methods both use standard ajax calls that exist within a SessionsController, setting the ApplicationController properties when required (using needs) Below you’ll see a simple example of my authenticate method:

App.SessionsController = Ember.Controller.extend({
  needs: ['application'],

  authenticate: function() {
    var that = this;
    var applicationController = that.get('controllers.application');
    
    var request = $.ajax({
      type: 'POST',
      url: '/sessions',
      data: that.params(), // just returns a params hash
      dataType: 'json'
    });

   request.done(function(data) {
     applicationController.set('loggedIn', true);
     that.transitionToRoute('logged_in_route');
   });

   request.fail(function(data) {
     applicationController.set('loggedIn', false);
     that.set('errorMessage', 'There was a problem with your email or password');
   });
 }

});

#5

Great Sorcery example :slight_smile: In my own fork of Sorcery I have extra Mongoid generators and the token_auth fork included. I will use those… It shouldn’t be too much trouble. The auth_token module looks very solid and easy to use :slight_smile:


#6

kmandrup we are in the process of working through this issue ourselves. We are not using a Rails back-end but rather an express/mongoose server that we wrote. I think the tech stack is very similar between us despite the server difference.

At the moment, I am using an initial authentication ajax call which, if successful, parses the provided username and pw (through bcrypt for encryption/security) and then returns a session token from the server. This token is stored in server memory (could be redis in the future) as a key-value with the associated user id.

When future requests arrive from the client they will contain the cookie in the header. I have a “requireAuth” middleware infront of every API route that checks for the user associated with the provided cookie (extracted from the request header). If they can be found, then the API calls returns successfully. Otherwise, I return a consistently formatted 401 with a message that could be printed to the screen or whatever you prefer.

With regards to the Ember side of things, I am just beginning the experimentation. I am tempted to think that less is more here. I think the simplest solution is to define a UserController that does its own ajax call on login (outside the bounds of Ember-Data). If a valid payload is returned then it is set as the content of the UserController. If any payload comes back as an error, the UserController content is wiped. If they log out, the user controller content is wiped. Etc

If you would like to see my very WIP project where I am exploring this stuff you can follow it/clone it/whatever at https://github.com/4South/express-ember-auth

I will be working on it all day today so feel free to get a hold of me if desired through twitter, this thread, or irc.

Steve


#7

Given that it appears to be common to use token-based authentication in ember.js apps, I wondered how developers are handling long-running sessions, and in particular, cases where tokens are due to expire whilst a user is logged in.

As far as I can tell, there are a couple options:

  • Use a refresh token to obtain a new access token before it expires, as mentioned in the OAuth 2.0 spec. The details of this method seem to be a bit fuzzy to me (I think the spec assumes an authorization server and a resource server)
  • Use a long-lived access token (+ cookie to store it in), and assume users don’t mind the enforced “Remember me” functionality

Any other ideas?

… and a bonus question: should access tokens be hashed before being saved to the database?


#8

I’ve been using Ember Simple Auth to great success on a client project…


#9

Yes, I’ve been looking into ember-simple-auth. How long are your tokens valid for? and how do you handle expiration (whilst a user is logged in)


#10

We’re not expiring our tokens yet since we’re still pre-launch but I believe ESA has some support for refresh tokens.


#11

I am also intensively researching ways to authenticate a REST API. This is not really an emberjs issue but since this API will mainly be consumed by an emberjs client it kind of is… Many times I read about various (mostly token-based) approaches. Most of them are kind of home-brewn. At first glance this seems to be ok (and may really is ok for non-critical application), but then this #1 rule of security comes to my mind: Don’t try it yourself, you will most likely do it wrong. This is especially true for security protocols.

So what do you think about this problem. Is it even a problem for you?


#12

@matthooks: thanks for clarifying.

In researching this problem, I came across a discussion on the OAuth mailing list re: Refresh tokens, which suggests ways to achieve long-lived sessions:

… the authorization server can issue:

  • an access token good for an hour, with a refresh token good for a year or good-till-revoked
  • an access token good-till-revoked without a refresh token
  • an access token good-till-revoked with a refresh token, used to obtain additional access tokens for a distributed environment

For simple authentication systems the top two points are viable options. The first approach is reviewed below.


The OAuth 2.0 spec outlines strict requirements for implementing refresh tokens, to ensure that new access tokens cannot be easily generated and retrieved. The following is taken from the OAuth 2.0 spec with regard to requesting a new access token with a refresh token:

The authorization server MUST:

  • require client authentication for confidential clients or for any client that was issued client credentials (or with other authentication requirements),
  • authenticate the client if client authentication is included and ensure that the refresh token was issued to the authenticated client, and
  • validate the refresh token.

From this, I gather that, when refreshing an access token, authentication is required (the spec uses HTTP Basic auth in the example), and that there has to be some way of identifying that the refresh token was issued to the client. It’s on these points where I don’t believe that Ember Simple Auth conforms—it simply sends up the refresh token as a request param, along with the soon-to-expire access token.


Conclusion: Right now, the simplest implementation I can think of is having good-till-revoked tokens and communicating over SSL. This keeps user credentials safe (by the nature of access token-based auth), prevents man-in-the-middle attacks (using SSL), and ensures that a user sends authenticated requests for as long as the cookie is valid. It also eases managing valid tokens in the browser and on the server. The downsides are that the access token is stored as plain text both in the database and in the cookie, and so if either are somehow leaked, it’d be easy for an attacker to assume a user’s identity.

I’d gladly welcome feedback/criticism on this.


#13

I’m the main author of Ember.SimpleAuth so a quick note from my side: client id/client secret are now supported (see this pull request). HTTP Auth is not supported but if anyone would like to send a pull request I’d be ok with adding it. The main point here is that both client id/client secret as well as HTTP auth don’t really provide additional security. If an attacker can get access to your refresh token they can most likely get access to the client id/client secret or basic auth or whatever as well. The problem is that all this security-relevant stuff needs to be on the client (as it’s used by Ember) and thus can be exposed by an attacker if you a) don’t use (correctly configured) SSL or b) are vulnerable to XSS attacks.


#14

@marcoow excellent explanation. Thank you.


#15

I created a project permit-authorize, which is a bit similar to CanCan in the Rails world.

It uses permit objects as an extra abstration to encapsulate a specific set of permission rules for some “domain” (any logical entity/grouping/category really). It includes caching for performance and loading of rules from any JSON source (file, data store etc.)

Available for both client and server via npm and bower.

Give it a try :wink:

Minimal dependencies (a few lodash functions, custom light build of lodash).


#16

Hi @kmandrup is there example code to integrate with Ember.js?


#17

It is designed to be pluggable with any system, lib or framework. There are many ember exames for how to create a can handlebars helpers by extending if helper, and you can use it in router as well via hooks. See fx simple auth


#18

I’m in the process of refactoring the auth library into small modules that can be combined or substituted as you like, so you can opt in to the parts you want. @kithokit you are welcome to have a look and help out if you’re interested…


#19

I’m starting out on a new ember-cli app. I was wondering what type of authenticating to use. The ember-cli app would be an OAuth client to our custom OAuth server/provider.

The two OAuth grant type options we have are Implicit Grants, or using Authorization code workflows. What confuses me is that the Implicit Grant workflow is said to be less secure, but is the default in client side static apps which need to work with OAuth. What are folks doing in this area?