SharePoint / sp-dev-docs

SharePoint & Viva Connections Developer Documentation
https://docs.microsoft.com/en-us/sharepoint/dev/
Creative Commons Attribution 4.0 International
1.23k stars 992 forks source link

SPFX deployed as Personal Teams Tab token error #7499

Closed Macro21 closed 2 years ago

Macro21 commented 2 years ago

Target SharePoint environment

other (enter in the "Additional environment details" area below)

What SharePoint development model, framework, SDK or API is this about?

💥 SharePoint Framework

Developer environment

Windows

What browser(s) / client(s) have you tested

Additional environment details

Describe the bug / error

I have created a webpart and deployed it as an MS Teams application (personal tab). It works in Teams Web and mobile, but not in Teams Desktop. The problem is in these lines:

const prov = await this.context.aadTokenProviderFactory.getTokenProvider(); const token = await prov.getToken("https://xxxxxxx.onmicrosoft.com", false);

...and never get token or error.

In Teams Web: image

In Teams Desktop:

image

In SharePoint: Works.

I use an Azure Function with AAD Identity Provider:

image

image

I follow this post for Azure Function Configuration.

https://www.eliostruyf.com/securing-azure-functions-existing-azure-ad-app/

My Teams Manifest:

{ "$schema": "https://developer.microsoft.com/en-us/json-schemas/teams/v1.11/MicrosoftTeams.schema.json", "manifestVersion": "1.11", "packageName": "com.microsoft.teams.servicesTab", "id": "a97f9d9d-bcb3-4247-afa8-cfe97438e926", "version": "1.0.27", "developer": { "name": "Client S. Coop", "websiteUrl": "https://products.office.com/en-us/sharepoint/collaboration", "privacyUrl": "https://privacy.microsoft.com/en-us/privacystatement", "termsOfUseUrl": "https://www.microsoft.com/en-us/servicesagreement" }, "name": { "short": "TeamsTab", "full": "Servicios de Client" }, "description": { "short": "Acceso a los diferentes servicios ofrecidos por Client.", "full": "En esta aplicación podrás conocer y acceder a todos los servicios que dispones como parte de Client Group. Podrás filtrar por los diferentes campos por los que están etiquetados." }, "icons": { "outline": "outline.png", "color": "color.png" }, "accentColor": "#004578", "staticTabs": [ { "entityId": "a97f9d9d-bcb3-4247-afa8-cfe97438e926", "name": "Mis documentos", "contentUrl": "https://{teamSiteDomain}/_layouts/15/TeamsLogon.aspx?SPFX=true&dest=/_layouts/15/teamshostedapp.aspx%3Fteams%26personal%26componentId=a97f9d9d-bcb3-4247-afa8-cfe97438e926%26forceLocale={locale}&inTeamsSSO=true", "scopes": [ "personal" ] } ], "permissions": [ "identity", "messageTeamMembers" ], "validDomains": [ ".login.microsoftonline.com", ".sharepoint.com", "*.sharepoint-df.com", "spoppe-a.akamaihd.net", "spoprod-a.akamaihd.net", "resourceseng.blob.core.windows.net", "msft.spoppe.com" ], "webApplicationInfo": { "resource": "https://{teamSiteDomain}", "id": "00000003-0000-0ff1-ce00-000000000000" }, "localizationInfo": { "defaultLanguageTag": "es", "additionalLanguages": [ { "languageTag": "eu", "file": "eu.json" } ] } }

Steps to reproduce

  1. Create one Azure Function
  2. Create Azure AD App Register
  3. Config authenticate for Azure Function with the Azure AD App register
  4. Try get access token in SPO
  5. Deploy the webpart as Personal Tab App

Pd: I tested in other tenant and it works in Teams Desktop and Teams Mobile.

Expected behavior

Get Azure Function access token in MS Teams Desktop from SPFx Webpart deployed as Teams personal tab.

ghost commented 2 years ago

Thank you for reporting this issue. We will be triaging your incoming issue as soon as possible.

lucabandMSFT commented 2 years ago

Hey @Macro21 , is there a reason why you had to craft the manifest manually instead of using the "sync to Teams" function in SPO app Catalog? just for testing purposes (to be sure the Teams manifest is crafted properly), could you use the "sync to Teams" function and see if that solves the issue?

