SharePoint / sp-dev-docs

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

Provider-hosted App Receives 401 Error when Requesting an App-only Token #6903

Open rob-windsor opened 3 years ago

rob-windsor commented 3 years ago

Category

Describe the bug

My client has a provider-hosted app that has been in use for more than a year. The SharePoint add-in is deployed to the tenant App Catalog in SharePoint Online and the app is an ASP.NET web site deployed to Azure App Service. For the last several days the app has been receiving 401 errors when requesting app-only tokens.

Steps to reproduce

When the app is launched it fails when requesting the app-only token. The error status code is 401 and the error message is Token request failed. The remote server returned an error: (401) Unauthorized.

image

Full error call stack:

Microsoft.IdentityModel.SecurityTokenService.RequestFailedException: at Microsoft.IdentityModel.S2S.Protocols.OAuth2.OAuth2S2SClient.Issue (Microsoft.IdentityModel.Extensions, Version=2.0.0.0, Culture=neutral, PublicKeyToken=69c3241e6f0468ca) at <ProductName>AppWeb.TokenHelper.GetAppOnlyAccessToken (<ProductName>AppWeb, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null) at <ProductName>AppWeb.DAL.<ProductName>UnitOfWork..ctor (<ProductName>AppWeb, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null) at <ProductName>AppWeb.SharePointContextFilterAttribute.SetControllerVars (<ProductName>AppWeb, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null) at <ProductName>AppWeb.SharePointContextFilterAttribute.OnActionExecuting (<ProductName>AppWeb, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null) at System.Web.Mvc.Async.AsyncControllerActionInvoker+AsyncInvocationWithFilters.InvokeActionMethodFilterAsynchronouslyRecursive (System.Web.Mvc, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35) at System.Web.Mvc.Async.AsyncControllerActionInvoker+AsyncInvocationWithFilters.InvokeActionMethodFilterAsynchronouslyRecursive (System.Web.Mvc, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35) at System.Web.Mvc.Async.AsyncControllerActionInvoker+<>c__DisplayClass33.<BeginInvokeActionMethodWithFilters>b__31 (System.Web.Mvc, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35) at System.Web.Mvc.Async.AsyncResultWrapper+WrappedAsyncResult1.CallBeginDelegate (System.Web.Mvc, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35) at System.Web.Mvc.Async.AsyncResultWrapper+WrappedAsyncResultBase1.Begin (System.Web.Mvc, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35) at System.Web.Mvc.Async.AsyncControllerActionInvoker.BeginInvokeActionMethodWithFilters (System.Web.Mvc, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35) at System.Web.Mvc.Async.AsyncControllerActionInvoker+<>c__DisplayClass21.<BeginInvokeAction>b__19 (System.Web.Mvc, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35) Inner exception System.Net.WebException handled at Microsoft.IdentityModel.S2S.Protocols.OAuth2.OAuth2S2SClient.Issue: at System.Net.HttpWebRequest.GetResponse (System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089) at Microsoft.IdentityModel.S2S.Protocols.OAuth2.OAuth2WebRequest.GetResponse (Microsoft.IdentityModel.Extensions, Version=2.0.0.0, Culture=neutral, PublicKeyToken=69c3241e6f0468ca) at Microsoft.IdentityModel.S2S.Protocols.OAuth2.OAuth2S2SClient.Issue (Microsoft.IdentityModel.Extensions, Version=2.0.0.0, Culture=neutral, PublicKeyToken=69c3241e6f0468ca)

Expected behavior

The request for the app-only token returns a 200 status code and includes the token.

Environment details (development & target environment)

Additional context

I have confirmed the following.

image

image

image

image

ghost commented 3 years ago

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

pdentener commented 3 years ago

My client has a provider-hosted app that has been in use for more than a year. The SharePoint add-in is deployed to the tenant App Catalog in SharePoint Online and the app is an ASP.NET web site deployed to Azure App Service. For the last several days the app has been receiving 401 errors when requesting app-only tokens.

