9

I am following this Microsoft Docs tutorial and everything appears to work upto the point where I call the web api with the access token using Postman.

To be specific:

  • I request a token, Azure AD redirects me to supply Username and Password
  • Credentials are accepted and a token is returned
  • I tell Postman to use the token and call the api
  • I get a 401

If I decode the token everything appears correct, i.e. the aud matches the Web API registration in AD B2C, User is correct, claims, etc.

Commenting out the [Authorize] attribute in my API works, data is returned so its something in the authorization of my API I think.

I'm not sure how I can debug the authentication process in ASP.NET Core Web API though. For example putting breakpoints in my controller doesn't work because my code doesn't even get that far.

UPDATE

In the Postman Console the Response Headers say: WWW-Authenticate:"Bearer error="invalid_token", error_description="The issuer is invalid"". The issuer is https://login.microsoftonline.com/<guid>/v2.0/.

UPDATE 2

Embarrassingly, as documented in the article, once I matched the AzureAdB2C.Instance setting in my appsettings.json with the Postman Auth Url the invalid_token error goes away but now I'm getting 500 errors: Unable to obtain configuration from..., Microsoft.IdentityModel.Protocols.ConfigurationManager&lt;T&gt;.GetConfigurationAsync(CancellationToken cancel).

BRICK WALL

The thread 0x5c30 has exited with code 0 (0x0).
Microsoft.AspNetCore.Hosting.Internal.WebHost:Information: Request starting HTTP/1.1 GET https://localhost:44366/api/values  
'iisexpress.exe' (CoreCLR: clrhost): Loaded 'C:\Program Files\dotnet\shared\Microsoft.NETCore.App\2.2.5\System.Net.Sockets.dll'. 
'iisexpress.exe' (CoreCLR: clrhost): Loaded 'C:\Program Files\dotnet\shared\Microsoft.NETCore.App\2.2.5\Microsoft.Win32.Primitives.dll'. 
'iisexpress.exe' (CoreCLR: clrhost): Loaded 'C:\Program Files\dotnet\shared\Microsoft.NETCore.App\2.2.5\System.Net.NameResolution.dll'. 
'iisexpress.exe' (CoreCLR: clrhost): Loaded 'C:\Program Files\dotnet\shared\Microsoft.NETCore.App\2.2.5\System.Security.Cryptography.Encoding.dll'. 
'iisexpress.exe' (CoreCLR: clrhost): Loaded 'C:\Program Files\dotnet\shared\Microsoft.NETCore.App\2.2.5\System.Collections.NonGeneric.dll'. 
Exception thrown: 'System.Net.Http.HttpRequestException' in System.Net.Http.dll
Exception thrown: 'System.IO.IOException' in Microsoft.IdentityModel.Protocols.dll
Exception thrown: 'System.IO.IOException' in System.Private.CoreLib.dll
Exception thrown: 'System.IO.IOException' in System.Private.CoreLib.dll
Exception thrown: 'System.InvalidOperationException' in Microsoft.IdentityModel.Protocols.dll
Exception thrown: 'System.InvalidOperationException' in System.Private.CoreLib.dll
'iisexpress.exe' (CoreCLR: clrhost): Loaded 'C:\Program Files\dotnet\shared\Microsoft.NETCore.App\2.2.5\System.Diagnostics.StackTrace.dll'. 
'iisexpress.exe' (CoreCLR: clrhost): Loaded 'C:\Program Files\dotnet\shared\Microsoft.NETCore.App\2.2.5\System.Reflection.Metadata.dll'. 
Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerHandler:Error: Exception occurred while processing message.
System.InvalidOperationException: IDX20803: Unable to obtain configuration from: '[PII is hidden]'. ---> System.IO.IOException: IDX20804: Unable to retrieve document from: '[PII is hidden]'. ---> System.Net.Http.HttpRequestException: Response status code does not indicate success: 404 (Not Found).
   at System.Net.Http.HttpResponseMessage.EnsureSuccessStatusCode()
   at Microsoft.IdentityModel.Protocols.HttpDocumentRetriever.GetDocumentAsync(String address, CancellationToken cancel)
   --- End of inner exception stack trace ---
   at Microsoft.IdentityModel.Protocols.HttpDocumentRetriever.GetDocumentAsync(String address, CancellationToken cancel)
   at Microsoft.IdentityModel.Protocols.OpenIdConnect.OpenIdConnectConfigurationRetriever.GetAsync(String address, IDocumentRetriever retriever, CancellationToken cancel)
   at Microsoft.IdentityModel.Protocols.ConfigurationManager`1.GetConfigurationAsync(CancellationToken cancel)
   --- End of inner exception stack trace ---
   at Microsoft.IdentityModel.Protocols.ConfigurationManager`1.GetConfigurationAsync(CancellationToken cancel)
   at Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerHandler.HandleAuthenticateAsync()
   at Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerHandler.HandleAuthenticateAsync()
   at Microsoft.AspNetCore.Authentication.AuthenticationHandler`1.AuthenticateAsync()
   at Microsoft.AspNetCore.Authentication.AuthenticationService.AuthenticateAsync(HttpContext context, String scheme)
   at Microsoft.AspNetCore.Authentication.AuthenticationHandler`1.AuthenticateAsync()
   at Microsoft.AspNetCore.Authentication.AuthenticationService.AuthenticateAsync(HttpContext context, String scheme)
   at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
   at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)
'iisexpress.exe' (CoreCLR: clrhost): Loaded 'C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App\2.2.5\Microsoft.AspNetCore.Http.Extensions.dll'. 
Microsoft.AspNetCore.Hosting.Internal.WebHost:Information: Request finished in 1438.8301ms 500 text/html; charset=utf-8
phil
  • 1,938
  • 4
  • 23
  • 33
  • What version of ASP.Net Core are you using for API? All auth* process is related to Identity. Identity is part of NetCore since v3 but is external in 2.2. Finally what you need is debug Identity namespace what is part of ASP.NET Core. – Sam Jul 17 '19 at 10:27
  • @Sam ASP.NET version is 2.2. – phil Jul 17 '19 at 10:38
  • You will find here how to activate debugging for not only your code but disassembly code. https://www.stevejgordon.co.uk/debugging-asp-net-core-2-source Namespace is Microsoft.AspNetCore.Identity if I remember well. Althougt logic could be in DataAnotations because you using [Authorize] as a tag. I hope it helps you almost a little. – Sam Jul 17 '19 at 11:05
  • @Sam, thanks I'll take a look. – phil Jul 17 '19 at 11:17
  • I am thinking your problem probably is with policy. Some misspell or difference between azure and api expected values. If you want copy the code in your Startup.cs or ensure it match with configuration you are using in azure. – Sam Jul 17 '19 at 11:18
  • 4
    embarrassing or not, the question “how do I *Debug* this?” remains extremely valid – Chris F Carroll Nov 07 '21 at 17:27

2 Answers2

0

Prompted by @Sam's last comment and my earlier realization of matching authority domains, instead of matching the appsettings.json AzureAdB2C:Instance value to the Postman Auth Url value of https://login.microsoftonline.com/, I matched the Postman Auth Url value to the appsettings AzureAdB2C:Instance value of https://<mytenant>.b2clogin.com/.

phil
  • 1,938
  • 4
  • 23
  • 33
0

I faced a similar issue while working from postman.

Solution : I have added the token under the postman Headers (Key : Authorization, Value : Bearer <YOUR_TOKEN_GOES_HERE>)

Replace <YOUR_TOKEN_GOES_HERE> with your token.

Problem : I have used the Bearer Token type under Authorization to pass token and received 401 error.

401 error from postman