cancel
Showing results for 
Search instead for 
Did you mean: 
Reply
HemanthN
Helper III
Helper III

How to configure SSO in PVA?

Hi,

 

I am trying to connect SSO in PVA on the Sharepoint website. I see the below error on the chrome console.

p1.png

I see a syntax error from the below line of code. I am following the SSO configuration by the doc provided below: "https://docs.microsoft.com/en-us/power-virtual-agents/configure-sso"

 

The below code is from the doc.

 

 var userID = clientApplication.account?.accountIdentifier != null ? ("Your-customized-prefix-max-20-characters" + clientApplication.account.accountIdentifier).substr(0,64) : (Math.random().toString() + Date.now().toString().substr(0,64)

 

I had posted by query before as well but no luck.. https://powerusers.microsoft.com/t5/General/How-to-configure-Single-Sign-On-in-PVA-with-Sharepoint-a...

 

Can anyone please help me out here?

 

Regards,

Hemanth

34 REPLIES 34

Hey HermanthN, per our conversation here's what we did with the relevant changes.  Apologies for the delay.

 

@using Microsoft.AspNetCore.Http
@using Microsoft.Extensions.Configuration
@inject IHttpContextAccessor HttpContextAssessor
@inject IConfiguration Configuration

@{
    string userId = HttpContextAssessor.HttpContext.User.Claims.FirstOrDefault(user => user.Type == "preferred_username").Value;
    string redirectUri = Configuration.GetValue<string>("ConnectionStrings:redirectUri");
    string clientId = Configuration.GetValue<string>("AzureAd:ClientId");
    string botId = Configuration.GetValue<string>("ConnectionStrings:BotId");
    string authority = $"{Configuration.GetValue<string>("AzureAd:Instance")}{Configuration.GetValue<string>("AzureAd:TenantId")}";
}

 

This gets you the user name through httpcontextassessor that I mentioned earlier.  From here you can pass this as a login hint:

 

   function exchangeTokenAsync(resourceUri) {
        let requestObj = {
            scopes: [resourceUri, 'openid', 'profile'],
            loginHint: '@userId'
        };
        return clientApplication.acquireTokenSilent(requestObj)
            .then(function (tokenResponse) {
                return tokenResponse.accessToken;
            })
            .catch(function (error) {
                console.log(error);
            });
     }

 

Note the redirect URI, that's also relevant and passed in here:

 

var clientApplication;
    (function () {
        var msalConfig = {
            auth: {
                // Client/tenant ID from CosineADOSupport app registration
                clientId: '@clientId',
                authority: '@authority',
                redirectUri: '@redirectUri'
            },
            cache: {
                cacheLocation: 'localStorage',
                storeAuthStateInCookie: false
            }
        };
        if (!clientApplication) {
            clientApplication = new Msal.UserAgentApplication(msalConfig);
        }
    }());

 

That's pretty much the difference between our code.  Let me know if you have any other questions.

Hi @PaulCullivan 

Thank you for responding back. I have done the above code changes, I am passing the user.userName as a loginHint. Please find the below code.

function exchangeTokenAsync(resourceUri) 
      {
        let user = clientApplication.getAccount();

        console.log("user.userName is: " + user.userName); // User Email ID
        document.getElementById("userName").innerHTML = "Welcome " + user.name; // User Name

        let requestObj = {
          scopes: [resourceUri, "openid", "profile"],
          loginHint: user.userName,
        };

        return clientApplication.acquireTokenSilent(requestObj).then(function (tokenResponse) {
            return tokenResponse.accessToken;
          }).catch(function (error) 
            {
              console.log("Error from exchangeTokenAsync function" + error);
            });
      }

 

Below is the MSAL code.

 

var clientApplication;

      (function () {
        var msalConfig = {
          auth:
          {
            clientId:'<Canvas(SSO) App Client ID> ',
            authority:'https://login.microsoftonline.com//<Directory ID>',
            redirectUri:'<My SharePoint website url were the bot is deployed>'
          },
          cache: 
          {
            cacheLocation: "localStorage",
            storeAuthStateInCookie: false,
          },
        };
        if (!clientApplication) 
        {
          clientApplication = new Msal.UserAgentApplication(msalConfig);
        }
      })();

 

Everytime my code enters into the if(id === "retry") block of code.

 

Errors from the logs:

id: retry - bot was not able to handle the invoke, so display the oauthCard

Error from exchangeTokenAsync functionClientAuthError: Token calls are blocked in hidden iframes

Failed to load resource: the server responded with a status of 502 ()

 

But I see my userName being fetched by the MSAL.

code.jpg

 

Below is the exchangeTokenAsync function

 

code2.jpg

I am not sure why this always fails and displays the login card.

ZakiVNGS
New Member

Hi,

 

This thread has helped me progress through various errors so thanks everyone for that.

I believe I'm real close but am getting a 403 error when the direct line API is called.

 I have followed the PVA SSO guide and gone through all the steps - Configure single sign-on - Power Virtual Agents | Microsoft Docs.

Also, I'm somewhat confused by contradicting instructions.

Please note that the two steps (in italics from the SSO article) below seem to contradict each other as to which app the expose an API scope need to be added to. Step 1 says add it to the initial app reg. However, in the following section step 4, it refers to the canvas app

 

Which one should the scope be configured in? - Initial app reg or the canvas app?

 

Define a custom scope for your bot

  1. Open the app registration that you created when you configured authentication.

Step 4 refers to the Canvas app reg - Enter the full scope URI from the Expose an API blade for the canvas app registration in the Token exchange URL field. The URI will be in the format of api://1234-4567/scope.name.

 

ZakiVNGS_0-1615120969702.png

 

Can someone please help? @BoLi @PaulCullivan @HemanthN 

Thanks in advance.

BoLi
PVA
PVA

Thanks, the document is indeed very confused and not clear. I will ask someone to update the doc. Thank you for pointing it out

Thank you @BoLi...appreciate it.

 

There are also several errors within the scripts provided within that article. I used this thread and one other to solve several of those.

 

I was wondering if you can help with the 403 error that I reported above somehow.

I think it just needs someone who has done this before to possibly advise as I'm confident that I have followed the article closely.

 

I'd be more than happy to provide my findings and contribute to improving the article by providing the correct working script etc.

Is there any chance we can connect virtually over a call? 

 

Cheers.

Helpful resources

Announcements
March Update

Welcome to the User Group Private Preview

Check out new user group experience and if you are a leader please create your group

V3_PVA CAmpaign Carousel.png

Community Challenge - Giveaways!

Participate in the Power Virtual Agents Community Challenge

Carousel 2021 Release Wave 2 Plan 768x460.jpg

2021 Release Wave 2 Plan

Power Platform release plan for the 2021 release wave 2 describes all new features releasing from October 2021 through March 2022.

Users online (1,389)