Skip to content

ImdsManagedIdentitySource (Managed Identity authentication) exception when parsing the identity endpoint response #4723

@v-mkmiecik

Description

@v-mkmiecik

Describe the bug
Hello,

I'm hitting an issue with the Managed Identity authentication (ManagedIdentityCredential class). I'm getting the following exception when trying to obtain an access token:
GetToken(): [json.exception.type_error.302] type must be number, but is string

The exception comes from the TokenCredentialImpl::ParseToken method in token_credential_impl.cpp when trying to obtain the expiresInPropertyName value from parsed json. It looks like the code expects json to contain a number, but the identity endpoint to which the request is sent returns a string instead.

Exception or Stack Trace
OLEDB sandbox.exe!Azure::Identity::_detail::TokenCredentialImpl::GetToken'::1'::catch$20() Line 136 C++
[External Code]
OLEDB sandbox.exe!Azure::Identity::_detail::TokenCredentialImpl::GetToken(const Azure::Core::Context & context, const std::function<std::unique_ptr<Azure::Identity::_detail::TokenCredentialImpl::TokenRequest,std::default_deleteAzure::Identity::_detail::TokenCredentialImpl::TokenRequest> __cdecl(void)> & createRequest, const std::function<std::unique_ptr<Azure::Identity::_detail::TokenCredentialImpl::TokenRequest,std::default_deleteAzure::Identity::_detail::TokenCredentialImpl::TokenRequest> __cdecl(enum Azure::Core::Http::HttpStatusCode,Azure::Core::Http::RawResponse const &)> & shouldRetry) Line 125 C++
OLEDB sandbox.exe!Azure::Identity::_detail::ImdsManagedIdentitySource::GetToken::__l2::<lambda_1>::operator()() Line 360 C++
[External Code]
OLEDB sandbox.exe!Azure::Identity::_detail::TokenCache::GetToken(const std::string & scopeString, std::chrono::duration<__int64,std::ratio<1,10000000>> minimumExpiration, const std::function<Azure::Core::Credentials::AccessToken __cdecl(void)> & getNewToken) Line 116 C++
OLEDB sandbox.exe!Azure::Identity::_detail::ImdsManagedIdentitySource::GetToken(const Azure::Core::Credentials::TokenRequestContext & tokenRequestContext, const Azure::Core::Context & context) Line 359 C++
OLEDB sandbox.exe!Azure::Identity::ManagedIdentityCredential::GetToken(const Azure::Core::Credentials::TokenRequestContext & tokenRequestContext, const Azure::Core::Context & context) Line 60 C++
OLEDB sandbox.exe!main() Line 46 C++

To Reproduce
The client application is very simple:
Azure::Core::Context context; Azure::Core::Credentials::TokenRequestContext tokenRequestContext; Azure::Core::Credentials::AccessToken accessToken; tokenRequestContext.Scopes.push_back("https://database.windows.net"); Azure::Identity::ManagedIdentityCredential managedIdentityCredential; try { accessToken = managedIdentityCredential.GetToken(tokenRequestContext, context); } catch (const std::exception& e) { std::cout << "Exception caught: " << e.what() << std::endl; }
Please note that variables such as MSI_ENDPOINT, MSI_SECRET, IDENTITY_ENDPOINT, IDENTITY_HEADER are not defined in my environment, so the CreateManagedIdentitySource function (managed_identity_credential.cpp) uses the ImdsManagedIdentitySource implementation which targets the "http://169.254.169.254/metadata/identity/oauth2/token" endpoint.

Expected behavior
The library should be able to correctly parse the json response from the identity endpoint.

Setup (please complete the following information):

  • OS: Windows
  • IDE : Visual Studio
  • 1.4.0

Additional context
The example response from the endpoint is as follows:
{ "access_token": "...", "client_id": "...", "expires_in": "84671", "expires_on": "1687364401", "ext_expires_in": "86399", "not_before": "1687277701", "resource": "https://database.windows.net", "token_type": "Bearer" }

Please note that the "expires_in" property has a string value.
Here's another response when using the ClientSecretCredential class (different endpoint):
{ "token_type": "Bearer", "expires_in": 86399, "ext_expires_in": 86399, "access_token": "..." }

In this case, the "expires_in" value is a number (which is what the TokenCredentialImpl::ParseToken method expects).

Information Checklist

  • Bug Description Added
  • Repro Steps Added
  • Setup information Added

Metadata

Metadata

Assignees

Labels

Azure.IdentityClientThis issue points to a problem in the data-plane of the library.customer-reportedIssues that are reported by GitHub users external to the Azure organization.needs-team-triageWorkflow: This issue needs the team to triage.questionThe issue doesn't require a change to the product in order to be resolved. Most issues start as that

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions