user does not exists in the tenant directory error when calling microsoft graph api - azure-active-directory

I'am trying to call microsoft graph api, I have did the instructions by microsoft documnets as bellow:
1- app registration in azure portal
Supported account types : all microsoft account users
2- calling 'https://login.microsoftonline.com/',tenant_id,'/oauth2/v2.0/authorize' by these parameters:
client_id <- #Application Id - on the azure app overview page
client_secret <-# the secret key for my app from azure portal
scope <- 'https://graph.microsoft.com/.default'
grant_type <- 'password'
username <- 'XXX#outlook.com'
password <- # the user password
tenant_id <-# tenant id for my app from azure portal
but it has this error:
AADSTS50034: The user account {EmailHidden} does not exist in the <tenant_ID> directory. To sign into this application, the account must be added to the directory.
I have registered my app by the same account that I passed through api.
I want to call my todo list from the graph.
based on #MdFaridUddinKiron's response I added some more explanation:
I think something in my domain in azure is wrong, these are some screenshot of it:
1- it shows "common" for endpoints, what should I use? "common" or my tenant:
2- my app authentication tab has some differences, is it important?
3- My domain overview page is look like this:
4- user is added in my active directory 5- user application page:
6- user assigned role:
I tested microsoft graph api successfully by the same user in the graph explorer, I am getting confused how the authentication flow must be.
I just want to call my own todo tasks

As per your comment, please follow the detail steps:
Make sure email you are trying to get token with is exists in azure ad
user list which showed below in details.
https://login.microsoftonline.com/YourTenant.onmicrosoft.com/oauth2/v2.0/token
client_id:b603c7be_Client_id_e61f925
scope:https://graph.microsoft.com/.default
client_secret:NpmwO/KDJ_client_secret:NpmwO_W0kWf1SbnL
username:tenentUser.onmicrosoft.com
password:YourUserPassword
grant_type:password
See the screen shot:
I am getting token as expected
Step: 1
Step: 2
Step: 3
Step: 4
Filter your user from your azure active directory user list as shown below.
Note:
Requested token user must be a tenant user for example YourUser#Yourtenant.onmicrosoft.com
User password must be correct that you are suing to token request.
Make sure your user belong to azure portal on your tenant
Your Client Id belongs to that tenant
Application secret is valid or not expired.
Update:
What should I use? "common" or my tenant?
It depends if you have many tenant in that case you can use common.
For example user need not to remember specific tenant they would
automatically redirected to specific tenant as per the credentials
they given.
For more information you could refer Official document
Feel free to share still you are having problem.

Related

How do I check if the user from a non-Graph Azure AD token is a member of an email distribution list in an APIM policy

