Appcomplianceautomation report list pager returns 401
Opened this issue · 9 comments
Bug Report
- import path of package in question:
azure-sdk-for-go/sdk/resourcemanager/appcomplianceautomation/armappcomplianceautomation
- SDK version:
1.0.0
- output of
go version
:go version go1.22.4 darwin/arm64
- What happened?
- Creating the Report client using
armappcomplianceautomation.NewReportClient
- Creating the ListPager using
NewListPager
(with nil, empty, partially filled options) - Using the Pager to fetch the Reports
- Receiving an error:
"{"error":{"code":"invalid_access_token","message":"Invalid access token"}}"
- What did you expect or want to happen?
Expected to receive the reports, asaz acat report list
is working correctly using the same credentials - How can we reproduce it?
Try to use thearmappcomplianceautomation
sdk to receive the report list.
I've also tried using the previousv.0.3.0
version, but that one resulted in400 Bad Request
errors. - Anything we should know about your environment.
We're fetching multiple resources across a big amount of services, using the same configuration, I've checked that the provider is registered to the subscription we use, and there are existing reports.
Can you please provide which versions of azcore
and azidentity
you're using? And also which credential type from azidentity
you're using?
We're using azcore v1.16.0
and azidentity v1.8.0
. The credential type is DefaultAzureCredential
It will take some debugging to figure out what's going wrong here because there are several possible causes for a 401 from the resource. First thing to check is that your app gets tokens from the source you expect, which I take it is the Azure CLI. One way to do this is to enable logging as described in the README. Your listener will get a message like "DefaultAzureCredential authenticated with AzureCLICredential".
If AzureCLICredential provided the token, the next step is to examine the service request and 401 response:
- is the request authorized with an access token i.e., is the value of its Authorization header like
Bearer eyJ0...
? - the 401 should include a WWW-Authenticate header; what's that header's value?
You can also collect this information from logging, for example:
import (
azlog "github.com/Azure/azure-sdk-for-go/sdk/azcore/log"
)
azlog.SetListener(func(event azlog.Event, msg string) {
fmt.Println(msg)
})
azlog.SetEvents(azidentity.EventAuthentication, azlog.EventRequest, azlog.EventResponse)
client, err := armappcomplianceautomation.NewReportClient(todoCredential, &arm.ClientOptions{
ClientOptions: policy.ClientOptions{
Logging: policy.LogOptions{
// note that the value of Authorization is secret. Allow logging
// it only if you can ensure the security of your log output
AllowedHeaders: []string{"Authorization", "WWW-Authenticate"},
},
},
})
Hi @blesniewski. Thank you for opening this issue and giving us the opportunity to assist. To help our team better understand your issue and the details of your scenario please provide a response to the question asked above or the information requested above. This will help us more accurately address your issue.
- the request indeed has an Authorization Header beginning like you mentioned
eyJ0
. - I don't see a
WWW-Authenticate
header on the 401 response
As to logging the credentials authentication, I've had some issues doing it, but by checking using a debugger I can say that the credential chain used for creating the DefaultAzureCredential
has inside:
ManagedIdentityCredential
,AzureCLICredential
,AzureDeveloperCLICredential
. There are no errors logged during their init that might suggest there's anything wrong.EnvironmentCredential
andWorkloadIdentityCredential
, containing errors explaining why they couldn't be initialized.
The created Credential and BearerTokenPolicy
has a field successfulCredential
which is pointing to AzureCLICredential
when initializing the Reports
client
I've verified that I can fetch Operations
using armappcomplianceautomation.NewOperationsClient
and same credentials.
Are the Authorization headers of the failing report request and the successful operations request identical (they should be)?
We're fetching multiple resources across a big amount of services, using the same configuration
Are all these resources in the same tenant?
Hi @blesniewski. Thank you for opening this issue and giving us the opportunity to assist. To help our team better understand your issue and the details of your scenario please provide a response to the question asked above or the information requested above. This will help us more accurately address your issue.
Are the Authorization headers of the failing report request and the successful operations request identical (they should be)?
Auth headers are identical,
Are all these resources in the same tenant?
Yes
Thanks. I believe we can conclude that the credential and client are behaving correctly:
DefaultAzureCredential
acquires a valid ARM token- we know this because
OperationsClient
requests succeed
- we know this because
- the failing
ReportClient
request is authorized with a valid ARM token- we know this because its Authorization header is identical to that of the successful
OperationsClient
request (this is expected; same audience, same token)
- we know this because its Authorization header is identical to that of the successful
I asked whether the resources are in the same tenant because there is a cross-tenant auth feature for ARM which I guess could produce this behavior if your ReportClient
request involved resources in multiple tenants. If it did, the request would need an access token for each tenant in its x-ms-authorization-auxiliary
header and you would need to set the ClientOptions.AuxiliaryTenants field when constructing the client. But this is irrelevant if the resources are all in the same tenant.
We've hit the limit of my knowledge here, so let me add @lirenhe for more guidance. The only thing I can think of that might be helpful at this point is to compare requests sent by az acat report list
to those sent by your ReportClient
. If they use the same REST API, the difference between success and failure should be in those requests.