Macro21 commented 2 years ago

Hey @Macro21 , is there a reason why you had to craft the manifest manually instead of using the "sync to Teams" function in SPO app Catalog? just for testing purposes (to be sure the Teams manifest is crafted properly), could you use the "sync to Teams" function and see if that solves the issue?

Hi! Thank you for help! I've tried it but it doesn't work in Teams Desktop. In web and mobile, yes.

The same code but changing the addresses works in another tenant. (With "sync to Teams" and manually)

lucabandMSFT commented 2 years ago

@Macro21 , thanks. when you say "hanging the addresses", what does it mean? Also, before "syncing to Teams" in the tenant that doesn't work, did you ensure you removed the old app from the Teams App Catalog?

Macro21 commented 2 years ago

@Macro21 , thanks. when you say "hanging the addresses", what does it mean? Also, before "syncing to Teams" in the tenant that doesn't work, did you ensure you removed the old app from the Teams App Catalog?

Sorry for bad explication.

In the client tenant: This works in Teams Web and Teams Mobile.

  1. Azure Function:

image

  1. AAD App:

image

  1. SPFx:

image

In the development tenant: (My tenant):

  1. Create new Azure Function
  2. Create new AAD App
  3. Change the Azure Function link and resource that point to the development Azure Function and resource in the SPFx project
  4. Deploy the solution in development app catalog, sync with Teams and all works in all devices.
juliemturner commented 2 years ago

I can confirm (although with a simpler test case) that the Personal App AND Teams Tab in the Teams Desktop Client is not authenticating. This is an issue that has been known for a long time. The workaround is (on the desktop client) visit a SharePoint page pinned as a Personal App (like Viva Connections Home) or a pinned SharePoint page on a tab. That page will load, get a token and then if you navigate back to the Personal App or Tab the SPFx solution it will load.

A user submitted this as an issue (along with other things). We have now solved all their other issues.

Personal App -> SPFx web part image

Teams Tab -> SPFx web part image

lucabandMSFT commented 2 years ago

hey @juliemturner , I want to be sure I understand the scenario you are describing here as this should no longer be the case considering all the recent updates we introduced in this code path:

at that point it will work in Teams web but not in Teams Desktop.. is that correct?

thanks

juliemturner commented 2 years ago

Not exactly no. You can see the source code (plus pre-built sppkg file) for the entire solution here: https://github.com/pnp/spfx-reference-scenarios/tree/main/samples/ace-teams-covid/covid-spfx/teams

✔ create a Teams personal app using SPFx (supportedhost == "TeamsPersonalApp") ❌ code attempts to call SharePoint and Graph endpoints, not custom secured endpoint with AADHTTPClient ❌ the solution is deployed into the SPO App Catalog but this is a custom manifest because it has custom icons, but is deployed using Sync to Teams -- which succeeds ✔ app is install in Teams

And then yes, at that point it will work immediately with Teams web but not in Desktop UNLESS you visit a SharePoint page which then authenticates you and everything starts working.

The user I mentioned was making a custom manifest, not sync to teams because they wanted to change the site collection that the app shows up in, so they followed this guidance: https://github.com/pnp/spfx-reference-scenarios/tree/main/samples/ace-teams-covid#custom-manifest

lucabandMSFT commented 2 years ago

so.. that seems to fail by design? :-)

by looking at the manifest you provided in the link above I see you are missing this key part:

without it, we revert back to the old "you need to be auth. in SPO in order to continue" path. By simply adding the text above in the Teams manifest should fix the issue by using the new auth code path.

"webApplicationInfo": { "resource": "https://{teamSiteDomain}", "id": "00000003-0000-0ff1-ce00-000000000000" }

Can you please try?

juliemturner commented 2 years ago

Those additional values in the manifest don't appear to make any difference.

Still the same problem.

lucabandMSFT commented 2 years ago

did you remove the app from Teams and add it back? sorry.. I'm asking this because I know that Teams is pretty ... "opinionated" :-) on the way it handles manifest caching. I would:

and then see if that works

juliemturner commented 2 years ago

Well cool, that seems to have fixed it.

That said this documentation needs to be updated to indicate that you need that value for non AADHTTPClient solutions as that is really not clear as this documentation gives the impression that it's only for your custom secured endpoints although now that you give me the values for it I can totally see why it would be needed.