Have an API in Azure API Management (APIM).
The API operation validates a JWT generated by Azure Active Directory (AAD) using a scope from a backend app registration (the scope is NOT User.Read). Note: client id is another app registration which is an authorized app of that backend scope.
After the JWT is validated, am I able take that token, extract user info out of it and verify if the user is part of a email distribution list (DL)? If so, how to do it within an APIM policy?
I am aware of MS Graph APIs. Using Postman I can confirm the DL is listed in the tenant's groups and can get its group ID. I can also confirm the user is a member of the group. The bit I'm stuck with for Graph API is that it needs a different token to the one supplied by the client application (due to he scopes being from different domains custom app registration vs graph) and I'm stuck at this point. Should I make the client app also get a graph token and pass it in a separate header, or is there way to orchestrate things from within APIM or something else?
The non-APIM part of this solution is provided by a Microsoft article. I've summarised those and combined with the APIM parts in the following steps:
In Azure, create a new Azure App Registration (note the client id for later)
Under "Certificates and secrets", add a client secret (note the secret for later)
Under "API Permissions", add a new MS Graph Application Permission (can be User.Read.All, Group.Read.All, GroupMember.Read.All depending on your situation). MS Graph's "groups" includes both AD groups and Distribution Lists (DL). Note: don't use Delegated permission.
Application permissions allow the authorized app to enquire about any user/group. You will need an Azure Admin to Grant Admin Consent for the App Registration to have the chosen Application Permission.
Now in Azure APIM, go to your API and edit the inbound policy.
Validate the JWT from the user making the call (See validate-jwt or newer validate-azure-ad-token) to ensure the User is authorized to call this API.
Extract the oid claim from the JWT (this is the user ID I'll use for the graph call) and save it in a variable using set-variable policy
Add a send-request policy request an auth token for MS Graph using client-credentials flow (this is when you'll need the client id and secret from earlier App registration). Note: secrets should be stored in a secure store like KeyVault but that is outside the scope of this answer.
Extract the access_token field from the JSON response body and put it in a variable using set-variable policy.
Create another send-request policy, but this time to the MS Graph endpoint. For User.Read.All permission you'd use /users/<userIdFromJwtOidClaim>/memberof/<groupId>. MS Graph v1.0 API Reference, and pass the access_token in the Authorization header using <set-header> element.
A status code of 200 indicates the user is a member of the group. IIRC A status code of 403 indicates the user isn't a member of the group.
Use a choose policy to perform logic depending on the user's group membership.
Use return-response policy to send a response back to the user.

Microsoft OAuth authorization for specific user roles

I have to limit which users can access an Azure App. For now, only Global Admins can access using this link:
login.microsoftonline.com/common/oauth2/v2.0/authorize?client_id=client_id_goes_here&scope=user.read.all&response_type=code&redirect_uri=https://myredirectbacklink.com/aad/auth&response_mode=query&state=portal&prompt=consent
After redirect back I get Token using
https://login.microsoftonline.com/common/oauth2/v2.0/token and the query contains the same scope as the authorized link.
The flow of the app is the same as documented in Microsoft identity platform and OAuth 2.0 authorization code flow.
My problem is that client wants to allow Billing Admins to access their app. I went through all Graph Permission Scopes, but could not find any related to Billing Admin.
My knowledge of Microsoft's authorization is somewhat limited. I do know that limitations are done by scope. But if it's just link change or is it in Authentication App in Azure (there is one but I don't know how it's related to actual login permissions).
Should I look in a different direction or is it just simply changing the link? Microsoft's documentation didn't help a lot because it's mostly about calendars and other simple stuff.
Careful, requesting a permission that normally requires admin consent and causing the user consent prompt is not the proper way to ensure the user signing in is actually an admin. A non-admin user could simply modify the URL to scope=User.ReadBasic.All and remove prompt=consent. If the user is allowed to consent for User.ReadBasic.All (which is true in many organizations), they'd be able to continue the sign-in. (Or if the organization had granted admin consent for "User.Read.All", the non-admin user would only need to remove prompt=consent.)
If you need to ensure the user is an administrator, you need to explicitly check for directory role assignments.
You can choose from one of three different ways to do this:
You can configure your app to receive the wids claim, which will include the role template IDs of the directory roles for which the user has an active assignment. This is probably the simplest approach.
Using the Azure portal, you can do this under App registrations > (choose your app) > Token configuration > + Add groups claim. You must include "Directory roles" in your selection:
Another option is to a Microsoft Graph API request to check which of a given list of directory roles the user has been assigned:
POST https://graph.microsoft.com/v1.0/me/checkMemberObjects
Content-type: application/json
{
"ids": [
"fdd7a751-b60b-444a-984c-02652fe8fa1c",
"b0f54661-2d74-4c50-afa3-1ec803f12efe"
]
}
A third option is to make a Microsoft Graph API request to list the directory role assignments granted to the user:
GET https://graph.microsoft.com/beta/roleManagement/directory/roleAssignments
?$filter=principalId eq '{id}'
All three of these approaches involve using directory role template IDs to identify the directory role you are checking for. They're all listed here: https://learn.microsoft.com/azure/active-directory/roles/permissions-reference
Some examples you may be interested in:
Application administrator: 9b895d92-2cd3-44c7-9d02-a6ac2d5ea5c3
Cloud application administrator: 158c047a-c907-4556-b7ef-446551a6b5f7
Global administrator: fdd7a751-b60b-444a-984c-02652fe8fa1c
Privileged role administrator: e8611ab8-c189-46e8-94e1-60213ab1f814
Billing administrator: b0f54661-2d74-4c50-afa3-1ec803f12efe
(I included the first four because those are the directory roles which would, by default, be allowed to grant consent for User.Read.All.)
If someone needs solution and uses php:
You can use https://github.com/microsoftgraph/msgraph-sdk-php
$accessToken = 'token from redirect back, called access_token';
$body = [
"ids" => [
"fdd7a751-b60b-444a-984c-02652fe8fa1c",
"b0f54661-2d74-4c50-afa3-1ec803f12efe"
]
];
$graph = new Graph();
$graph->setAccessToken($accessToken);
$user = $graph->createRequest("post", "/me/checkMemberObjects")
->attachBody($body)
->execute();

Azure AD Enterprise Application - Identify Caller Application

I have a REST API which uses Azure ADD App registration to allow other apps to call it.
In the Azure Portal, I have registered it as an Enterprise Application and also registered the consumer applications and assigned them Roles appropriately.
The authentication and RBAC works fine.
But the use case that I am working on requires me to identify and log the incoming request calling application's name (The one seen in the portal as 'Display Name', when we view the list of users and groups for an enterprise Application).
As advised in the internet, I am using some Identity related API to read the claims from the request header.
var provider = claimsUser.FindFirst("http://schemas.microsoft.com/identity/claims/identityprovider").Value;
var sid = claimsUser.FindFirst(ClaimTypes.NameIdentifier).Value;
OR
var sid = claimsUser.FindFirst("stable_sid").Value;
But this gives me a GUID value which I couldn't map to any of the consumers of the Enterprise Application.
The clients are all registered in the Azure portal.
In the Portal, I can see the apps in the "Users and Groups" section for the Enterprise application, with their appropriate roles.
In terms of usage, before making the call, the clients generate a bearer token based on the certificate that they get from Azure. The make the call with the bearer token attached to the request header. This bearer token is validated against the Azure AD, in the filters set before every controller..
What I want is to get are the details about this client who has made the call.. As per some repliers, and, to which I agree, the Guid that I get as part of the previous call mentioned above is for the actual user and not the app itself which is making the call.
Can anyone throw some light into it.. some code snippet will be of real help..
I'm not sure what authentication flow you are using, but SID is generally for a user that's logged in, not an application. if your client applications are using client id and secret, the token it returns that you send to the api should include the app registration guid. https://learn.microsoft.com/en-us/azure/active-directory/develop/v2-oauth2-client-creds-grant-flow#access-control-lists . So the appid and iss should give you the guid of the app registration. using this, you can make a call to graph api, to identify the display name of the app registration. https://learn.microsoft.com/en-us/graph/api/application-get?view=graph-rest-1.0&tabs=http
If your app is a user login app, and you don't want to make a call to graph, the other option you could do as a workaround would be to create app roles and assign users to them but name the app roles with some convention that includes the app's display name. then the name could come through under roles claim.. https://learn.microsoft.com/en-us/azure/active-directory/develop/howto-add-app-roles-in-azure-ad-apps
those are some options.. but other than calling graph or kinda working around to inject the name into a different claim of the token I'm not sure of any other method to get the "app registration's display name"

connect azure function to b2c

So, I created azure b2c directory, and created inside it application like https://github.com/Azure-Samples/active-directory-b2c-javascript-msal-singlepageapp, and I created azure function in general azure directory that suppose to read blob and return json file. Also I created custom login page for sign in.
I ran my program locally, and I can login, and instead of call API that uses in github, I call azure function and it works.
But now I want to secure access to function, so I make authLevel 'user' and try to make Authentication via Azure Active Directory.
And no mater how I make settings, or I can't connect because I don't have permissions, or I can't use function because I don't have permissions.
Also I get this error The client id ’/.auth/login/aad/callback' specified in the request is not registered in tenant ‘’.”
How should I connect function to b2c so only authorised users can have access to function response.
Setting up B2C authentication for your Azure Functions App is actually really easy:
Create Azure Functions App and write down the URL
E.g. https://myazurefunctions.azurewebsites.net (make sure to make it a HTTPS URL)
Configure your application in Azure Active Directory B2C:
Write down the Application ID
Add a reply URL for your Functions App,
adding the suffix /.auth/login/aad/callback. E.g.
http://myazurefunctions.azurewebsites.net/.auth/login/aad/callback
Get the Metadata Endpoint URL for your Sign-in policy
If you open the details of your sign-in policy, you'll find it right at the top. E.g.:
In your Functions App, on the bottom left select "Function app settings" and go to "Configure authentication":
Turn on authentication and select Azure Active Directory:
Select the advanced settings and enter the following values:
Client ID: The Application ID which you copied in step 2. a.
Issuer Url: The Metadata Endpoint URL from step 3.
Save your settings and you're done!
With the new "User flows (policies)" a few small changes must be made to the selected answer:
Perform Step-3 as follows to get the "Metadata Endpoint URL”:
a) Go to your B2C tenant and click on User flows (policies).
b) Select your login (or sign up sign in) flow and click on “Run user flow”.
c) Your "Metadata Endpoint URL” is displayed at the top of the new window – right beneath the ”Run user flow” heading.
Perform Step-4 and 5 as follows to configure “Authentication”:
a) Go to your function apps and click on your function app (NOT on one of your functions inside your function app).
b) Click on Platform features and then on Authentication / Authorization.
c) Turn on “App Service Authentication”. Select “Log in with Azure Active Directory” and then click on “Azure Active Directory – Configured (Advanced)”.
Continue with Step-6.

