question

MattStrenz-3063 avatar image
0 Votes"
MattStrenz-3063 asked AlexandreQ-7989 answered

Authenticating with msal via browser

I'm looking to allow a UI test to bypass login via a token I'm getting from a REST request to login.microsoft.com. I have the response coming back with a valid token but am unable to populate the browser so my "user" is logged in on page load. I'm currently leveraging Cypress to validate the application and am using the below method to get my token and populate local storage and a cookie.



 Cypress.Commands.add("login", () => { cy.request({ method: "POST", url: `https://login.microsoftonline.com/${Cypress.config( "tenantId" )}/oauth2/token`, form: true, body: { grant_type: "client_credentials", client_id: Cypress.config("clientId"), client_secret: Cypress.config("clientSecret"), resource: Cypress.config("clientId"), }, }).then((response) => { cy.log("RESPONSE: " + JSON.stringify(response.body)) const Token = response.body.access_token Cypress.config("Token", Token) localStorage.setItem(`{ "authority":"https://login.microsoftonline.com/${Cypress.config("tenantId")}/", "clientId": "${Cypress.config("clientId")}"}`, `{"accessToken":"${Token}","idToken":"${Token}", "expiresIn": "${response.body.expires_on}"}`) localStorage.setItem(`msal.${Cypress.config("clientId")}.idtoken`,`${Token}`) cy.setCookie(`msal.${Cypress.config("clientId")}.idtoken`,`${Token}`); }); });


Does anybody know what the browser needs to consider a user authenticated?



azure-active-directory
· 3
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

Hi, are you following any specific documentation for this? I would like to replicate it and let you know what I find!

0 Votes 0 ·

Hi, @MattStrenz-3063 are you still encountering this issue?

0 Votes 0 ·

Hi, are there any updates with this case? If not, please select the appropriate response as "Answered." Otherwise please let us know how we can assist you.

0 Votes 0 ·
MichaelMcMullin-9560 avatar image
1 Vote"
MichaelMcMullin-9560 answered SumanthReddyAvulaACCENTURE-2409 commented

I've been having the same issue. There seems to be a lot of samples for working with ADAL (example), but after a lot of trial and error, I've got close with MSAL:

const tenant = 'https://login.microsoftonline.com/{my_tenant_id}/';
const tenantUrl = `${tenant}oauth2/token`;
const clientId = '{my_app_id}';
const clientSecret = '{my_secret}';
const azureResource = 'api://{my_app_id}';
    
