-
Notifications
You must be signed in to change notification settings - Fork 863
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Type initializer for ChecksumUtils threw an exception (only on iOS in Release mode for an MAUI App) #3689
Comments
We did make a change to the checksum functionality recently, but it was only meant to impact S3. Is there a stack trace you can share? I'm curious on why Cognito would cause the checksum code path to be executed. |
@pbru87 Good morning. Are you also using the high-level Cognito library https://github.com/aws/aws-sdk-net-extensions-cognito? We compute GetUserPoolSecretHash, but unsure how it would be as a result in Checksum changes in AWS .NET SDK. Below code works fine on Windows: <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net9.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Amazon.Extensions.CognitoAuthentication" Version="2.5.5" />
<PackageReference Include="AWSSDK.CognitoIdentity" Version="3.7.402.25" />
<PackageReference Include="AWSSDK.CognitoIdentityProvider" Version="3.7.407" />
</ItemGroup>
</Project> Program.cs using Amazon.CognitoIdentityProvider;
using Amazon.Extensions.CognitoAuthentication;
using Amazon.Runtime;
using System.Text;
string userPoolId;
string clientId;
string clientSecret;
const int BufferSize = 10000;
Console.SetIn(new StreamReader(Console.OpenStandardInput(), Encoding.UTF8, false, BufferSize));
Console.Write("Enter User Pool ID: ");
userPoolId = Console.ReadLine();
Console.Write("Enter Client ID: ");
clientId = Console.ReadLine();
Console.Write("Enter Client Secret: ");
clientSecret = Console.ReadLine();
bool reexecuteFlow = false;
do
{
Console.Write("User Name: ");
string userName = Console.ReadLine();
while (string.IsNullOrWhiteSpace(userName))
{
Console.Write("Please enter a valid User Name: ");
userName = Console.ReadLine();
}
Console.Write("Do you have a Refresh Token (Y/N): ");
char hasRefreshTokenResponse = Convert.ToChar(Console.ReadLine());
bool hasRefreshToken = (char.ToLower(hasRefreshTokenResponse) == 'y');
Console.WriteLine();
string passwordOrRefreshToken;
if (!hasRefreshToken)
{
Console.Write("Password: ");
passwordOrRefreshToken = Console.ReadLine();
while (string.IsNullOrWhiteSpace(passwordOrRefreshToken))
{
Console.Write("Please enter a valid Password: ");
passwordOrRefreshToken = Console.ReadLine();
}
}
else
{
Console.Write("Existing Refresh Token: ");
passwordOrRefreshToken = Console.ReadLine();
while (string.IsNullOrWhiteSpace(passwordOrRefreshToken))
{
Console.Write("Please enter a valid Refresh Token: ");
passwordOrRefreshToken = Console.ReadLine();
}
}
Console.WriteLine("\nExecuting {0} auth flow.", (hasRefreshToken ? "Refresh Token" : "Username/Password"));
#pragma warning disable CS8604 // Possible null reference argument.
AuthFlowResponse authFlowResponse = (hasRefreshToken ? GetCredsFromRefreshAsync(userName, passwordOrRefreshToken, userPoolId, clientId, clientSecret).GetAwaiter().GetResult() : GetCredentials(userName, passwordOrRefreshToken, userPoolId, clientId, clientSecret).GetAwaiter().GetResult());
#pragma warning restore CS8604 // Possible null reference argument.
Console.WriteLine("ID Token: {0}\nAccess Token {1}\nRefresh Token: {2}", authFlowResponse.AuthenticationResult.IdToken, authFlowResponse.AuthenticationResult.AccessToken, authFlowResponse.AuthenticationResult.RefreshToken);
Console.Write("\n\nRe-execute Flow (Y/N): ");
char reexecuteFlowResponse = Convert.ToChar(Console.ReadLine());
reexecuteFlow = (char.ToLower(reexecuteFlowResponse) == 'y');
} while (reexecuteFlow);
static async Task<AuthFlowResponse> GetCredentials(string userName, string password, string userPoolId, string clientId, string clientSecret)
{
var provider = new AmazonCognitoIdentityProviderClient(new AnonymousAWSCredentials(), FallbackRegionFactory.GetRegionEndpoint());
var userPool = new CognitoUserPool(userPoolId, clientId, provider, clientSecret);
var user = new CognitoUser(userName, clientId, userPool, provider, clientSecret);
AuthFlowResponse authResponse = await user.StartWithSrpAuthAsync(new InitiateSrpAuthRequest()
{
Password = password
}).ConfigureAwait(false);
while (authResponse.AuthenticationResult == null)
{
if (authResponse.ChallengeName == ChallengeNameType.NEW_PASSWORD_REQUIRED)
{
Console.WriteLine("Enter your desired new password: ");
string newPassword = Console.ReadLine();
authResponse = await user.RespondToNewPasswordRequiredAsync(new RespondToNewPasswordRequiredRequest()
{
SessionID = authResponse.SessionID,
NewPassword = newPassword
});
}
else if (authResponse.ChallengeName == ChallengeNameType.SMS_MFA)
{
Console.WriteLine("Enter the MFA Code sent to your device: ");
string mfaCode = Console.ReadLine();
authResponse = await user.RespondToSmsMfaAuthAsync(new RespondToSmsMfaRequest()
{
SessionID = authResponse.SessionID,
MfaCode = mfaCode
}).ConfigureAwait(false);
}
else
{
Console.WriteLine("Unrecognized authentication challenge.");
return null;
}
}
return authResponse;
}
static async Task<AuthFlowResponse> GetCredsFromRefreshAsync(string userName, string refreshToken, string userPoolId, string clientId, string clientSecret)
{
AmazonCognitoIdentityProviderClient provider = new AmazonCognitoIdentityProviderClient(new AnonymousAWSCredentials(), FallbackRegionFactory.GetRegionEndpoint());
CognitoUserPool userPool = new CognitoUserPool(userPoolId, clientId, provider, clientSecret);
CognitoUser user = new CognitoUser(userName, clientId, userPool, provider, clientSecret);
user.SessionTokens = new CognitoUserSession(null, null, refreshToken, DateTime.Now, DateTime.Now.AddHours(1));
InitiateRefreshTokenAuthRequest refreshRequest = new InitiateRefreshTokenAuthRequest()
{
AuthFlowType = AuthFlowType.REFRESH_TOKEN_AUTH
};
return await user.StartWithRefreshTokenAuthAsync(refreshRequest).ConfigureAwait(false);
} As @dscpinheiro requested, please share the stack trace to troubleshoot the issue. Thanks, |
Hi @dscpinheiro, hi @ashishdhingra, Thanks for your quick replies! @ashishdhingra: That the code works under Windows and without issues is expected (see my above issue description). Issue is only on iOS (Release mode). @ashishdhingra: Yes, we also use the NuGet packages AWSSDK.CognitoIdentity and AWSSDK.CognitoIdentityProvider.
@dscpinheiro, @ashishdhingra: Here comes the StackTrace (for the exception message "TypeInitialization_Type, Amazon.Runtime.Internal.Util.ChecksumUtils")...
|
Thanks for the stack trace. I suspect the issue is happening because we try to check if the AWS Common Runtime dependency is available:
We're only checking for |
@dscpinheiro: Thanks for the feedback! For now it's fine for us to use older versions of the NuGet package (as there is currently no downside to do so) - and we will be very happy when this issue will be addressed in a recent update. 🙂 |
@pbru87 Would you be able to try the latest versions of the They include an update to the |
@dscpinheiro We tested today with exactly the package versions, you mentioned - and it works again, like a charm 🎉 - Thank you very much for this very fast fix! Much appreciated. 🙂 - As it is fixed, I herebey also close this issue. |
Comments on closed issues are hard for our team to see. |
Describe the bug
We have a MAUI app (for Android and iOS), where users can sign in. Our CIAM provider is AWS Cognito. Users can sign in via email address/password or via Federated Identity (Apple, Google).
That used to work just fine, but when we upgraded our AWS NuGet packages to newer versions, the email/password login seems to work no more. Instead we get the following error message "The type initializer for 'Amazon.Runtime.Internal.Util.ChecksumUtils' threw an exception."
This exception seems to be thrown when we call the following method (probably on
StartWithSrpAuthAsync
):For some reason, that error only occurs in the "Release" version for iOS. - Android is not affected at all. - Works also just fine when called from a simple app like a console application. - In "Debug" mode it also works just fine for iOS. - Therefore, we assume that it might be related to AOT-compatibility and trimming (which seems to be used for iOS releases already, but is somewhat in beta for Android still).
What else?
Regression Issue
Expected Behavior
Sign-in via
StartWithSrpAuthAsync
method throws no exception (for "Release" mode on iOS), but succeeds and returns a validAuthFlowResponse
(as in previous AWSSDK.Core versions).Current Behavior
Sign-in via
StartWithSrpAuthAsync
method throws the following exception (for "Release" mode on iOS): "The type initializer for 'Amazon.Runtime.Internal.Util.ChecksumUtils' threw an exception."Reproduction Steps
Possible Solution
Re-check your latest changes in class 'Amazon.Runtime.Internal.Util.ChecksumUtils'. (Current issue might be related to AOT-compatibility and trimming,)
Additional Information/Context
Problem only occurs in "Release" mode on iOS. ("Debug" mode and Android/Linux/Windows not affected).
AWS .NET SDK and/or Package version used
AWSSDK.Core 3.7.402.4 or AWSSDK.Core 4.0.0-preview.8 => Exception occurs with both versions.
Targeted .NET Platform
.NET 9.0
Operating System and version
iOS
The text was updated successfully, but these errors were encountered: