101010
101010

Reputation: 15726

How to open and then automatically-close the OAuth page in Chrome on Android?

[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

Upvotes: 2

Views: 2876

Answers (2)

SushiHangover
SushiHangover

Reputation: 74144

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:

Upvotes: 3

Jon
Jon

Reputation: 1763

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.

Upvotes: 0

Related Questions