1

I'm using Ember 2.3 with Ember Simple Auth 1.0 and am wondering if anyone had any suggestions on the best approach to handle the following situation:

With the particular industry my platform serves, most staff are actually independent contractors and therefore could belong to multiple businesses. With that said, I have some specific requirements that I'm trying to address:

  • Avoid having to create a separate account with separate credentials for each business the staff member belongs to.
  • Allow credentials to be revoked at any time for a particular account.
  • Allow for account-level permissions.
  • Make it simple to switch accounts from inside the application without having to fully-reauthenticate.

To achieve this, my initial implementation is based around issuing a single JWT (using ember-simple-auth-token) for each user account. The proposed authentication flow would be as follows:

  1. User logs in with username and password
  2. System authenticates and if credentials are valid, return a token for each account.
    • If the system returns no tokens, return an error.
    • If the system returns a single token, use that token by default and redirect to the authenticated area of the site.
    • If the system returns more than one token, display a list of the accounts associated with those tokens and allow the user to choose the one in which they will be assuming the role of at that point.

What to do when the system returns more than one token is where I have questions:

  • Is there a way to "intercept" to allow the user to choose which account/token to use before ESA commits the token to the session in local storage?
  • If I want the user to be able to switch accounts, is it just a matter of swapping out the token value in local storage?

If there's anything else I should consider, I'd appreciate the feedback. If you also happen to think this is a terrible approach and have some feedback, I'd absolutely love it.

Cheers.

jdixon04
  • 1,435
  • 16
  • 28

1 Answers1

3

From ESA's perspective the user would be authenticated when the backend responds with one or more tokens (you'll have to implement a custom authenticator and authorizer of course). The fact that the session actually contains multiple tokens for multiple accounts isn't relevant for ESA really - that would be sth. that you'd need to handle in your application code instead.

Once the session is authenticated with one or more tokens, you can access them via the session's data.authenticated property, e.g. this.get('session.data.authenticated.tokens') etc. You could store the currently active account the user wants to use in the session's non-authenticated area, e.g. this.get('session.data').set('activeToken', 'whatever').

marcoow
  • 4,062
  • 1
  • 14
  • 21
  • Thanks! This makes much more sense now. Really appreciate your feedback and for creating ESA in the first place! – jdixon04 Feb 03 '16 at 20:47
  • one thing I noticed when trying to implement this is that on successful authentication, the application transitions to the`routeAfterAuthentication` route before the `authorize` method is called on my custom authorizer. Because of that, any ember-data calls I have on that route aren't able to use the token that's been set. Does this sound correct to you? – jdixon04 Feb 03 '16 at 21:44
  • Nix the previous comment. I figured out the issue on my end. Cheers! – jdixon04 Feb 03 '16 at 22:01
  • One last question: you mentioned storing the currently active account in the non-authenticated area of the session. Is there a particular reason for that? – jdixon04 Feb 04 '16 at 02:12
  • Actually, that wasn't my last question :) I'm trying to override the `restore()` method in order to be able to restore the session. I just realized that when I set the `activeAccount`, it doesn't persist to `localStorage`. Is there a recommended way to do so outside of just accessing it directly? – jdixon04 Feb 04 '16 at 02:41
  • You store the active account in the unauthenticated area of the session because you must not write to the authenticated area. You should not override the `restore` method of the session of course BTW - I guess you're referring to the one in the authenticator. Any data you set on the session's `data` property should be stored in the session store - of course you cannot actually store Ember Data objects or so in the session data, only values that are serializable to JSON. – marcoow Feb 04 '16 at 10:37
  • Here's what I have: I store the `activeAccount` in `session.data`. I overrode `authorize()` in my custom authorizer and I'm able to access that property directly using the `session` service since only the `authenticated` data is passed via the `data` argument. I then have to override `restore()` in my custom authenticator or else it doesn't know how to restore the session if I reload the page. Unfortunately, I can't access the session data using the `session` service. There is data, but it's just an empty object: `{ authenticated: {}`. https://gist.github.com/jamesdixon/7353bfcc11794463fa6f – jdixon04 Feb 04 '16 at 19:09
  • I was able to get all of this working, but I had to write the active account to the authenticated area. Everything appears to be working properly, but you did say that the `authenticated` area should NOT be written to. Is there a specific reason for not doing so? Am I compromising the security of the system by doing so? Sorry for the barrage of questions. Thank you! – jdixon04 Feb 09 '16 at 23:38
  • Yes, you should not write to the `authenticated` part as that's controlled by ESA through the authenticator which might not know and/or care about your custom properties and override them. Also the internals of the `authenticated` part are considered private API and might change in the future. There's also an assertion preventing writes to the `authenticated` area which is currently not working 100% but once that is fixed your code will probably break. – marcoow Feb 10 '16 at 08:05
  • Bummer. Any suggestions given the code I presented above regarding not being able to access anything in the session service in the custom authenticator? Thanks again for your help. – jdixon04 Feb 10 '16 at 08:10
  • If you store the active account in the general part of the session store instead of the `authenticated` part everything should be fine. – marcoow Feb 10 '16 at 08:14