Calling Protected API from UI not working #2401
Replies: 7 comments 2 replies
-
@Gregory-Lange: How does your "DownstreamApi" section look in the appsettings.json file. Do you have the square brackets around the scopes? Aside, you could use an authorization policy to verify the identity of the client. See https://github.com/AzureAD/microsoft-identity-web/wiki/authorization-policies |
Beta Was this translation helpful? Give feedback.
-
@jmprieur "DownstreamApi": {
"BaseUrl": "https://localhost:7214/",
"Scopes": "api://-------------/Swagger.Access"
} Also this morning when I did another clean solution however i did it on both the UI and API this time i am getting the message "WaitingForActivation" which doesn't make sense why it went from Unauthorized to Waiting for Activation. The AzureAD Admins have already granted the scopes that i linked in the UI app registration permissions and there are not permissions to grant consent in the API app registration. However if i change my authentication code back to what i had before i know it will throw the unauthorized and that code is below. builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddMicrosoftIdentityWebApi(builder.Configuration.GetSection("EntraId")); I also have the below way of calling the api that throws the unauthorized with the current auth setup for the api without reverting the auth to the above authentication. HttpResponseMessage value = await _DownstreamApi.CallApiForUserAsync("MyAPI", options => { options.BaseUrl = "https://localhost:7214/WeatherForecast"; }).ConfigureAwait(false); As for the policy i have actually extended the Authorization flow, handler/attribute/policyprovider/requirement, to allow me to do various things but have not called my custom coding yet as i wanted to test that i can in fact get my UI and API to talk to each other. |
Beta Was this translation helpful? Give feedback.
-
If i change a few things to make the scopes in the downstream section of Json us the square brackets i get an msal error which makes not sense to me. But i will read up on the link they give to this error. MsalUiRequiredException: No account or login hint was passed to the AcquireTokenSilent call. MicrosoftIdentityWebChallengeUserException: IDW10502: An MsalUiRequiredException was thrown due to a challenge for the user. See https://aka.ms/ms-id-web/ca_incremental-consent. |
Beta Was this translation helpful? Give feedback.
-
Given you are using IDownstreamApi, the scopes need to be an array "DownstreamApi": {
"BaseUrl": "https://localhost:7214/",
"Scopes": ["api://-------------/Swagger.Access"]
} The new exception you get is expected if Did the tenant admin provide admin consent for these scopes? Aside, I'm curious: why is your section named EntraId and not AzureAd? Is it an AzureAd app? a B2C app? or an Entra external identity app? |
Beta Was this translation helpful? Give feedback.
-
So i called it EntraId sense that is what AzureAD id now being called via re-branding. The UI and API both have their own App registrations and on the UI the scopes have been consented to by the admin for singleorg where i work. I guess i failed to tell you more about the stack i am using which is .net 6 MVC C# and a .net 6 WebAPI. So i have made the change to using the brackets and removed adding that on the initial scopes that i use in the .EnableTokenAcquisitionToCAllDownstreamAPI() but left it in the .adddownstreamapi(). Doing this i get the MsalUiRequiredException i posted prior but adding the AuthorizeForScopes i then just get an unauthorized message back on my call that is the following: HttpResponseMessage value = await _DownstreamApi.CallApiForUserAsync("MyAPI", options => { options.BaseUrl = "https://localhost:7214/WeatherForecast"; }).ConfigureAwait(false); Doesn't the program.cs setup not pull in all needed tokens even the downstream? If so why would setting the attribute to that make that change and do i also have to have that on the API side above the endpoint? I haven't found a straight forward example for doing this so i have been putting it together as i have read up on what to do. |
Beta Was this translation helpful? Give feedback.
-
Ok for EntryId, but this does not apply to public API changes, nor configuration file. But your choice (provided you also changed the section in the appsettings.jon). BTW: we are not going to update the appsettings.json and program.cs/startup.cs in the ASP.NET Core samples to replace AzureAd by EntryId Given you have pre-authorization, you could ask for the following scope: "api://-------------/.default" : this means all the pre-authorized scopes. the authorizeForScopes attribute is only for web apps (as there can be incremental consent). For web API only admin consented scopes can be requested (there is no UI in web APIs) We have examples of web apps calling web APIs (linked from the doc I shared above): |
Beta Was this translation helpful? Give feedback.
-
Sorry for the delay in response, however moving to the .default and adding the AuthorizeForScopes attribute made this all start working. I guess my assumption was if you called Authorize it would pull all and wouldn't need to do the Authorizeforscopes attribute. I do have one question on that and that is can i have the exception namespace that the AuthorizeForScopes uses also in my extended authorize attribute? So in my extended i would inherait from AuthorizeAttribute, IAuthorizationFilter and the ExceptionFilterAttribute? |
Beta Was this translation helpful? Give feedback.
-
Hi, I am working on having a UI and API both protected by their own Registered apps and have been following all of MS tutorials/docs on the subject but haven't been able to successfully make a call. My UI registration has the scopes from the api registration consented to and i am trying to call the downstreamapi via IDownstreamAPI.
I am getting 401 Unauthorized when doing the below i am also seeing in the output in the window as follows:
UI MVC App Program.cs
WebAPI Program.cs
UI HomeController.cs calling the api
Beta Was this translation helpful? Give feedback.
All reactions