4
votes

Firstly, I am not a seasoned JS Developer, so please excuse obvious mistakes that I could have made.

I am trying to implement a custom Authenticator for authenticating a user with Keycloak using the OAuth2 Password Grant which requires the client_id be passed as part of the request body.

import OAuth2PasswordGrant from 'ember-simple-auth/authenticators/oauth2-password-grant';
export default OAuth2PasswordGrant.extend({   
  serverTokenEndpoint: 'http://localhost:8080/something/token', 
  makeRequest(url, data, headers = {}) {
    data.client_id = 'my-app';
    return this._super(url, data, headers);
  }
});

I have a controller that uses this Authenticator by calling this action:

actions: {
  authenticate() {
    let {username, password} = this.getProperties('username', 'password');
    this.get('session').authenticate('authenticator:oauth2', username, password).then(() => {
      // Do something
    }).catch((response) => {
      // Show error
    });
  }
}

This causes Firefox to hang and gives me an unresponsive script message.

If I remove the return from the makeRequest() method, I can see from the browser debugger that the call to Keycloak actually returns correctly with the object that contains my token etc. However ember inspector shows some errors related to unresolved promises. But I guess that's because I'm no longer returning the promise.

What am I doing wrong here?

How can I fix the unresponsive script issue?

Is there another way for me to achieve my goal?

Edit 1: This is when I remove the return

Here is the actual object that is returned:

{
"access_token":"eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJTRUNSd09fMlZWdGhxUVBUWnFxNHlqX0tKekxnOElSTjBrQkx5UTlacklrIn0.eyJqdGkiOiI1NDgzZDdkMi0zMDdhLTQyZjItYWUxZC0xYTZjMTZjOTM2ZjAiLCJleHAiOjE1MDgzMzE5MjAsIm5iZiI6MCwiaWF0IjoxNTA4MzMxNjIwLCJpc3MiOiJodHRwOi8vbG9jYWxob3N0OjgwODAvYXV0aC9yZWFsbXMvc2Z4LWl0cmFuc2Zlci13ZWItYWdlbnQiLCJhdWQiOiJhZ2VudC13ZWItYXBwIiwic3ViIjoiMzZiMWY4OWMtNGYwMC00OTU1LWE0YzMtZWQ0NzZmZDU2OGM3IiwidHlwIjoiQmVhcmVyIiwiYXpwIjoiYWdlbnQtd2ViLWFwcCIsImF1dGhfdGltZSI6MCwic2Vzc2lvbl9zdGF0ZSI6IjQwODMxZWFhLTRmMmEtNDk2ZS05NDVkLTdiZWIxN2U0NmU0NCIsImFjciI6IjEiLCJhbGxvd2VkLW9yaWdpbnMiOlsiaHR0cDovL2xvY2FsaG9zdDo0MjAwIl0sInJlYWxtX2FjY2VzcyI6eyJyb2xlcyI6WyJ1bWFfYXV0aG9yaXphdGlvbiIsImJhY2stb2ZmaWNlLWFnZW50Il19LCJyZXNvdXJjZV9hY2Nlc3MiOnsiYWNjb3VudCI6eyJyb2xlcyI6WyJtYW5hZ2UtYWNjb3VudCIsIm1hbmFnZS1hY2NvdW50LWxpbmtzIiwidmlldy1wcm9maWxlIl19fSwibmFtZSI6IlVtYXIgS2hvbHZhZGlhIiwicHJlZmVycmVkX3VzZXJuYW1lIjoidW1hciIsImdpdmVuX25hbWUiOiJVbWFyIiwiZmFtaWx5X25hbWUiOiJLaG9sdmFkaWEiLCJlbWFpbCI6InVtYXJAYWlydmFudGFnZS5jby56YSJ9.eUJFklRiRjQPOC1rQLcqrljsSWmGXCpNNKqLJGAcvbnbwx8X0T1iqrmpFdyMN3EKRrIfTZyYRfcTEbpcBEjZcZtgDY9V0Ntvt4pvpUx_8Ey6I8xZQolHVwferjM30puLqG8MImADUimNrj3ghbJbAaCOJktIKgLnTIhDbkNb-8lzgbyq-rEP6lYAWjQ2OuOZnc8NQQ9CJiR9M1SB79SEmY2iQW9E_J8xo8BgZQ0GUBrhaWPo-Kn4RnlEcRNzVnlLHQKi5FM7Zpov3SMQUbAeLat38V41y09ap2XVCy7MfL_7-TrSlMx0TLrhWqPgA5aaXbmsT9_vKOoXNZoJ9bWCuA",
"expires_in":300,
"refresh_expires_in":1800,
"refresh_token":"eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJTRUNSd09fMlZWdGhxUVBUWnFxNHlqX0tKekxnOElSTjBrQkx5UTlacklrIn0.eyJqdGkiOiIxNTUwNDIyZS02OThkLTQ5N2ItODZmYi00YmY5MTFlMTcwYzYiLCJleHAiOjE1MDgzMzM0MjAsIm5iZiI6MCwiaWF0IjoxNTA4MzMxNjIwLCJpc3MiOiJodHRwOi8vbG9jYWxob3N0OjgwODAvYXV0aC9yZWFsbXMvc2Z4LWl0cmFuc2Zlci13ZWItYWdlbnQiLCJhdWQiOiJhZ2VudC13ZWItYXBwIiwic3ViIjoiMzZiMWY4OWMtNGYwMC00OTU1LWE0YzMtZWQ0NzZmZDU2OGM3IiwidHlwIjoiUmVmcmVzaCIsImF6cCI6ImFnZW50LXdlYi1hcHAiLCJhdXRoX3RpbWUiOjAsInNlc3Npb25fc3RhdGUiOiI0MDgzMWVhYS00ZjJhLTQ5NmUtOTQ1ZC03YmViMTdlNDZlNDQiLCJyZWFsbV9hY2Nlc3MiOnsicm9sZXMiOlsidW1hX2F1dGhvcml6YXRpb24iLCJiYWNrLW9mZmljZS1hZ2VudCJdfSwicmVzb3VyY2VfYWNjZXNzIjp7ImFjY291bnQiOnsicm9sZXMiOlsibWFuYWdlLWFjY291bnQiLCJtYW5hZ2UtYWNjb3VudC1saW5rcyIsInZpZXctcHJvZmlsZSJdfX19.XgYSZWwfaHeY1yZZuwnQ5bj-0IHP4UEmiPTqaeCE1KVyjl3kZz3HJVisndtcKPr05kalS-M_NqU0TaYvbcZ_zesJRIga5sz4gGRqObUmUCUJoQ_iWoOhbM2SutiVnlfgJDACvOxegIcSvakZTgQsEcSweio_0kMFqi-2DYzFp6Rl0TpQ8vALLkc7rEOonUGyt7S4qQzkT-xB1_ZDlSVfm6mC-QKYNZhtqBT18P7MKxBhEgwrJtCytA_4ft7qNAbgvZ3kUohcbhzxGvtHej5RKHNI2wTzwK3IWHbkLWNndxSk_Lzj2-lCx380VpTkVpiDJfq5umjskOmI13dyPF7paA",
"token_type":"bearer",
"not-before-policy":0,
"session_state":"40831eaa-4f2a-496e-945d-7beb17e46e44"
}

