msgraph-sdk-dotnet
msgraph-sdk-dotnet copied to clipboard
PageIterator seems to ignore request-options "WithAppOnly" on subsequent requests
I'm in the process of migrating some code from v4 to v5 and encounter the same bug while using the NextPageRequest (v4) in the PageIterator (v5).
I have to get the Access-Packages from our Azure AD using graph and this has to be done with "AppOnly" application permissions. For all other tasks, delegated permissions are needed so I don't have the Graph-Client injected with AppOnly in the first place.
So I just add the option "WithAppOnly()" to the request and all works well for the first request.
But as soon as the single-page limit is reached, in this case 100, the iterator kicks in and ignore the options from the request so the next call crashes with an unauthorized error because the request is done with the user-credentials instead.
Here's the entire function with some explanations to better understand the issue:
The behaviour is the same in the old v4 but there was an easy workaround to add the "WithAppOnly" to the "NextPageRequest".
Please show me how add the options to any subsequent request...I tried many workarounds but haven't found a working one yet.
private async Task<List<AccessPackage>> GetAccessPackagesAsync(
CancellationToken cancellationToken = default)
{
var accessPackages = new List<AccessPackage>();
var accessPackagesResponse = await _graphServiceClient
.IdentityGovernance
.EntitlementManagement
.AccessPackages
.GetAsync(requestConfiguration =>
{
requestConfiguration.QueryParameters.Expand = new[] { "assignmentPolicies" };
requestConfiguration.Options.WithAppOnly();
requestConfiguration.QueryParameters.Top = 999;
}, cancellationToken)
;
try
{
if (accessPackagesResponse != null)
{
var pageIterator = PageIterator<AccessPackage, AccessPackageCollectionResponse>.CreatePageIterator(
_graphServiceClient,
accessPackagesResponse, accessPackage =>
{
accessPackages.Add(accessPackage);
return true;
}
, subsequentRequest =>
{
// How to add ...WithAppOnly() to following request?
return subsequentRequest;
}
);
await pageIterator.IterateAsync(cancellationToken);
}
}
catch (Exception e)
{
Console.WriteLine(e);
throw;
}
// Working v4 code.
//IEntitlementManagementAccessPackagesCollectionPage? entitlementAccessPackages = null;
//while (entitlementAccessPackages is not { NextPageRequest: null })
//{
// var entitlementAccessPackagesRequest = entitlementAccessPackages?.NextPageRequest.WithAppOnly() ??
// _graphServiceClient
// .IdentityGovernance
// .EntitlementManagement
// .AccessPackages
// .Request()
// .Expand("assignmentPolicies")
// .WithAppOnly()
// .Top(999);
// entitlementAccessPackages = await entitlementAccessPackagesRequest
// .GetAsync(cancellationToken);
// accessPackages.AddRange(entitlementAccessPackages);
//}
return accessPackages;
}
Thanks for raising this @Jan1503,
Just to confirm, is WithAppOnly()
a custom method you have to update the Option collection?
Any chance it works out if you have the following request configurator?
subsequentRequest =>
{
subsequentRequest.RequestOptions.WithAppOnly(); // How to add ...WithAppOnly() to following request?
return subsequentRequest;
}
Alternatively, you can also call
subsequentRequest =>
{
subsequentRequest.AddRequestOptions( ... );// pass a list of IRequestOptions
return subsequentRequest;
}
No, WithAppOnly()
is an official extension method in Microsoft.Identity.Web.RequestOptionsExtension
.
It instructs the graph to use application-permissions for the next request instead of delegated-permissions.
As I said, the first request without the iterator works as expected but any subsequent requests fail, because the iterator ignores the request options configured in the first request.
This is also the case when using the "old" sdk as I have mentioned here without any reply: https://github.com/AzureAD/microsoft-identity-web/issues/2272
@andrueastman Hey, any news on this or a workaround? This stops me from updating my app!