0

I am trying to set up an authenticator which would be valid for many providers, because in the backend I am using doorkeeper assertion method which handles the whole flow.

I have installed:

* "ember-cli-simple-auth": "0.8.0-beta.1"
* "ember-cli-simple-auth-oauth2": "^0.8.0-beta.2"
* "ember-cli-simple-auth-torii": "^0.8.0-beta.2"
* "torii": "^0.3.4"

I was looking at this issue Workflow for Ember-simple-auth, Torii and Facebook Oauth2 so I could write this:

# templates/login
<a {{action 'oauth2Authenticate' 'facebook-oauth2'}}>Login with facebook</a>
<a {{action 'oauth2Authenticate' 'google-oauth2'}}>Login with google</a>

# controllers/login
actions: {
  oauth2Authenticate: function(provider) {
    this.get('session').authenticate('authenticator:oauth2', { torii: this.get('torii'), provider: provider });
  }
}

# initializers/authentication
import Oauth2Authenticator from '../authenticators/oauth2';
export function initialize(container) {
  container.register('authenticator:oauth2', Oauth2Authenticator);
}
export default {
  name: 'authentication',
  initialize: initialize
};

# authenticators/oauth2
import Ember from 'ember';
import OAuth2 from 'simple-auth-oauth2/authenticators/oauth2';

export default OAuth2.extend({  
  authenticate: function(options) {
    var self = this;
    console.log(options.provider);
    return new Ember.RSVP.Promise(function(resolve, reject) {
      options.torii.open(options.provider).then(function(data) {
        var data = {
          grant_type: 'assertion',
          provider: options.provider,
          assertion: data.authorizationCode         
        };
        self.makeRequest(self.serverTokenEndpoint, data).then(function(response) {
          Ember.run(function() {
            var expiresAt = self.absolutizeExpirationTime(response.expires_in);
            self.scheduleAccessTokenRefresh(response.expires_in, expiresAt, response.refresh_token);
            resolve(Ember.$.extend(response, { expires_at: expiresAt }));
          });
        }, function(xhr, status, error) {
          Ember.run(function() {
            reject(xhr.responseJSON || xhr.responseText);
          });
        });
      }, reject);
    });
  }
});

# config/environment
ENV['simple-auth'] = {
  authorizer: 'simple-auth-authorizer:oauth2-bearer',
  crossOriginWhitelist: ['*']
};

ENV['simple-auth-oauth2'] = {
  serverTokenEndpoint: ENV.host + '/oauth/token',
  refreshAccessTokens: true
};

ENV['torii'] = {
  providers: {
    'facebook-oauth2': {
      apiKey:      '631252926924840',
      redirectUri: 'http://localhost:4200'
    }, 
    'google-oauth2': {
      apiKey:      '631252926924840',
      redirectUri: 'http://localhost:4200'
    }
  }
};
  • POST /oauth/token: I pass to server the following params: 1. grant_type="assertion" 2. provider 3. assertion="3dPartyToken"

I am not sure if it is the better way for my requirements, for now I am getting the problem that I cannot run open method of torii, anybody know what I am doing wrong? if you have a better solution to this issue would be very appreciated.

error: enter image description here

Community
  • 1
  • 1
Moh
  • 249
  • 3
  • 15
  • Do you want to exchange the third-party token with a token of your custom API? – kunerd Apr 25 '15 at 20:06
  • @kunerd Totally, in the case of third party authentication /oauth/token must receive the next parameters (provider="facebook"|"google", grant_type="assertion", and assertion="3dPartyToken") – Moh Apr 26 '15 at 04:26
  • In this case you should subclass the torii authenticator, override the `authenticate` method and when super resolves make the request to your server to exchange the token. – marcoow Apr 26 '15 at 06:49
  • @marcoow do you mean such as I described in my question? I actually see it the same. It will be really nice if you could explain the flow by an example. – Moh Apr 26 '15 at 09:59

2 Answers2

1

You shouldn't extend the OAuth 2.0 authenticator to authenticate with torii as OAuth 2.0 and torii are very different from an Ember Simple Auth point of view although most of the torii providers connect to OAuth 2.0 backends. Simply use the torii authenticator and pass the torii provider that you want to use as the 2nd argument to Session.authenticate. See this example to get an idea for how that works.

marcoow
  • 4,062
  • 1
  • 14
  • 21
  • @macoow I had actually the same but no request '/oauth/token' was sent to server after facebook authentication via torii. I have now facebook-oauth2 provider and simple-auth-authenticator:torii but not working. should I require torii somewhere? – Moh Apr 25 '15 at 06:33
  • @macoow, I extended the `simple-auth-torii/authenticators/torii` and override the `authenticate` method and called 'this._super(provider, options)' form my new class. But it seems like the super class unable to find the torii object and it gives me a error `Cannot read property 'open' of undefined`. how can I extend the torii to override the authenticate method and how can i get the `torii` instance to my new class to call methods like 'open'? – PIKP Jun 11 '15 at 07:25
0

Currently I'm using a similar approach as described in the question, but I inject torii into my authenticator via an initializer:

export default {
  name: 'custom-torii-oauth2-config',
  before: 'simple-auth',
  after: 'torii',

  initialize: function(container, application) {
    application.inject('authenticator:custom-torii-oauth2', 'torii', 'torii:main');
  }
};

After that it can be used within the authenticator like following:

this.torii.open(...)

I also thought about the solution marcoow mentioned in his comment, but for me it results in to much duplicate code with the oauth2-authenticator. Wouldn't an extension for the torii-authenticator be nice, which is handling exactly this flow?

Edit Important part of custom-torii-oauth2 authenticator.

  fetchOauthData: function(options) {
    var _this = this;
    return new Ember.RSVP.Promise(function(resolve, reject) {
      _this.torii.open(options.provider).then(function(oauthData) {
        Ember.run(function() {
          resolve({
            grant_type: 'authorization_code',
            provider: oauthData.provider,
            code: oauthData.authorizationCode,
          });
        });
      }, function(error) {
        Ember.run(function() {
          reject(error);
        });
      });
    });
  }
kunerd
  • 1,076
  • 10
  • 25
  • I like your solution even I am not sure what would be the best implementation. could you please put some code of custom-torii-oauth2 authenticator?! I did not got how to handle torii open method, torii always seems undefined for me. – Moh Apr 27 '15 at 07:24