This is what ember inspector (Promises) shows:

enter image description here

Here is the stacktrace from the Promise:

Ember Inspector ($E):  authenticate/<@http://localhost:4200/assets/vendor.js:77927:9
initializePromise@http://localhost:4200/assets/vendor.js:63591:7
Promise@http://localhost:4200/assets/vendor.js:64067:35
authenticate@http://localhost:4200/assets/vendor.js:77919:14
authenticate@http://localhost:4200/assets/vendor.js:78528:14
authenticate@http://localhost:4200/assets/vendor.js:79420:14
authenticate@http://localhost:4200/assets/sfx-itransfer-web-agent.js:855:9
join@http://localhost:4200/assets/vendor.js:20249:24
run$1.join@http://localhost:4200/assets/vendor.js:37657:12
makeClosureAction/</<@http://localhost:4200/assets/vendor.js:29073:16
exports.flaggedInstrument@http://localhost:4200/assets/vendor.js:37087:14
makeClosureAction/<@http://localhost:4200/assets/vendor.js:29072:15
submit/<@http://localhost:4200/assets/vendor.js:70453:20
tryCatch@http://localhost:4200/assets/vendor.js:63549:14
invokeCallback@http://localhost:4200/assets/vendor.js:63562:15
publish@http://localhost:4200/assets/vendor.js:63532:9
@http://localhost:4200/assets/vendor.js:54458:16
invoke@http://localhost:4200/assets/vendor.js:19948:17
flush@http://localhost:4200/assets/vendor.js:19827:25
flush@http://localhost:4200/assets/vendor.js:20019:25
end@http://localhost:4200/assets/vendor.js:20128:26
run@http://localhost:4200/assets/vendor.js:20212:21
join@http://localhost:4200/assets/vendor.js:20219:24
run$1.join@http://localhost:4200/assets/vendor.js:37657:12
handleEvent/<@http://localhost:4200/assets/vendor.js:58233:18
exports.flaggedInstrument@http://localhost:4200/assets/vendor.js:37087:14
handleEvent@http://localhost:4200/assets/vendor.js:58232:17
_Mixin$create.handleEvent@http://localhost:4200/assets/vendor.js:57385:12
_bubbleEvent@http://localhost:4200/assets/vendor.js:57685:14
setupHandler/<@http://localhost:4200/assets/vendor.js:57619:20
dispatch@http://localhost:4200/assets/vendor.js:5546:16
add/elemData.handle@http://localhost:4200/assets/vendor.js:5355:6
1
I don't see a bug in the code you provided. You may need to post the error message output. The fact that Firefox is hanging is strange, there must be an infinite loop or something similar occurring - promises by themselves don't cause this.AlexMA
It is quite odd. I have added some more debugging information to the questionKernelKoder
why would you not set clientId like serverTokenEndpoint is seted?user1156168
clientId is not an attribute on OAuth2PasswordGrant as serverTokenEndpoint is.KernelKoder

1 Answers

1
votes

Actually you solution looks like right.

I guess you have a problem in server response or mismatch request methods GET/POST. To solve this try to debug promise inside makeRequest.

    return new RSVP.Promise((resolve, reject) => {
  fetch(url, options).then((response) => {
    response.text().then((text) => { //<-- here debug text 
      let json = text ? JSON.parse(text) : {};
      if (!response.ok) { //<-- and here debug response 
        response.responseJSON = json;
        reject(response);
      } else {
        resolve(json);
      }
    });
  }).catch(reject);

So if problem will here, just rewrite whole method of makeRequest and add you own promise with custom fetch.

Another way is to write custom Authenticator, overriding authenticate, restore and (optionally) invalidate methods as wrote in documentation: https://github.com/simplabs/ember-simple-auth#implementing-a-custom-authenticator