mardi 11 février 2020

Azure AD Auth Ember JS v3.15

I'm a noob with JS in general, but I've put together a simple app for work that embeds a Tableau dashboard using Ember.JS. I'm starting to think Ember just isn't right, but I have zero familiarity with anything else.

I have an index route with a short message to users, and a login with Microsoft button. I'd like to use Azure AD only to authenticate business users when they click the button. The return URL would be the embedded route, and the application route just has some header and footer info.

I tried picking apart the sample [https://docs.microsoft.com/en-us/azure/active-directory-b2c/tutorial-single-page-app?tabs=applications], and I'm not getting anywhere. I don't even know what errors would be meaningful, since I'm not even sure this can work.

I've placed this in my index.html file ..

<script type="text/javascript" src="https://alcdn.msauth.net/lib/1.2.1/js/msal.js" integrity="sha384-9TV1245fz+BaI+VvCjMYL0YDMElLBwNS84v3mY57pXNOt6xcUYch2QLImaTahcOP" crossorigin="anonymous"></script>
<script type="text/javascript">
    if(typeof Msal === 'undefined')document.write(unescape("%3Cscript src='https://alcdn.msftauth.net/lib/1.2.1/js/msal.js' type='text/javascript' integrity='sha384-9TV1245fz+BaI+VvCjMYL0YDMElLBwNS84v3mY57pXNOt6xcUYch2QLImaTahcOP' crossorigin='anonymous'%3E%3C/script%3E"));
</script>
<script src="https://code.jquery.com/jquery-3.2.1.min.js" class="pre"></script>

I have the buttons in my index.hbs file ..

<button onclick="signIn()" type="submit" id="ms-login" />
<button type="button" class="hide" onclick="callApi()">Call Web API</button>

Now I'm trying to figure out what to do with this ..

<pre class="response"></pre>

<script class="pre">

  // The current application coordinates were pre-registered in a B2C tenant.
  var appConfig = {
    b2cScopes: [?],
    webApi: "?"
  };

</script>

<script>
  "use strict";

  // configuration to initialize msal
  const msalConfig = {
      auth: {
          clientId: "{Application (client) ID}", //This is your client ID
          authority: "?", //This is your tenant info
          validateAuthority: false
      },
      cache: {
          cacheLocation: "localStorage",
          storeAuthStateInCookie: true
      }
  };

  // instantiate MSAL
  const myMSALObj = new Msal.UserAgentApplication(msalConfig);

  // request to signin - returns an idToken
  const loginRequest = {
      scopes: appConfig.b2cScopes
  };

  // request to acquire a token for resource access
  const tokenRequest = {
      scopes: appConfig.b2cScopes
  };

  // signin and acquire a token silently with POPUP flow. Fall back in case of failure with silent acquisition to popup
  function signIn() {
      myMSALObj.loginPopup(loginRequest).then(function (loginResponse) {
          getToken(tokenRequest).then(updateUI);
      }).catch(function (error) {
          logMessage(error);
      });
  }

  //acquire a token silently
  function getToken(tokenRequest) {
      return myMSALObj.acquireTokenSilent(tokenRequest).catch(function(error) {
        console.log("aquire token popup");
        // fallback to interaction when silent call fails
        return myMSALObj.acquireTokenPopup(tokenRequest).then(function (tokenResponse) {
        }).catch(function(error){
          logMessage("Failed token acquisition", error);
      });
    });
  }

  // updates the UI post login/token acqusition
  function updateUI() {
    const userName = myMSALObj.getAccount().name;
    console.log(myMSALObj.getAccount());
    logMessage("User '" + userName + "' logged-in");

    // add the logout button
    const authButton = document.getElementById('auth');
    authButton.innerHTML = 'logout';
    authButton.setAttribute('onclick', 'logout();');

    // greet the user - specifying login
    const label = document.getElementById('label');
    label.innerText = "Hello " + userName;

    // add the callWebApi button
    const callWebApiButton = document.getElementById('callApiButton');
    callWebApiButton.setAttribute('class', 'visible');
  }

  // calls the resource API with the token
  function callApi() {
    getToken(tokenRequest).then(function(tokenResponse) {
      callApiWithAccessToken(tokenResponse.accessToken);
    });
  }

  // helper function to access the resource with the token
  function callApiWithAccessToken(accessToken) {
    // Call the Web API with the AccessToken
    $.ajax({
      type: "GET",
      url: appConfig.webApi,
      headers: {
        'Authorization': 'Bearer ' + accessToken,
      },
    }).done(function (data) {
      logMessage("Web APi returned:\n" + JSON.stringify(data));
    })
      .fail(function (jqXHR, textStatus) {
        logMessage("Error calling the Web api:\n" + textStatus);
      })
  }

  // signout the user
  function logout() {
    // Removes all sessions, need to call AAD endpoint to do full logout
    myMSALObj.logout();
  }

  // debug helper
  function logMessage(s) {
    document.body.querySelector('.response').appendChild(document.createTextNode('\n' + s));
  }

</script>

Then, if this is possible in Ember, I'm unsure what to put for b2cScopes and webApi here ..

<script class="pre">

  // The current application coordinates were pre-registered in a B2C tenant.
  var appConfig = {
    b2cScopes: [?],
    webApi: "?"
  };

</script>

Also, what goes in the Authority here? The example has a tenant url, but once I created the App Registration, I was only provided a Directory (tenant) ID GUID.

const msalConfig = {
    auth: {
        clientId: "{Application (client) ID}", //This is your client ID
        authority: "?", //This is your tenant info
        validateAuthority: false
    },
    cache: {
        cacheLocation: "localStorage",
        storeAuthStateInCookie: true
    }
};

Thank you for looking at this, and I'm sorry if I haven't provided enough info to solve. Python and SQL are easy peezy lol, but JS won't stop kicking me while I'm down!




Aucun commentaire:

Enregistrer un commentaire