xamarin / Xamarin.Auth

Xamarin.Auth
Apache License 2.0
542 stars 350 forks source link

Browser doesn't close itself on Android with native renderers #226

Open zati- opened 7 years ago

zati- commented 7 years ago

Xamarin.Auth Issue

IF BUG, INCLUDE THIS PART:

Version

Steps to reproduce

Call OAuth2Autenticator on Android with native renderers, using presenter or AuthenticatorPage. Custom URL scheme is registered

     OAuth2Authenticator authenticator = new OAuth2Authenticator(
              "mobile",
              "secret",
              "openid profile api1",
              new Uri(Settings.Server + "/connect/authorize"),
              new Uri("myapplogin://localhost/oauth2redirect"),
              new Uri(Settings.Server + "/connect/token"),
              null,
              true);
            authenticator.Completed += Authenticator_Completed;
            var presenter = new Xamarin.Auth.Presenters.OAuthLoginPresenter();
            presenter.Login(authenticator);

` Custom URL scheme interceptor Activity andAuthenticator_Completed` are called.

Platform:

Expected behaviour

Web browser should close itself after authentication

Actual behaviour

The web browser doesn't close itself after authentication. This is working well on IOS (both native and not) and on Android when isUsingNativeUi=false

image

VS bug #733077, VS bug #1057144

moljac commented 7 years ago

@zati- I need more info: decl/def of Activity with IntentFilter.

zati- commented 7 years ago
[Activity(Label = "CustomUrlSchemeInterceptorActivity", NoHistory = true, LaunchMode = LaunchMode.SingleTop)]
    [IntentFilter(
    new[] { Intent.ActionView },
    Categories = new[] { Intent.CategoryDefault, Intent.CategoryBrowsable },
    DataSchemes = new[] { "myapplogin" })]
    public class CustomUrlSchemeInterceptorActivity : Activity
    {
        protected override void OnCreate(Bundle savedInstanceState)
        {
            base.OnCreate(savedInstanceState);

            // Convert Android.Net.Url to Uri
            var uri = new Uri(Intent.Data.ToString());

            // Load redirectUrl page
            AuthenticationState.Authenticator.OnPageLoading(uri);

            Finish();
        }
    }
kylewhittington commented 6 years ago

Having the same issue, but using Google to authenticate. I've read a bunch of other forum posts of people talking about the issue, but I am yet to find someone saying how to solve it other than when it got close around here (https://forums.xamarin.com/discussion/92903/xamarin-forms-with-xamarin-auth-on-android-ios) and then nothing.

This happens to me on all the versions I'm testing and it's a very lacklustre experience... is there any progress with this or anything out there that can help!?

moljac commented 6 years ago

@zati- @kylewhittington

This is how you can test your registered scheme:

     adb shell am start \
       -a android.intent.action.VIEW \
       -d "myapplogin://localhost/oauth2redirect" com.your.app.packagename

In your intent there is only myapplogin defined, but no DataHost[s] (localhost) or DataPath[s] (oauth2redirect).

I haven't played with all options.

You call

AuthenticationState.Authenticator.OnPageLoading(uri);

so events should be raised!

loanburger commented 6 years ago

I also have this same problem. I have posted about it on Xamarin.Forums. Presenter does not close. I can suppress the message by doign CustomTabsConfiguration.CustomTabsClosingMessage = null;

botfx commented 6 years ago

I have the some issue in Google, Microsoft and Facebook using nativeUI (on Android).

gonzalonm commented 6 years ago

