Search code examples
ember.jsember-simple-authsimplesamlphp

Ember SimpleAuth & SimpleSAMLPHP Screen Flash


I'm building an Ember application and I have to integrate with SimpleSAMLPHP to handle authentication against multiple identity providers (IdP). At a high level, the authentication flow is as follows:

  • User navigates to Ember application
  • User is not authenticated (via SimpleAuth) and sees view A.
  • User clicks "log in" and is directed to SimpleSAMLPHP, which is outside of the Ember application.
  • User enters credentials and is authenticated against whatever IdP and returned to the Ember application.

It's on this return to the Ember application that's the problem. Ember will load view A (the non-authenticated view) because Ember SimpleAuth has not yet reached its sessionAuthenticationSucceeded callback. That callback is reached shortly thereafter and I can render the authenticated view B into the outlet. The problem is the user sees a flash of view A prior to seeing view B.

  • Can I POST to SimpleSAMLPHP via AJAX without having to leave the Ember application? I'm assuming that would defeat the point, create security issues, etc.
  • Or is there a way to have Ember differ rendering until the sessionAuthenticationSucceeded callback is reached?
  • I suppose I could also use some trickery and have view A always be a spinner or something and then render a new view when ready. I think this might just cause other problems, since sessionAuthenticationSucceeded is only executed immediately after authentication.

I'm either missing something simple or there's just not really a good way to do this. I'm open to any suggestions, thanks in advance.


Solution

  • What I ended up doing was basically not having any view logic at the "index" route of my Ember application and instead, creating a new route, which I redirect the user to after log in. I also added the AuthenticatedRouteMixin so I could use the beforeModel hook transition. The gist of it is:

    App.ApplicationRoute = Ember.Route.extend(
        SimpleAuth.AuthenticatedRouteMixin,
        SimpleAuth.ApplicationRouteMixin, 
        {
    
        beforeModel: function (transition) {
            var session = this.get('session');
    
            if (!Ember.isEmpty(session)) {
                this.transitionTo('new route');
            } else {
                this._super(transition);
            }
        },
    
        model: function (params) {
            // ...
        },
    
        renderTemplate: function () {
            // ...
        },
    
        actions: {
    
            sessionAuthenticationSucceeded: function () {
                this.renderTemplate();
                this.transitionTo('new route');
            },
    
            authenticateSession: function () {
                // ...
            },
    
            invalidateSession: function () {
                // ...
            }
        }
    });
    

    Effectively the user is redirected to SimpleSAMLPHP, logs in and on redirection back, Ember redirects to the new route. If they refreshed the page, we see that they have a session in beforeModel and redirect to the new route as well. Now there's no screen flash for the user.