Using Cognito Federated Identities from Xamarin

大憨熊 提交于 2019-12-08 12:13:37

问题


I guess my question, Understanding Cognito Identities, wasn't specific enough. I still can't figure out how to use a federated identity from a Xamarin app. Here's what I'm trying, but it's really quite random because I can't find any sample code for this task out there. I tried putting a breakpoint on the AddLogin line, and it never gets hit, even though breakpoint two lines up does get hit. There are too many new-to-me technologies in this code for me to know where to begin on tracking down the problem. (I x'd out the Identity pool ID in the code below, but a real one is there.) At this point I'm just trying to get evidence that I can uniquely identify/validate an Amazon account, and maybe add it to my user pool. But I can't even get the code to entirely execute or report an error.

Login().ContinueWith(t => { if (t.Exception != null) 
    Toast.MakeText(ApplicationContext, t.Exception.ToString(), ToastLength.Long).Show(); });

public async Task Login()
{
   CognitoAWSCredentials credentials = new CognitoAWSCredentials(
       "us-east-2:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", // Identity pool ID
       RegionEndpoint.USEast2 // Region
   );

   var client = new Amazon.SecurityToken.AmazonSecurityTokenServiceClient(credentials);
   var request = new Amazon.SecurityToken.Model.GetFederationTokenRequest("myamazonid@gmail.com");
   var response = await client.GetFederationTokenAsync(request);
   credentials.AddLogin("www.amazon.com", response.Credentials.SessionToken);
}

回答1:


It took a good deal of searching, but I think I figured it out. Setting up the services and getting the client ID is not too hard (is well documented) compared to working out the code, so this answer will focus on the code. Google is particularly tricky because of changes made to their OAuth implementation that prevents some forms of authentication from working. In order for Google identities to work with Cognito, APIs need to be up-to-date. Use NuGet to reference the following API versions or later:

  • Xamarin.Auth 1.5.0.3
  • Xamarin.Android.Support.v4 25.4.0.2
  • Xamarin.Android.Support.CustomTabs 25.4.0.2
  • AWSSDK.CognitoIdentity 3.3.2.14
  • AWSSDK.Core 3.3.17.8
  • Validation 2.4.15
  • Xamarin.Android.Support.Annotations 25.4.0.2

This code is in the main activity:

protected override void OnCreate(Bundle savedInstanceState)
{
    // (etc)
    credentials = new CognitoAWSCredentials(
       "us-east-2:00000000-0000-0000-0000-000000000000", // Identity pool ID
       RegionEndpoint.USEast2 // Region
    );
    // (etc)
}

private void ShowMessage(string message)
{
  AlertDialog dlgAlert = new AlertDialog.Builder(this).Create();
  dlgAlert.SetMessage(message);
  dlgAlert.SetButton("Close", (s, args) => { dlgAlert.Dismiss(); });
  dlgAlert.Show();
}

public void Logout()
{
  credentials.Clear();
}

public void Login()
{
  if (!string.IsNullOrEmpty(credentials.GetCachedIdentityId()) || credentials.CurrentLoginProviders.Length > 0)
  {
     if (!bDidLogin)
        ShowMessage(string.Format("I still remember you're {0} ", credentials.GetIdentityId()));
     bDidLogin = true;
     return;
  }

  bDidLogin = true;
  auth = new Xamarin.Auth.OAuth2Authenticator(
     "my-google-client-id.apps.googleusercontent.com",
     string.Empty,
     "openid",
     new System.Uri("https://accounts.google.com/o/oauth2/v2/auth"),
     new System.Uri("com.mynamespace.myapp:/oauth2redirect"),
     new System.Uri("https://www.googleapis.com/oauth2/v4/token"),
     isUsingNativeUI: true);

  auth.Completed += Auth_Completed;
  StartActivity(auth.GetUI(this));
}

private void Auth_Completed(object sender, Xamarin.Auth.AuthenticatorCompletedEventArgs e)
{
  if (e.IsAuthenticated)
  {
     var http = new System.Net.Http.HttpClient();
     var idToken = e.Account.Properties["id_token"];

     credentials.AddLogin("accounts.google.com", idToken);
     AmazonCognitoIdentityClient cli = new AmazonCognitoIdentityClient(credentials, RegionEndpoint.USEast2);
     var req = new Amazon.CognitoIdentity.Model.GetIdRequest();
     req.Logins.Add("accounts.google.com", idToken);
     req.IdentityPoolId = "us-east-2:00000000-0000-0000-0000-000000000000";
     cli.GetIdAsync(req).ContinueWith((task) =>
     {
        if ((task.Status == TaskStatus.RanToCompletion) && (task.Result != null))
           ShowMessage(string.Format("Identity {0} retrieved", task.Result.IdentityId));
        else
           ShowMessage(task.Exception.InnerException!=null ? task.Exception.InnerException.Message : task.Exception.Message);
     });
  }
  else
     ShowMessage("Login cancelled");
}

Then there's another activity to handle the callback from the redirect URL in the Google authentication process:

[Activity(Label = "GoodleAuthInterceptor")]
[IntentFilter(actions: new[] { Intent.ActionView }, Categories = new[] { Intent.CategoryDefault, Intent.CategoryBrowsable },
  DataSchemes = new[] { "com.mynamespace.myapp" }, DataPaths = new[] { "/oauth2redirect" })]
public class GoodleAuthInterceptor : Activity
{
  protected override void OnCreate(Bundle savedInstanceState)
  {
     base.OnCreate(savedInstanceState);
     Android.Net.Uri uri_android = Intent.Data;
     Uri uri_netfx = new Uri(uri_android.ToString());
     MainActivity.auth?.OnPageLoading(uri_netfx);
     Finish();
  }
}


来源:https://stackoverflow.com/questions/46065300/using-cognito-federated-identities-from-xamarin

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!