Same issue here in Google. Looks like CustomTabs does not close properly. Finding the way to close it manually :(

cabauman commented 6 years ago

This may not be a "proper" fix but it stopped me from tearing my hair out. I've only tested using Google auth for Android native.

Just make your calling activity start itself in the OnAuthenticationCompleted callback, with ClearTop and SingleTop flags.

public async void OnAuthenticationCompleted(GoogleOAuthToken token)
{
    var intent = new Intent(this, typeof(SignInActivity));
    intent.SetFlags(ActivityFlags.ClearTop | ActivityFlags.SingleTop);
    StartActivity(intent);

    // Retrieve the user's email address
    var googleService = new GoogleService();
    var email = await googleService.GetEmailAsync(token.TokenType, token.AccessToken);

    // Display it on the UI
    var googleButton = FindViewById<Button>(Resource.Id.googleLoginButton);
    googleButton.Text = $"Connected with {email}";
}

Oh and make sure to set the CustomTabsClosingMessage to null. Otherwise, you'll see the toast in your SignInActivity upon being authenticated.

private void OnGoogleLoginButtonClicked(object sender, EventArgs e)
{
    // Display the activity handling the authentication
    var authenticator = Auth.GetAuthenticator();
    var intent = authenticator.GetUI(this);
    Xamarin.Auth.CustomTabsConfiguration.CustomTabsClosingMessage = null;
    StartActivity(intent);
}
kirk-marple commented 6 years ago

Curious, has anyone found a better solution to CustomTabs not closing properly on Android?

The trick for starting the intent with ClearTop does work, but I read somewhere else this may have bad side effects.

Is this a bug in Xamarin.Auth, or a problem on the Google/Android side?

newky2k commented 6 years ago

can you try this in the latest version please

zati- commented 6 years ago

@newky2k Still the same with latest version

newky2k commented 6 years ago

@zati- Ok thanks

ilyalehchylin commented 5 years ago

To switch back to the previous activity I used

var intent = new Intent(this, typeof(MainActivity)).SetFlags(ActivityFlags.ReorderToFront);
StartActivity(intent);

instead of

Finish();

moljac commented 5 years ago

Moving it to High Priority

In order to speed up the bugfixing, please add link to the repo with minimal sample (with removed sensitve data)

Brosten commented 5 years ago

AuthTest.zip Here is a complete minimal sample with google login, showing that the login-browser doesn't Close after successfully completing the login process.

Is anyone working on this?

PilgrimViis commented 5 years ago

Can you please tell us about this issue status? Should I use hacks to handle the issue myself or somebody gonna fix it soon in library?

ybadragon commented 5 years ago

I can confirm this still doesn't work in the latest version. Also the CustomClosingMessage isn't accessible anymore?

akamud commented 5 years ago

No update? No workaround?

ybadragon commented 5 years ago

@akamud Here is how I've been getting around this

[Activity(Label = "CustomUrlSchemeInterceptorActivity", NoHistory = true, LaunchMode = LaunchMode.SingleTop)]
    [IntentFilter(
        new[] { Intent.ActionView },
        Categories = new[] { Intent.CategoryDefault, Intent.CategoryBrowsable },
        DataSchemes = new[] { "myapplogin" },
        DataPath = "/oauth2redirect")]
    public class CustomUrlSchemeInterceptorActivity : Activity
    {
        protected override void OnCreate(Bundle savedInstanceState)
        {
            base.OnCreate(savedInstanceState);

            // Convert Android.Net.Url to Uri
            global::Android.Net.Uri uri = Intent.Data;
           //This is the part that hides the Custom Tabs message
            CustomTabsConfiguration.CustomTabsClosingMessage = null;
            Uri uri_netfx = new Uri(uri.ToString());

            // Load redirectUrl page
            AppAuth.Authenticator.OnPageLoading(uri_netfx);

            //This is what forces the page to close.
            var intent = new Intent(this, typeof(MainActivity));
            intent.SetFlags(ActivityFlags.ClearTop | ActivityFlags.SingleTop);
            StartActivity(intent);

            this.Finish();

            return;
        }
    }
akamud commented 5 years ago

EDIT: The above works! Thanks @thomasonb!

ybadragon commented 5 years ago

@akamud yes I am, no problem. Glad to help :)

nicolas-garcia commented 4 years ago

Hi!

I still have this issue, even with the code provided by @thomasonb above. Here is my code in the callback:

[Activity(Label = "AppCallback", NoHistory = true, LaunchMode = LaunchMode.SingleTop)]
[IntentFilter(new[] {Intent.ActionView},
    Categories = new[] {Intent.CategoryDefault, Intent.CategoryBrowsable},
    DataSchemes = new []{ "app" },
    DataHosts = new []{ "signin", "signout"}
    )]
public class OidcCallbackActivity : AppCompatActivity
{
    protected override void OnCreate(Bundle savedInstanceState)
    {
        base.OnCreate(savedInstanceState);

        var uriAndroid = Intent.Data;
        // Convert Android.Net.Url to Uri
        var uri = new Uri(uriAndroid.ToString());

        // Load redirectUrl page
        AuthenticatorState.Authenticator?.OnPageLoading(uri);

        //This is what forces the page to close.
        var intent = new Intent(this, typeof(MainActivity));
        intent.SetFlags(ActivityFlags.ClearTop | ActivityFlags.SingleTop);
        StartActivity(intent);

        this.Finish();

        return;
    }
}

Any idea what's wrong with this code? I've been struggling with it for months...

EDIT: Clarification, I am redirected to my app and the code above is called, but the browser is still opened in background. The next time you try to open it from the app, it shows up on the previous opened page after redirection. Actually, my issue is related to #275

zigagrcar commented 4 years ago

@nicolas-garcia From my experience, it didn't work because of wrong datascheme and datahost, I had to put correct app id from Google API

        DataSchemes = new[] { "com.googleusercontent.apps.YOURID" },
        DataPath = "/oauth2redirect")]
IlyaDhtvzGhbltn commented 2 years ago

@nicolas-garcia From my experience, it didn't work because of wrong datascheme and datahost, I had to put correct app id from Google API

        DataSchemes = new[] { "com.googleusercontent.apps.YOURID" },
        DataPath = "/oauth2redirect")]

Could you clarify what is - YOURID? I've used all from dashboard and still have the issue

image