Getting passwordPolicies as null always in Microsoft graph API 1.0 - azure-active-directory

I'm Using Microsoft Graph API Version 1.0
I need to fetch the password expiry time configured in the Azure Active Directory for users using the graph API.
I'm used the https://developer.microsoft.com/en-us/graph/graph-explorer.
In the admin.microsoft.com the configured value is 14 days for password expiry. But, Graph API returns null value. But if we configure the password as never expires, Graph API is returning as DisablePasswordExpiration
The API I have requested in Graph Explorer is
GET https://graph.microsoft.com/v1.0/me?$select=passwordPolicies

There is no way how to get password validity period from Graph API.
What you can read is the time when the users last changed their password or when their password was created.
You need to call beta API.
GET https://graph.microsoft.com/beta/me?$select=lastPasswordChangeDateTime
Response
{
"#odata.context": "https://graph.microsoft.com/beta/$metadata#users(lastPasswordChangeDateTime)/$entity",
"lastPasswordChangeDateTime": "2022-05-10T10:31:55Z"
}

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.

How the AAD token is refreshed after expiry?

I am working on a SDK where we send telemetry(1000s of events/minute) to Ingestion Service owned by Microsoft.(SDK is used by webapps hosted on Azure VMS or App services) The Ingestion Service currently support authentication using Managed Identities (both system and user assigned). My idea is to take a dependency on the Azure Identity SDK and use the existing DefaultAzureCredential or ManagedIdentityCredential implementations of 'TokenCredential' to get the tokens as shown below and Use this defaultCredential while initializing the sdk. Once I have the sdk initialized my idea is to get the token and attach to authorization header on each request.
DefaultAzureCredential defaultCredential = new DefaultAzureCredentialBuilder()
.managedIdentityClientId("<MANAGED_IDENTITY_CLIENT_ID>")
.build();
Questions:
How frequently are the tokens refreshed? How to control the expiry of these tokens?
When the token is expired, are the managed Identities smart enough to call the AAD and get new tokens. Or is it the SDKs(client) responsibility to get a new token and update the header.
In my opinion, the token won't be refreshed automatically, and if you wanna know the expired time, you could use tools like fiddler to catch the request which used the token and use jwo.io to decode it, you will get a claim of 'exp', it's a unix timestamp, you can convert it then you can know the expire time.
And the expire time is managed by the policy of your tenant, you can follow the tutorial to create a policy for your access token. And because your code just new DefaultAzureCredential(), any time execute the line, it will generate a new instance so that you don't worry about the token expired.

Azure client credentials grant oath not working in hybrid setup for Graph Mail API access

In hybrid setup if client credentials grant type is used to get token and if that token is used to get on-prem user messages (https://graph.microsoft.com/v1.0/users('onpremuser#onpremdomain.com')/messages/) using graph api it fails by providing UnknownError.
When debugged on IIS logs error shown was "This token profile 'V1S2SAppOnly' is not applicable for the current protocol." error_category="invalid_token".
However if authorization code grant or resource owner password credential (ROPC) grant if used to obtain token , we were able to get messages of on prem user using graph API.
Have attached screenshot of token for both. How to make client credentials grant work for on-prem user messages access using graph API (in hybrid setup) ?
Update
Update i went and edited web.config of rest in Exchange server to have V1S2SAppOnly in profiles. After that previous error is gone and new error is seen.
Bearer+client_id="00000002-0000-0ff1-ce00-000000000000",+trusted_issuers="00000001-0000-0000-c000-000000000000#ea6064aa-d6fc-48d3-abb8-1728e1f39e0b",+token_types="app_asserted_user_v1+service_asserted_app_v1",+error="invalid_token" 2000008;reason="The+token+should+have+valid+permissions+or+linked+account+associated+with+partner+application+'00000003-0000-0000-c000-000000000000'.";error_category="invalid_grant"
I think the problem is with the aud claim, i.e. the audience for token.
For the first token that you have shared
aud value is 00000002-0000-0000-c000-000000000000. This is the resource Id for Azure AD Graph API and not Microsoft Graph API. For Microsoft Graph API, you should be using https://graph.microsoft.com or Id 00000003-0000-0000-c000-000000000000
this token is probably the one where you used client credentials grant, as there isn't any user claim
For the second token that you have shared
aud value is https://graph.microsoft.com which is correct
this token is acquired in context of a user name anoop so I guess this is the one which is working for you.
What you want is:
Application with Client credentials => Graph API => Local Exchange.
This scenario isn't supported out-of-the-box, but you can however tell your local exchange server to accept those tokens. See this answer https://stackoverflow.com/a/56131954/639153
In a nutshell, you need to change the authentication config of your front-end exchange servers to accept client credentials from the graph api. By default only delegated credentials are supported, and these settings are not documented on the exchange side.
Warning, we tested these settings, and it's working but not supported by Microsoft
This is the blog where I've found the answer to your question. https://blog.thenetw.org/2019/05/13/using-client_credentials-with-microsoft-graph-in-hybrid-exchange-setup/

How to get all users in active directory via Microsoft Graph - React?

Hey I am a beginner in React and Graph.
To explain, I have to create a little web site in React using Microsoft Graph to get Active Directory data ( like all the users and their information of the company which uses AAD ).
I am actually a little lost of how I can get this list of users.
Can you help me ?
Once logged into your app that have proper access right to read all users data, you should be able to retrieve users with a http get on that url
GET https://graph.microsoft.com/v1.0/users
Don't forget to add bearer token in your HTTP headers.
To get users in azure AD, you can call the List Users GET HTTP request.
GET https://graph.microsoft.com/v1.0/users
To get the number of users returned you can use the $top query parameter to specify the page size of the result set. See docs here.
https://learn.microsoft.com/en-us/graph/query-parameters#top-parameter
GET https://graph.microsoft.com/v1.0/users?$top=200

Client Credentials access token not working office 365

I am using client credentials flow to generate an access token. Following is the request.
I received the access token and I am using to call Web API like
https://graph.microsoft.com/v1.0/me/mailfolders/inbox/messages
Following is the screenshot
Calling Web API gives InvalidAuthenticationToken Error.
Any workaround on this.?
You're resource should be set to https://graph.microsoft.com.
In your screenshot, theresource is set to https://outlook.office.com but you're calling a Microsoft Graph. Since you're providing an access_token for a different resource, Microsoft Graph is rejecting it.
You also need to make sure you've requested the proper Microsoft Graph permissions in the Azure Portal. To call /mailFolders/inbox/messages for example, you need request permission for either Mail.Read or Mail.ReadWrite.
Finally, you cannot use /me with the Client Credentials grant. The /me is simply shorthand for /users/{current-user-id}/. Since Client Credentials does not have a current user, the API has no idea which user me is. You will need to reference a specific user entity in the path:
/v1.0/users/{userPrincipalName}/mailfolders/inbox/messages

Resources