SOLVED

Trying to use Teams SSO but with Dynamics CRM API to query a Dataverse Table.

Copper Contributor

Hi, I've followed the steps to integrate the SSO and it's working with Graph and the User.Read Scope.

 

But when I try to Add the scope user_impersonate (78ce3f0f-a1ce-49c2-8cde-64b5c0896db40 from Dynamics, I'm getting an error.

 

It's seems that the method handleMessageExtensionQueryWithSSO always searches the scope on the Graph resource.

 

anyone have tried this?

 

Thanks!

4 Replies

@cdantiags - Could you please provide the repro steps along with CRM integration details, so that we can try out once from our end?

@Prasad_Das-MSFT  Yes, first, thanks for your reply.

1- I've created the Message Extension example from the Teams Toolkit.
2- Once we got the example running, I've added the SSO using this article.

https://github.com/OfficeDev/TeamsFx/wiki/Develop-single-sign-on-experience-in-Teams

3- I've that example running and getting the token for the logged user.

This is a fragment of the code that is working

....

public async handleTeamsMessagingExtensionQuery(context: TurnContext, query: MessagingExtensionQuery): Promise<any> /*MessagingExtensionResponse */ {
return await handleMessageExtensionQueryWithSSO(context, oboAuthConfig, initialLoginEndpoint, ["User.Read"], async (token: MessageExtensionTokenResponse) => {

....

// Init OnBehalfOfUserCredential instance with SSO token
const credential = new OnBehalfOfUserCredential(token.ssoToken, oboAuthConfig);

// Create an instance of the TokenCredentialAuthenticationProvider by passing the tokenCredential instance and options to the constructor
const authProvider = new TokenCredentialAuthenticationProvider(credential, {
scopes: ["User.Read"],
});

// Initialize Graph client instance with authProvider
const graphClient = Client.initWithMiddleware({
authProvider: authProvider,
});

// Call graph api use `graph` instance to get user profile information.
const profile = await graphClient.api("/me").get();

.........



4- I've want to use the logged user information to query Dataverse, for that, I've used postman and got an example working...

https://learn.microsoft.com/en-us/power-apps/developer/data-platform/webapi/use-postman-perform-oper...

5- So, I wanted to merge this... from a Teams app (with sso) use the token and query a Dataverse table...

I've tried with this code....

var t = await credential.getToken([]);
const config = {
headers: { Authorization: `Bearer ${t.token}` },
};
const response = await axios.get(`${webApiUrl}cre5d_saleses?$top=10`, config);

But I'm getting a 401.

NOTE: If I change t.token with the token I'm using in Postman, it works!. So the token is the problem...

6- On mi Azure App Registration I've added the Dynamics CRM Permissions.

{
"resourceAppId": "00000007-0000-0000-c000-000000000000",
"resourceAccess": [
{
"id": "78ce3f0f-a1ce-49c2-8cde-64b5c0896db4",
"type": "Scope"
}
]
},

But the problem continues....

Hope this helps!!! Thanks!

best response confirmed by cdantiags (Copper Contributor)
Solution

@cdantiags - 

The problem you're facing might be due to the scope of the token. The SSO token you're getting from Teams is scoped for the Graph API ("User.Read") and might not have the necessary permissions to access the Dataverse API.

In your Azure App Registration, you've added the Dynamics CRM permissions, which is correct for accessing Dataverse. However, you need to ensure that the token you're using in your Teams app includes these permissions.

Here's how you can modify your code to include the necessary scopes:

public async handleTeamsMessagingExtensionQuery(context: TurnContext, query: MessagingExtensionQuery): Promise<any> /*MessagingExtensionResponse */ {
    return await handleMessageExtensionQueryWithSSO(context, oboAuthConfig, initialLoginEndpoint, ["https://<your_dataverse_url>/.default"], async (token: MessageExtensionTokenResponse) => {
        // your code here
    });
}

In the above code, replace <your_dataverse_url> with your actual Dataverse URL. The /.default scope is a built-in scope for accessing all the permissions defined in an application registration.

 

 

 

Thanks, 

Prasad Das

------------------------------------------------------------------------------------------ 

If the response is helpful, please click "**Mark as Best Response**" and like it. You can share your feedback via Microsoft Teams Developer Feedback link.

Thanks, Using that scope and the token property, NOT the ssoToken it's working.

Thanks!
1 best response

Accepted Solutions
best response confirmed by cdantiags (Copper Contributor)
Solution

@cdantiags - 

The problem you're facing might be due to the scope of the token. The SSO token you're getting from Teams is scoped for the Graph API ("User.Read") and might not have the necessary permissions to access the Dataverse API.

In your Azure App Registration, you've added the Dynamics CRM permissions, which is correct for accessing Dataverse. However, you need to ensure that the token you're using in your Teams app includes these permissions.

Here's how you can modify your code to include the necessary scopes:

public async handleTeamsMessagingExtensionQuery(context: TurnContext, query: MessagingExtensionQuery): Promise<any> /*MessagingExtensionResponse */ {
    return await handleMessageExtensionQueryWithSSO(context, oboAuthConfig, initialLoginEndpoint, ["https://<your_dataverse_url>/.default"], async (token: MessageExtensionTokenResponse) => {
        // your code here
    });
}

In the above code, replace <your_dataverse_url> with your actual Dataverse URL. The /.default scope is a built-in scope for accessing all the permissions defined in an application registration.

 

 

 

Thanks, 

Prasad Das

------------------------------------------------------------------------------------------ 

If the response is helpful, please click "**Mark as Best Response**" and like it. You can share your feedback via Microsoft Teams Developer Feedback link.

View solution in original post