Search code examples
ember.jsember-simple-auth

Using ember-simple-auth when the login page is on another system


The page to login to our application is a jsp hosted on another machine. I have managed to get requests firing to this machine by modifying authenticated-route-mixin by allowing window.location.replace to be called if the route start with http.

  beforeModel(transition) {
    if (!this.get('session.isAuthenticated')) {
      Ember.assert('The route configured as Configuration.authenticationRoute cannot implement the AuthenticatedRouteMixin mixin as that leads to an infinite transitioning loop!', this.get('routeName') !== Configuration.authenticationRoute);

      transition.abort();
      this.set('session.attemptedTransition', transition);
      debugger;
      if (Configuration.authenticationRoute.startsWith('http')) {
        window.location.replace(Configuration.authenticationRoute);
      } else {
        this.transitionTo(Configuration.authenticationRoute);
      }
    } else {
      return this._super(...arguments);
    }
  }

This is working but when I am redirected back to my application, ember-simple-auth thinks I am no longer logged in and redirects be back to the remote machine, which then sends me back to the application in an infinite loop.

Obviously I need to set something to let ember-simple-auth know that it it is actually logged in. Why is it not doing this automatically? What am I doing wrong?

I am pretty new to oAuth so I could be missing some basic setting here.

Here is the URL.

  ENV['ember-simple-auth'] = {
    authenticationRoute: 'https://our-server.com/opensso/oauth2/authorize?client_id=test-client-1&response_type=code&redirect_uri=http%3A%2F%2Flocalhost%3A4200%2Fsecure'
  };

Solution

  • Instead of modifying the AuthenticatedRouteMixin, I'd recommend handling your app-specific login in an Authenticator-- the key configuration primitive that Ember Simple Auth provides as part of its public API.

    To the best of my understanding, on first loading the app, and checking to see if a user is authenticated, Ember Simple Auth will use the restore method, defined as part of the Authenticator API.

    You can return a promise from restore that resolves or rejects to indicate whether the user is authenticated. How you check this is an implementation detail of your auth system.

    I don't know how you're storing credential(s) on the client (would be great if you could provide more detail), but here's an example flow, using cookies for authentication:

    1. Ember boots, ESA attempts to restore the session.
    2. restore makes a simple AJAX request to a secured, "dummy" resource on your Java server-- and checks if it gets back a 200 or a 401.
    3. We get a 401 back. The user isn't authenticated, so reject in the Promise returned from restore.
    4. Let ESA redirect the user to your authentication route. Ideally, don't override the AuthenticatedRouteMixin-- instead, use the beforeModel hook in the authentication route to send users to your JSP login page.
    5. The user correctly authenticates against the JSP form.
    6. In its response, your Java server sets some kind of encrypted, signed session cookie (this is how it generally works with Rails) as a credential. In addition, it sends a redirect back to your Ember app.
    7. Ember boots again, ESA calls restore again.
    8. restore pings your Java server again, gets a 200 back (thanks to the cookie), and thus resolves its Promise.
    9. ESA learns that the user's authenticated, and redirects to the 'route after authentication'.

    Keep in mind that, at its core, ESA can only indicate to the client whether the backend considers it 'authenticated' or not. ESA can never be used to deny access to a resource-- only to show something different on the client, based on the last thing it heard from the backend.

    Let me know if any of that was helpful.