We have the very same setup and are facing a similar issue. All existing installs of our App are (still) working fine, but it's impossible to get the app working in 2 separate new (at least to our App) SharePoint Online tenants (with DisableCustomAppAuthentication set to false). In those SharePoint online tenants requesting an app-only token always returns 401 with a similar stack trace (for the token part).

VesaJuvonen commented 3 years ago

We are tracking this internally, but if anyone has an option to open up a Premier Support case for pushing things forward more efficiently, that would be awesome. Seems like a growing issue with new tenants gradually here and there, so hoping that we would get this on the official process with Premier Support soon. We'll try to prioritize this internally also regardless.

patmill commented 3 years ago

Hi @rob-windsor - is it possible for you to paste the URL that is failing? Feel free to scrub query strings / PII / etc. Is it a call to accounts.accesscontrol.windows.net, or is it a call to the sharepoint domain?

rob-windsor commented 3 years ago

@patmill It's a call to https://accounts.accesscontrol.windows.net/tokens/OAuth/2. Error message is Token request failed. <--- The remote server returned an error: (401) Unauthorized.

But I can make what I believe is the same call using Fiddler and get a 200 response with a token.

image

patmill commented 3 years ago

Thanks Rob, trying to figure out where to route this issue to. One more thing that might be useful is to see what the difference between the request generated from the running code vs. the request you generate manually. Do you happen to have access to the headers / body / etc. of both, or just the manual one?

rob-windsor commented 3 years ago

@patmill I just have access to the information available in Azure Application Insights. So far I haven't found a way to get the headers and body of the request from there, just the URL. I'm not super familiar with Application Insights, so it's possible that information is available and I just don't know how to get to it.

rob-windsor commented 3 years ago

@patmill The provider-hosted app is using the standard TokenHelper to get the app-only token. I don't know if that helps answer your previous question, but I thought it would be worth a mention.

phettz commented 3 years ago

@rob-windsor Not sure if its the same issue, but I had some "random" errors with auth from old applications a month ago or so. The issue was then that the old applications did not use TLS 1.2 as default from where the code was running. I just bumped the .NET Version of the project and it started working again.

Could also try setting in manually in your code:

const System.Security.Authentication.SslProtocols _Tls12 = (System.Security.Authentication.SslProtocols)0x00000C00;
const System.Net.SecurityProtocolType Tls12 = (System.Net.SecurityProtocolType)_Tls12;
System.Net.ServicePointManager.SecurityProtocol = Tls12;
pdentener commented 3 years ago

@rob-windsor Not sure if its the same issue, but I had some "random" errors with auth from old applications a month ago or so. The issue was then that the old applications did not use TLS 1.2 as default from where the code was running. I just bumped the .NET Version of the project and it started working again.```

We had the very same issue in a couple of our client's SharePoint Online tenants. I think Microsoft is enforcing the higher TLS version incrementally, tenant by tenant. After enabling TLS 1.2 everything was fine again. Until a few weeks later the issue with the 401 token response started cropping up. Both issues seem unrelated to me, but who knows.

@rob-windsor Should you find a workaround or even a permanent solution for the 401 issue before anything appears in this thread, I would greatly appreciate your feedback as some of our clients are still struggling with getting our app to work. We are in the midst of opening a ticket, but getting it opened in the right place, is a challenge in itself.

rob-windsor commented 3 years ago

The application was configured to use .NET 4.5. I bumped that to .NET 4.7.2 and it appears to have addressed the issue. However, @pdentener 's comment about the issue returning even after bumping the .NET version concerns me. I guess all I can do is monitor the situation and deal with the issue if it returns.

Thanks to everyone who offered assistance here!

image

JonathanHuss commented 3 years ago

+1 for this exact same scenario that showed up with an organization I'm supporting. Upgrading the .NET version to 4.7.2 in the web.config resolved the issue for us, too, at least for now. We have a case open as well, but it's not a Premier level case. Not sure if that's useful for tracking at all or not (@VesaJuvonen)? I'm also a Microsoft FTE, so happy to share screens or data or whatever that might be useful for further troubleshooting.

JayakumarB commented 3 years ago

I also face similar issue for two of my customers. I was able to fix this by upgrading .Net framework from 4.5 to 4.7.2. Thanks everyone!