Xamarin OIDC BankID auth from android

377 Views Asked by At

I try to authorize with swedish BankID from Android and i can't redirect to my app. I use Essentials.WebAuthenticator and from IOS it works perfect, but android can't redirect from final page to my app.

Page after auth

WebAuthenticatorBrowser

internal class WebAuthenticatorBrowser : IBrowser
    {
        private readonly string _callbackUrl;

        public WebAuthenticatorBrowser(string callbackUrl = null)
        {
            _callbackUrl = callbackUrl ?? "";
        }
        public async Task<BrowserResult> InvokeAsync(BrowserOptions options, CancellationToken cancellationToken = default)
        {
            try
            {
                var callbackUrl = string.IsNullOrEmpty(_callbackUrl) ? options.EndUrl : _callbackUrl;
                WebAuthenticatorResult authResult =
                    await WebAuthenticator.AuthenticateAsync(new Uri(options.StartUrl), new Uri(callbackUrl));
                var authorizeResponse = ToRawIdentityUrl(options.EndUrl, authResult);

                return new BrowserResult
                {
                    Response = authorizeResponse
                };
            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex);
                return new BrowserResult()
                {
                    ResultType = BrowserResultType.UnknownError,
                    Error = ex.ToString()
                };
            }
        }

        public string ToRawIdentityUrl(string redirectUrl, WebAuthenticatorResult result)
        {
            IEnumerable<string> parameters = result.Properties.Select(pair => $"{pair.Key}={pair.Value}");
            var values = string.Join("&", parameters);

            return $"{redirectUrl}#{values}";
        }
    }

MainActivity

    namespace JAG.Droid
{
    [Activity(Label = "JAG", Icon = "@mipmap/icon", Theme = "@style/MainTheme", MainLauncher = true, ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation | ConfigChanges.UiMode | ConfigChanges.ScreenLayout | ConfigChanges.SmallestScreenSize,
        LaunchMode = Android.Content.PM.LaunchMode.SingleInstance)]
    public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity
    {
        protected override void OnCreate(Bundle savedInstanceState)
        {
            base.OnCreate(savedInstanceState);

            Xamarin.Essentials.Platform.Init(this, savedInstanceState);
            global::Xamarin.Forms.Forms.Init(this, savedInstanceState);

            Xamarin.Essentials.Platform.ActivityStateChanged += Platform_ActivityStateChanged;

            LoadApplication(new App());
        }
        public override void OnRequestPermissionsResult(int requestCode, string[] permissions, [GeneratedEnum] Android.Content.PM.Permission[] grantResults)
        {
            Xamarin.Essentials.Platform.OnRequestPermissionsResult(requestCode, permissions, grantResults);

            base.OnRequestPermissionsResult(requestCode, permissions, grantResults);
        }

        protected override void OnResume()
        {
            base.OnResume();
            Xamarin.Essentials.Platform.OnResume();
        }

        protected override void OnNewIntent(Intent intent)
        {
            base.OnNewIntent(intent);

            Xamarin.Essentials.Platform.OnNewIntent(intent);
        }

        protected override void OnDestroy()
        {
            base.OnDestroy();

            Xamarin.Essentials.Platform.ActivityStateChanged -= Platform_ActivityStateChanged;
        }

        void Platform_ActivityStateChanged(object sender, Xamarin.Essentials.ActivityStateChangedEventArgs e) =>
            Toast.MakeText(this, e.State.ToString(), ToastLength.Short).Show();
    }

    [Activity(NoHistory = true, LaunchMode = LaunchMode.SingleTop)]
    [IntentFilter(new[] { Android.Content.Intent.ActionView }, Categories = new[]
    { Android.Content.Intent.CategoryDefault, Android.Content.Intent.CategoryBrowsable }, DataScheme = "JAG")]
    public class WebAuthenticatorCallbackActivity : Xamarin.Essentials.WebAuthenticatorCallbackActivity
    {

    }
}

OIDC config

var options = new OidcClientOptions
        {
            Authority = AUTHORITY,
            ClientId = CLIENTID,
            ClientSecret = CLIENTSECRET,
            Scope = SCOPE,
            RedirectUri = REDIRECTURI,
            PostLogoutRedirectUri = LOGOUTREDIRECTURI,
            Browser = new WebAuthenticatorBrowser() 
        };

        options.BackchannelHandler = new HttpClientHandler() { ServerCertificateCustomValidationCallback = (message, certificate, chain, sslPolicyErrors) => true };
        options.Policy.Discovery.RequireHttps = false;
        App.OIDCclient = new OidcClient(options);

Call login

_result = await App.OIDCclient.LoginAsync(new LoginRequest());

            if (_result.IsError)
            {
                Microsoft.AppCenter.AppCenterLog.Error("Error", _result.Error);
                return;
            }

If I close final page I get Exception

A task was canceled.

     at Xamarin.Essentials.WebAuthenticator.PlatformAuthenticateAsync (System.Uri url, System.Uri callbackUrl) [0x001c3] in D:\a\1\s\Xamarin.Essentials\WebAuthenticator\WebAuthenticator.android.cs:94 
  at JAG.Helpers.WebAuthenticatorBrowser.InvokeAsync (IdentityModel.OidcClient.Browser.BrowserOptions options, System.Threading.CancellationToken cancellationToken) [0x00071] in /Users/samoykin/projects/tests/IntroApp/JAG/Helpers/WebAuthenticatorBrowser.cs:25
0

There are 0 best solutions below