Azure AD Protected Web API calls failed with Consent error - azure-api-apps

I have an application(WebApp) which calls external API(WebApi1) and WebApi1 calls Another external Api WebApi2.
I have given application permission to WebApi1 from WebApp
Similarly application permission to WebApi2 from WebApi1
I got consent page for WebApi1 and accepted it, it works fine for WebApi1. But when I tried to call WebApi2 with on behalf of user from WebApi1, it throws consent page error.
AADSTS65001: The user or administrator has not consented to use the
application with ID

If you register the app from Azure portal, there is no need to config the knownClientApplications since it already give the consent when we register the app.
And if you register from other portal, after you config the KnownClientApplications you need to grant the permission again to use the parameter prompt=consent. In this time, the web app will also require you to give the consent to the web api2. After you grant the consent, the issue should be fixed.

Related

User-Consent screen not showing when using Postman and .Net 6 Web Api

So I am writing a .NET 6 Core Web Api using Azure AD as authentication for the API.
Now when using Graph API as example, you need to setup Graph API scopes in the App Registration. Lets use a delegated "user.read" permission for this example.
I use Postman to receive the access token for the application by authenticating as an user against Azure AD for the API. I would expect to receive a consent-screen so I can consent to the usage of "user.read". This does not happen though.. I get logged in and receive a valid access token. In the Backend though, it will throw an error because the user / admin did not consent to the application.
How do I get around this? Why don't I get asked to consent the permissions set up in the app registration? Neither in Postman, nor in a Swagger oAuth Flow..
My current workaround for this is to use a React application and sign in over the frontend application. Using the frontend application, I get asked to consent to the permissions. After consenting, I can use postman without getting the "user didn't consent" - error.
Any ideas? What did I miss?
Let's focus on the user-consent page first. When we created an azure ad app then add api permission for it, then use this azure ad app to make your .net 6 app/react app integrate azure ad to use azure authentication, and we go to the microsoft sign in page and successfully sign in, we will see a dialog which indicating that this app require you to consent a list of permissions. The permissions are correspond to the api permissions you set for the aad app. After consent once, then it won't ask you to consent again when sign in next time.
This consent only happened when users are signed in. Let's go back to the flows used to generate access token in Azure AD. Since you used delegate permission, then you may used the recommend Auth code flow(Another flow called ROPC flow can also generate delegate access token but not recommended). When we used auth code flow, we need to sign in first, the login url should look like this:
https://login.microsoftonline.com/tenant.onmicrosoft.com/oauth2/v2.0/authorize?client_id=azure_ad_app_id
&response_type=code
&redirect_uri=http://localhost/myapp/
&response_mode=query
&scope=user.read
&state=12345
We need to use it to get the auth code, then we can use the code to generate access token, per my test, I created a new azure ad app and when I directly hit this url in the browser and sign in, it still required me to give the consent. So I'm afraid the reason why you didn't see the dialog when test in post man is that you've consent it when test in react app, or you don't use auth code flow.

Azure AD SSO login problem with admin account

I've registered a single application in Azure AD for the following reasons.
Azure AD SSO (From Any Azure AD directory)
Read users, groups, and their members
Provided following permissions and granted admin consent.
NOTE: We still depend on some of the Azure AD Graph API. So, we have added the legacy API permissions.
I can able to contact the Azure AD using REST API and get the user, groups and other information.
When I try to sign in to the application from any other directory, I'm getting the following consent screen. I can able to provide the consent and proceed to log in.
But, when I try to login into the same directory, I'm not getting the consent screen even when I logged in with the Azure AD admin. Stuck in the following screen.
When I register separate applications for SSO and REST APIs, this issue doesn't occur.
I would like to know why I'm stuck in the above screen when combining both SSO and REST API permissions.
• Please check whether the correct Azure AD roles have been assigned to your account ID, i.e., Global Administrator, Cloud Application Administrator, Application Administrator, or owner of the app object through the as one of these is needed for you to access the application. Also, ensure that you have assigned your account ID the correct app role assignment for the admin consent to be allowed during the SSO signup process as below: -
You can check the app role assignments for your account ID through the Enterprise application blade and searching your application there, then opening it and selecting the users and groups blade, check the app role assignment that your account ID has to that application while also, giving ‘Azure Service Management’ api permissions for user_impersonification as below, thus ensuring that you account ID will be having correct API permissions.
Once, the above settings are configured correctly, you should be able to access the application through your admin credentials.

Is Azure's User.Read permission required for OAuth consent forms?