Azure Active Directory Web Application without login current user

I am following an older tutorial (https://code.msdn.microsoft.com/Write-Sample-App-for-79e55502) that shows how to create a web application that connects to an Azure Active Directory tenant using ADAL. There is a class library that contains DirectoryService classes that I believe does the work in retrieving AD user properties. I am wanting to create a login method for this project for security purposes, and to be able to identify what user is logged in to the application. Currently there is not a signin method that authenticates against AD by entering a username/password, so I am a little puzzled at how the app can retrieve user properties with just the AppId,Domain,and AppSecret in the Web.config without actually having someone login with either their AD creds or redirecting to login.microsoftonline/{tenantId}.....I do not know if I am making sense, but I want to be able to add a login method so a user is forced to login so it gets the claims for that specific user but if I am already using ADAL, can I also incorporate Owin?
There are two parts to your question -
1. How is this app working today, without asking end users to explicitly sign in
This sample is using Client Credential Grant, in which you don't need end users to sign in, but use the identity of an application itself to get the auth token and use it for further operations. As you mention yourself, it just needs AppId, Domain and App Secret from web.config. You can read all about it here - Client Credentials Grant
Related code to acquire token is available in MVCDirectoryGraphSample\Helpers\MVCGraphServiceHelper.cs file
AuthenticationContext authenticationContext = new AuthenticationContext(authString);
ClientCredential clientCred = new ClientCredential(ConfigurationManager.AppSettings["AppPrincipalId"],
2. How to add a login method to force users to sign in to your web application
You can start using something like Authorization Code Grant flow, instead of client credentials. Look here for documentation on different scenarios that Azure AD supports. Your case looks like a web application calling Graph API, described here
Exact code sample to do this is available here - Code Samples

Resources