juliemturner commented 2 years ago

I wonder if @Macro21 is suffering from a problem with their ability to auth with that endpoint because it's using a separate AAD App Reg.. i.e. you can only put 1 in your teams manifest and if he has a custom secured application that uses a different app registration maybe that's why SSO in the client desktop isn't working....

lucabandMSFT commented 2 years ago

Thanks @juliemturner : I've committed a change for this doc that specifies the need of that entry in the manifest to have auth working on Teams rich clients. Changes will go live as soon as my change gets approved.

@Macro21, are you able to make the same changes that helped Julie's scenario?

Macro21 commented 2 years ago

Hi! First, thanks for help.

Steps I followed this morning:

  1. To avoid errors, I created another project that I deployed using "Sync to teams" like @lucabandMSFT recommends.
  2. The new app works on web and mobile. (Remember that in my development environment the same solution works in all scenarios.)
  3. To solve the problem in desktop Teams I have tried @juliemturner solution (The workaround is (on the desktop client) visit a SharePoint page pinned as a Personal App (like Viva Connections Home) or a pinned SharePoint page on a tab. That page will load, get a token and then if you navigate back to the Personal App or Tab the SPFx solution it will load.):

image image image image image

Am I doing something wrong, @juliemturner ?

This is the new project deployed as personal app and teams tab:

image image

And the code:

image

On the other hand I have also tried another solution that one of my colleagues has worked in another project with the same problem, but it didn't work for me either. The solution that worked for my colleague was to use: "webApplicationInfo": { "resource": "https://{teamSiteDomain}", "id": "00000000-0000-0000-0000-000000000000" }, With a custom manifest, of course.

juliemturner commented 2 years ago

@Macro21 -- I can try and shed some light but I probably do not have all the answers. This section:

"webApplicationInfo": {
   "resource": "https://{teamSiteDomain}",
   "id": "00000003-0000-0ff1-ce00-000000000000"
}

says that the resource needs to have access to the AAD app registration with an id of 00000003-0000-0ff1-ce00-000000000000. Given what I know of how the tokens work in SPFx and if you look in AAD in your tenant, not in the App Registrations section (where your app for your Azure Function is likely registered) but in the Enterprise applications section you will find that id registered to an app called Office 365 SharePoint Online. image

Per my previous comments I did not know for SSO to work in the Teams Desktop client that webApplicationInfo would need a reference to that app registration because the documentation implication as I mentioned to @lucabandMSFT implied it was only used to do SSO when using the AADHTTPClient in SPFx which my solution is not... this is why, when I added that to my manifest my solution started to work, because it had a pointer to where it needs to go to get a SSO token. What I think you would need to do to get the AADHTTPClient to work is to modify the id, not with the value of the Office 365 SharePoint Online enterprise app registration id, but with the app registration that was created for your Azure Function. HOWEVER, what I was saying to @lucabandMSFT above is that that section of the Teams manifest only allows for one entry, it's not an array. So, I think if you do change it and it works you will not be able to access the Microsoft Graph or SharePoint endpoints through the SPFx HTTPClients (SPHTTPClient or GraphHTTPClient). And further, if your solution does access those it may still not work and you wouldn't really know it because you'd be changing one security token error for another... @lucabandMSFT would have to confirm, or you could test it. If that's not a need of your application, then I would say that might be the fix for you.

Macro21 commented 2 years ago

@Macro21 -- I can try and shed some light but I probably do not have all the answers. This section:

"webApplicationInfo": {
   "resource": "https://{teamSiteDomain}",
   "id": "00000003-0000-0ff1-ce00-000000000000"
}

says that the resource needs to have access to the AAD app registration with an id of 00000003-0000-0ff1-ce00-000000000000. Given what I know of how the tokens work in SPFx and if you look in AAD in your tenant, not in the App Registrations section (where your app for your Azure Function is likely registered) but in the Enterprise applications section you will find that id registered to an app called Office 365 SharePoint Online. image