My multi-tenant Azure application requires only the app-level EWS legacy permission full_access_as_app to run. This app-level permission can only be consented to by an administrator---it's extremely powerful because it gives the app read and write permissions over every EWS mailbox in a tenancy.
If I, as an admin for my Azure tenancy, grant my application only this single permission behind the scenes in AAD configuration, everything works fine when I run the application for my tenancy.
However when you create a new app in Azure, Azure always assumes you will want the user-level Graph API User.Read permission automatically. When you try to remove the permission you get this ominous warning:
And in the case when I leave it out, interactive OAuth consent forms don't work. The error message looks like this.
The client has not listed any permissions for 'AAD Graph' in the requested permissions in the client's application registration. Or, The admin has not consented in the tenant. Or, Check the application identifier in the request to ensure it matches the configured client application identifier. Please contact your admin to fix the configuration or consent on behalf of the tenant.
In other words, it appears that the application won't be able to run for anyone else's tenancy because their admins can't consent to it.
My hypothesis is that this is because Azure is using the User.Read permission to check whether the person signing in through the OAuth form is an administrator. In other words this permission is needed just this one time, before the application is ever run for the admin's tenancy.
Looking at the actual OAuth consent form, this does appear to be the case.The app wants to sign in and read my profile, to check if I am admin... or so it seems to me.
Am I right about this? Documentation I have been able to find is rather scanty.

Azure AD secured .Net Core Web API 3.1 from Angular Frontend returns 401 with MSAL

I am attempting to access a secure .net core 3.1 Web API via an Angular 9 front-end. I used the Angular 9 code sample from the MSAL Angular repo.
I can successfully sign in using my own Azure AD App Registrations, but when calling my endpoint (decorated with [Authorize]), I get a 401 in my frontend, as well as in postman (expected).
My Angular Interceptor doesn't even add the bearer token in the request to the API because the getScopesForEndpoint() returns null for the request:
let scopes = this.auth.getScopesForEndpoint(req.url);
console.log(scopes);
// scopes is null here.
If I hard-code the scopes into the interceptor like this:
scopes = [
"user.read",
"openid",
"profile",
"api://[My API ID]/weatherforecast"
];
I receive this error:
InteractionRequiredAuthError: AADSTS65001: The user or administrator has not consented to use the
application with ID '[MY APP CLIENT ID]' named '[MY APP]'. Send an interactive
authorization request for this user and resource.
I followed this tutorial here: Tutorial and I configured my Azure AD to be very similar to this. The only major change was that I allowed MutiTenant instead of SingleTenant:
My Angular app doesn't seem to be registered with the API, according to the error, but I thought that is what this was in Azure AD:
Am I missing a step in allowing my app to call my API's authorized endpoint? Here is a post, Very similar to the setup that I followed Related SO Post. The only difference is that my Web API is on https://localhost:44381/weatherforecast instead of being deployed to Azure. The accepted answer doesn't seem to help with my scenario. Also another very similar post here: Related SO Post 2 but the answer talks about a Cors issue, which is not relevant.
In your front-end AD app, you need to add the Delegated permission instead of Application permission.
If you have not define a Delegated permission for your Web API App, navigate to it in the portal -> Expose an API -> Add a scope, follow this link to expose an API Delegated permission.
Then in your front-end AD app, add the delegated permission.
After add the permission, click the Grant admin consent for xxx button, it means the admin consent for the permission for the user just in your AAD tenant.
Note: if your app is a multi-tenant app, and the user who login to the app is in another AAD tenant, it needs the admin of that tenant consent the app, just let the global admin of that tenant to login the app, consent the permission. After the consent, other users in that tenant will also be able to login.
In your code, the authority need to be https://login.microsoftonline.com/common, then in the scopes of the request, it need to include the delegated permission scopes: ["<Application ID URI>/<Scope name>"], in my sample, it is scopes: ["api://xxxxxxx/Test.test"].

Azure AD OAuth2.0 Application Permissions

I am trying to setup an API to be protected using Oauth 2.0 in Azure AD. I follow the steps in here: https://learn.microsoft.com/en-us/azure/active-directory/develop/v2-oauth2-auth-code-flow.
The API has one scope - one application permission defined. I am able to add the API permission successfully to the client app, and have selected the right scope, as shown in the screenshot.
However, when I test the web app, after authentication the below error is thrown:
The application OAuthClientApp asked for scope approle that doesn
t exist on the resource 2700000003-0000-0000-c000-000000000000.
Contact the app vendor.
App permissions only apply when a client app uses client credentials only for authentication.
So when there is no user involved, app permissions apply.
A client can acquire an access token using their client id + secret/certificate with the scope your-api-client-id/.default or your-api-id-uri/.default.
Documentation for client credentials grant: https://learn.microsoft.com/en-us/azure/active-directory/develop/v2-oauth2-client-creds-grant-flow.
.default basically means "the permissions required statically by my app in the registration".
Since app permissions must be required statically, it makes sense to use it.
Authorization code grant, implicit grant and a few others involve a user in the authentication and only delegated permissions apply.
Remember to also grant admin consent for the app permission.
In the screenshot it says consent has not been granted.

Resources