export function login() {
    cy.request({
        method: 'POST',
        url: tenantUrl,
        form: true,
        body: {
            grant_type: 'client_credentials',
            client_id: clientId,
            client_secret: clientSecret,
            resource: azureResource
        }
    }).then(response => {
    const Token = response.body.access_token;

    window.localStorage.setItem(`msal.idtoken`, Token);
    window.localStorage.setItem(`msal.client.info`, `{my_hard_coded_value}`);
});
Cypress.Commands.add('login', login);


Unfortunately I'm still unfamilar with Azure AD and Cypress, but this seems to get Cypress past the login stage.

The values for my_tenant_id, my_app_id and my_secret are readily available in the Azure Portal.

The setting I'm unsure of is msal.client. info. I noticed that in a normal browser session, local storage has quite a few msal settings, but only msal.idtoken and msal.client. info are strictly required. The idtoken value is returned in response.body.access_token, so it's easily added. However, msal.client. info seems to return the same value each time. I'm not sure if that's always the case, but for now, I've simply added the hard-coded value from a browser session into the above code. Seems to work for me, but I'd like to understand it a little better.







· 1
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

Hi @MichaelMcMullin-9560 , This used to work for me when using MSAL , but now we moved to MSAL V2 and the above solution is not working . Can i get any help on solving the issue with MSALV2?

0 Votes 0 ·
KimberlyLy-0520 avatar image
0 Votes"
KimberlyLy-0520 answered

Hi @MichaelMcMullin-9560 ,

I want to thank you for all of the groundwork you've done to figure out which variables to set when working with MSAL! I think I can help with figuring out where clientInfo comes from. It looks like it is generated from the clientId, which explains why it is always the same value. See source here: https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/70b87bcd27bfe67789c92b9bc046b45733f490ed/lib/msal-core/src/ClientInfo.ts

I was able to use your code and just added import * as MSAL from "@azure/msal-browser" and window.localStorage.setItem(msal.client.info``, MSAL.clientInfo);`

Worked like a charm for me!


5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

VaibhavSawant-2337 avatar image
0 Votes"
VaibhavSawant-2337 answered VaibhavSawant-2337 edited

@KimberlyLy-0520 While setting msal.client.info in local storage, getting an error "Invalid base64 string" and it's not login user to web application. Tried to add MSAL.clientInfo by importing @azure/msal-browser. But, no luck. Can you please guide, what's going wrong here.

 import * as MSAL from "@azure/msal-browser"
    
 Cypress.Commands.add("login", () => {
     cy.request({
       method: "POST",
       url: `https://login.microsoftonline.com/${Cypress.config("tenantId")}/oauth2/token`,
       form: true,
       body: {
         grant_type: "client_credentials",
         client_id: Cypress.config("clientId"),
         client_secret: Cypress.config("clientSecret"),
         resource: Cypress.config("resource")
       },
     }).then(response => {
       const MSALToken = response.body.access_token;
       const expiresOn = response.body.expires_on;
       console.log("Body: " + JSON.stringify(response.body));
       window.localStorage.setItem("msal.token.keys", `${Cypress.config("clientId")}|`);
       window.localStorage.setItem(`msal.access.token.key${Cypress.config("clientId")}`, MSALToken);
       window.localStorage.setItem(`msal.expiration.key${Cypress.config("clientId")}`, expiresOn);
       window.localStorage.setItem("msal.idtoken", MSALToken);
       window.localStorage.setItem(`msal.client.info`, MSAL.clientInfo);
     });
   });

Response Received:

 {
   "token_type": "Bearer",
   "expires_in": "3599",
   "ext_expires_in": "3599",
   "expires_on": "1622095375",
   "not_before": "1622091475",
   "resource": "00000002-0000-0000-c000-000000000000",
   "access_token": "eyJ0eXAiOiJKV1QiLCJh....BEFg"
 }

Getting Error "Invalid base64 string" while setting

 window.localStorage.setItem(`msal.client.info`, MSAL.clientInfo);
    
    
 Unhandled Promise rejection: The client info could not be parsed/decoded correctly. Please review the trace to determine the root cause. Failed with error: Error: Invalid base64 string ; Zone: <root> ; Task: Promise.then ; Value: ClientAuthError: The client info could not be parsed/decoded correctly. Please review the trace to determine the root cause. Failed with error: Error: Invalid base64 string
     at e [as constructor] (VM19 main-es2015.5d1f7b11d6a7d9a05ff5.js:1)
     at new e (VM19 main-es2015.5d1f7b11d6a7d9a05ff5.js:1)
     at Function.e.createClientInfoDecodingError (VM19 main-es2015.5d1f7b11d6a7d9a05ff5.js:1)
     at new t (VM19 main-es2015.5d1f7b11d6a7d9a05ff5.js:1)
     at t.getAccount (VM19 main-es2015.5d1f7b11d6a7d9a05ff5.js:1)
     at t.checkAccount (VM19 main-es2015.5d1f7b11d6a7d9a05ff5.js:1)
     at new t (VM19 main-es2015.5d1f7b11d6a7d9a05ff5.js:1)
     at Object.FG+x.t.ɵfac [as factory] (VM19 main-es2015.5d1f7b11d6a7d9a05ff5.js:1)
     at Nr.hydrate (VM19 main-es2015.5d1f7b11d6a7d9a05ff5.js:1)
     at Nr.get (VM19 main-es2015.5d1f7b11d6a7d9a05ff5.js:1) ClientAuthError: The client info could not be parsed/decoded correctly. Please review the trace to determine the root cause. Failed with error: Error: Invalid base64 string
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

AlexandreQ-7989 avatar image
0 Votes"
AlexandreQ-7989 answered

Hello,

Does anyone have a solution for this issue ?

Thank you in advance.

5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.