Per my previous comments I did not know for SSO to work in the Teams Desktop client that webApplicationInfo would need a reference to that app registration because the documentation implication as I mentioned to @lucabandMSFT implied it was only used to do SSO when using the AADHTTPClient in SPFx which my solution is not... this is why, when I added that to my manifest my solution started to work, because it had a pointer to where it needs to go to get a SSO token. What I think you would need to do to get the AADHTTPClient to work is to modify the id, not with the value of the Office 365 SharePoint Online enterprise app registration id, but with the app registration that was created for your Azure Function. HOWEVER, what I was saying to @lucabandMSFT above is that that section of the Teams manifest only allows for one entry, it's not an array. So, I think if you do change it and it works you will not be able to access the Microsoft Graph or SharePoint endpoints through the SPFx HTTPClients (SPHTTPClient or GraphHTTPClient). And further, if your solution does access those it may still not work and you wouldn't really know it because you'd be changing one security token error for another... @lucabandMSFT would have to confirm, or you could test it. If that's not a need of your application, then I would say that might be the fix for you.

Yes, I understand that the GUID refers to an enterprise application in the AAD and that it gives you access to the Graph API and SPO resources.

Before opening this thread I already tried adding the GUID of the application I have registered myself in the AAD, but it didn't work.

At the moment in my solution I don't need Graph or SPO calls, but my own application can grant those permissions for Graph or SPO if needed, right?

In any case, it doesn't matter, because setting another GUID has no effect.

The real question is: Why in my development tenant it works and in the client one it doesn't?

Thank you very much for your help. :)

juliemturner commented 2 years ago

Yes, you are probably entirely correct about being able to grant access to the SP and Graph resources within your own app registration, I hadn't thought of that.

Re that you had already tried that, my apologies, although I read the thread I originally missed where you shared that information. So effectively in your development tenant using the Enterprise App registration Id in the Teams Manifest allows you to access even the Azure Function, that's interesting. I would have thought to make that work you would have had to have granted that enterprise app access to your Azure Function (similar to your scenario of adding SP and Graph resources to your registration). Regardless at this point your question is beyond my abilities to provide insight, hopefully on of the Microsoft people can think of something else.

lucabandMSFT commented 2 years ago

So.. it's not magic :): what we are doing here is basically implemented the same SSO flow that Teams had for rich client as described here.

When SPFx detects that it is running on Teams rich clients, we use that flow to get a token for SPFx application principal and then we exchange that to every token that was approved for SPFx components (via the API access page in SPO tenant admin).

Because we use SPO as a "broker" to access other resources, SPO is the only one that needs to be registered inside Teams manifest.

@Macro21 : when you say: "To avoid errors, I created another project that I deployed using "Sync to teams" like @lucabandMSFT recommends. The new app works on web and mobile. (Remember that in my development environment the same solution works in all scenarios.)" does it mean that it solves the problem?

Would be possible for us to take a look at the environment where the problem occurs and collect logs?

juliemturner commented 2 years ago

So, to clarify @lucabandMSFT you're saying that you only need to add the id of the Office 365 SharePoint Online app registration and that any other app registration you have for AADHTTPClient will get the token it needs. That is helpful to have shared, I hope you added that point to the documentation.

lucabandMSFT commented 2 years ago

yes @juliemturner , that is correct (and we are talking about the flow from the Teams rich clients here.. web is a different story).

and Yes: I added that to the documentation: waiting for that to be approved then it will go live

Macro21 commented 2 years ago

@lucabandMSFT "does it mean that it solves the problem?" :

In my development environment it has always worked. In fact, in the development environment I use two tenants and it is a much more complicated scenario and it still works:

image

In the client tenant (just one tenant):

image

As a workaround what I have done is to redirect to an SPO page within the code when detecting that we are in Teams Desktop. At the moment this works because we don't have more client requirements:

image

@lucabandMSFT "Would be possible for us to take a look at the environment where the problem occurs and collect logs?" : Sorry, it is not possible because it is the customer's production environment.

In any case, the alternative solution mentioned above works (Cause is not a Teams enviroment, is a SPO page without Teams context). If in the future they need this to work, the customer should open a ticket to support and try to solve the problem that way.

Thank you very much for your help @lucabandMSFT and @juliemturner

patmill commented 2 years ago

Thanks @Macro21 . We'll close this for now, but we have made a note of the scenarios, and are working on the improved docs.

ghost commented 2 years ago

Issues that have been closed & had no follow-up activity for at least 7 days are automatically locked. Please refer to our wiki for more details, including how to remediate this action if you feel this was done prematurely or in error: Issue List: Our approach to locked issues