AWSClientAuthCognitoCachingAuthenticatedCredentialsProvider.cpp 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. /*
  2. * Copyright (c) Contributors to the Open 3D Engine Project.
  3. * For complete copyright and license terms please see the LICENSE at the root of this distribution.
  4. *
  5. * SPDX-License-Identifier: Apache-2.0 OR MIT
  6. *
  7. */
  8. #include <Authorization/AWSClientAuthCognitoCachingAuthenticatedCredentialsProvider.h>
  9. #include <AzCore/Debug/Trace.h>
  10. #include <aws/cognito-identity/CognitoIdentityClient.h>
  11. #include <aws/cognito-identity/model/GetCredentialsForIdentityRequest.h>
  12. #include <aws/cognito-identity/model/GetIdRequest.h>
  13. #include <aws/core/utils/Outcome.h>
  14. #include <aws/core/utils/logging/LogMacros.h>
  15. #include <aws/identity-management/auth/CognitoCachingCredentialsProvider.h>
  16. #include <aws/identity-management/auth/PersistentCognitoIdentityProvider.h>
  17. namespace AWSClientAuth
  18. {
  19. static const char* AUTH_LOG_TAG = "AWSClientAuthCognitoCachingAuthenticatedCredentialsProvider";
  20. static const char* ANON_LOG_TAG = "AWSClientAuthCachingAnonymousCredsProvider";
  21. // Modification of https://github.com/aws/aws-sdk-cpp/blob/main/aws-cpp-sdk-identity-management/source/auth/CognitoCachingCredentialsProvider.cpp#L92
  22. // to work around account ID requirement. Account id is not required for call to succeed and is not set unless provided.
  23. // see: https://github.com/aws/aws-sdk-cpp/issues/1448
  24. Aws::CognitoIdentity::Model::GetCredentialsForIdentityOutcome FetchCredsFromCognito(
  25. const Aws::CognitoIdentity::CognitoIdentityClient& cognitoIdentityClient,
  26. Aws::Auth::PersistentCognitoIdentityProvider& identityRepository,
  27. const char* logTag,
  28. bool includeLogins)
  29. {
  30. auto logins = identityRepository.GetLogins();
  31. Aws::Map<Aws::String, Aws::String> cognitoLogins;
  32. for (auto& login : logins)
  33. {
  34. cognitoLogins[login.first] = login.second.accessToken;
  35. }
  36. if (!identityRepository.HasIdentityId())
  37. {
  38. Aws::CognitoIdentity::Model::GetIdRequest getIdRequest;
  39. // Only call SetIdentityPoolId if there's actually a pool id.
  40. // SetIdentityPoolId will cause AWS to think there's an id even if it's empty.
  41. // This leads AWS API calls to pass back a warning about an "invalid" pool id,
  42. // rather than (properly) passing back an error about not having a pool id.
  43. const Aws::String identityPoolId = identityRepository.GetIdentityPoolId();
  44. if (!identityPoolId.empty())
  45. {
  46. getIdRequest.SetIdentityPoolId(identityPoolId);
  47. }
  48. auto accountId = identityRepository.GetAccountId();
  49. if (!accountId.empty())
  50. {
  51. getIdRequest.SetAccountId(accountId);
  52. AWS_LOGSTREAM_INFO(logTag, "Identity not found, requesting an id for accountId "
  53. << accountId << " identity pool id "
  54. << identityPoolId << " with logins.");
  55. }
  56. else
  57. {
  58. AWS_LOGSTREAM_INFO(
  59. logTag, "Identity not found, requesting an id for identity pool id %s" << identityPoolId << " with logins.");
  60. }
  61. if (includeLogins)
  62. {
  63. getIdRequest.SetLogins(cognitoLogins);
  64. }
  65. auto getIdOutcome = cognitoIdentityClient.GetId(getIdRequest);
  66. if (getIdOutcome.IsSuccess())
  67. {
  68. auto identityId = getIdOutcome.GetResult().GetIdentityId();
  69. AWS_LOGSTREAM_INFO(logTag, "Successfully retrieved identity: " << identityId);
  70. identityRepository.PersistIdentityId(identityId);
  71. }
  72. else
  73. {
  74. AWS_LOGSTREAM_ERROR(
  75. logTag,
  76. "Failed to retrieve identity. Error: " << getIdOutcome.GetError().GetExceptionName() << " "
  77. << getIdOutcome.GetError().GetMessage());
  78. return Aws::CognitoIdentity::Model::GetCredentialsForIdentityOutcome(getIdOutcome.GetError());
  79. }
  80. }
  81. Aws::CognitoIdentity::Model::GetCredentialsForIdentityRequest getCredentialsForIdentityRequest;
  82. getCredentialsForIdentityRequest.SetIdentityId(identityRepository.GetIdentityId());
  83. if (includeLogins)
  84. {
  85. getCredentialsForIdentityRequest.SetLogins(cognitoLogins);
  86. }
  87. return cognitoIdentityClient.GetCredentialsForIdentity(getCredentialsForIdentityRequest);
  88. }
  89. AWSClientAuthCognitoCachingAuthenticatedCredentialsProvider::AWSClientAuthCognitoCachingAuthenticatedCredentialsProvider(
  90. const std::shared_ptr<Aws::Auth::PersistentCognitoIdentityProvider>& identityRepository,
  91. const std::shared_ptr<Aws::CognitoIdentity::CognitoIdentityClient>& cognitoIdentityClient)
  92. : CognitoCachingCredentialsProvider(identityRepository, cognitoIdentityClient)
  93. {
  94. }
  95. Aws::CognitoIdentity::Model::GetCredentialsForIdentityOutcome
  96. AWSClientAuthCognitoCachingAuthenticatedCredentialsProvider::GetCredentialsFromCognito() const
  97. {
  98. return FetchCredsFromCognito(*m_cognitoIdentityClient, *m_identityRepository, AUTH_LOG_TAG, true);
  99. }
  100. AWSClientAuthCachingAnonymousCredsProvider::AWSClientAuthCachingAnonymousCredsProvider(
  101. const std::shared_ptr<Aws::Auth::PersistentCognitoIdentityProvider>& identityRepository,
  102. const std::shared_ptr<Aws::CognitoIdentity::CognitoIdentityClient>& cognitoIdentityClient)
  103. : AWSClientAuthCognitoCachingAuthenticatedCredentialsProvider(identityRepository, cognitoIdentityClient)
  104. {
  105. }
  106. Aws::CognitoIdentity::Model::GetCredentialsForIdentityOutcome AWSClientAuthCachingAnonymousCredsProvider::
  107. GetCredentialsFromCognito() const
  108. {
  109. return FetchCredsFromCognito(*m_cognitoIdentityClient, *m_identityRepository, ANON_LOG_TAG, false);
  110. }
  111. } // namespace AWSClientAuth