2

[I'm doing this in Xamarin, but I suspect the answer doesn't matter about that much as Xamarin exposes more or less the same API as the native Java]

I'm trying to learn OAuth and implement the Authorization Flow (no Implicit Grant). This involves opening the browser, doing the authentication and then not doing the key-exchange. You'd think this would be really easy. Here's what I have below.

The problem with this is that the browser page sticks around after the user logs in. How do I get it to go away?

public void Authenticate()
{
    var sb = new StringBuilder();
    sb.Append("https://accounts.google.com/o/oauth2/v2/auth");
    sb.Append("?client_id=<MY ID HERE>");
    sb.Append("&response_type=code");
    sb.Append("&scope=openid%20email");
    sb.Append("&redirect_uri=<MY PACKAGE NAME HERE>:/oauth2redirect");

    var url = sb.ToString();

    var uri = Android.Net.Uri.Parse("googlechrome://navigate?url=" + url);
    try
    {
        System.Diagnostics.Debug.WriteLine(uri.ToString());

        Intent i = new Intent(Intent.ActionView, uri);
        i.AddFlags(ActivityFlags.NewTask);
        i.AddFlags(ActivityFlags.SingleTop);
        i.AddFlags(ActivityFlags.ClearTop);
        i.AddFlags(ActivityFlags.NoHistory);
        Android.App.Application.Context.StartActivity(i);
    }
    catch (Exception ex)
    {
        System.Diagnostics.Debug.WriteLine(ex.Message);
    }
}

Related:

Is there any way in Android to force open a link to open in Chrome?

Redirect page doesn't automatically close after successful OAuth authorization

101010
  • 14,866
  • 30
  • 95
  • 172

2 Answers2

3

You are using Chrome, not a Chrome Custom Tab:

Example:

var sb = new StringBuilder()
    .Append("https://accounts.google.com/o/oauth2/v2/auth")
    .Append($"?client_id={clientID}")
    .Append("&response_type=code")
    .Append("&scope=https://www.googleapis.com/auth/drive")
    .Append($"&redirect_uri={PackageName}:/SushiRedirect");

var builder = new CustomTabsIntent.Builder(GetSession())
    .SetToolbarColor(Color.ParseColor(TOOLBAR_COLOR)).SetShowTitle(true)
    .SetStartAnimations(this, Resource.Animation.slide_in_right, Resource.Animation.slide_out_left)
    .SetExitAnimations(this, Resource.Animation.slide_in_left, Resource.Animation.slide_out_right)
    .SetCloseButtonIcon(BitmapFactory.DecodeResource(Resources, Resource.Drawable.ic_arrow_back));
var customTabsIntent = builder.Build();
CustomTabsHelper.AddKeepAliveExtra(this, customTabsIntent.Intent);
customTabsIntent.LaunchUrl(this, Uri.Parse(sb.ToString()));

And adding an Intent filter to a LaunchMode.SingleTask Activity to catch the redirect and "close" the Shared Tab. Your auth code will be in the Intent data (Intent?.Data?.ToString()):

[Activity(Label = "CustomTabsClient.Application", MainLauncher = true, Icon = "@drawable/ic_launcher", LaunchMode = LaunchMode.SingleTask)]
[IntentFilter(
    new[] { Intent.ActionView },
    Categories = new[] { Intent.CategoryDefault, Intent.CategoryBrowsable },
    DataScheme = "com.sushhangover.customtabsclient.example", DataPath = "/SushiRedirect")]

I have port of Google's Java Chrome Shared Tab demo and a nuget package of their shared library code to aid in the implementation of your own Shared Tab setup:

SushiHangover
  • 73,120
  • 10
  • 106
  • 165
0

I don't think you can force chrome to close, as it's not part of your application. However, you can register an intent filter for the callback url after the oauth flow and chrome should forward that intent back to your application.

Jon
  • 1,715
  • 12
  • 14
  • I have the part working where the redirect_uri comes back to my app and an intent filter picks it up. From that intent filter / activity back in my app, is there a way to ask Chrome to close that tab? – 101010 Sep 14 '17 at 17:34
  • Try using `SingleTask` instead of `SingleTop` when building your intent – Jon Sep 14 '17 at 17:55