I have followed the official documentation of the web authenticator for .NET Maui here. It explains what to do efficiently, but they miss some crucial information regarding the callback URL. According to the article, the URL should be myapp://. I assume it could be anything like thisapp://.
The problem with myapp:// is that the WebAuthenticatorActivity does not like this. I get the following error when using myapp:// as the callback URL:
You must subclass the
WebAuthenticatorCallbackActivityand create an IntentFilter for it which matches yourcallbackUrl.
At the bottom I will post the code.
I have also had a look at Dan Siegal's helper library and his video on the MAUI web authenticator, but he could not get the app working in the video. I have also viewed his sample on GitHub and he uses "myapp" as the callback URL. The problem with only "myapp" is that the Uri class does not like it when you specify the callback URL for the web authenticator. Here is the error I get:
Invalid URI: The format of the URI could not be determined.
So basically I can't use "myapp://" or "myapp" and decided to do a combination of the two. For the Callback URL, I used "myapp://" and for the WebAuthenticatorActivity I used "myapp". This actually works, but there is still one problem. On the Google console it expects a redirect URL. I have tried "myapp://" or "myapp" but it does not allow this:
After searching the Internet, I found an article that mentions that I should use: https://mysite/signin-google. I have set up the API correctly according to the documentation and by using Dan Siegal's library.
So if I use "myapp://" as the callback URL for the web authenticator and "myapp" for the WebAuthenticatorActivity and https://mysite/signin-google on Google console, all is working until the point where Google tries to redirect back to my app from the browser. This is the error I get:
This mysite page can't by found. No webpage was found for the web address: https://mysite/signin-google
It comes down to:
What value should I use for:
- The callback URL of the web authenticator
- The WebAuthenticatorActivity
- The Google Console redirect URL
Here is my code:
File MauiProgram.cs
using CommunityToolkit.Maui;
using FertilizerFarm.Helpers;
using FertilizerFarm.Services;
using FertilizerFarm.View;
using Refit;
using Telerik.Maui.Controls.Compatibility;
namespace FertilizerFarm;
public static class Constants
{
public const string BaseUrl = "https://mysite/mobileauth/";
public const string CallbackScheme = "myapp://";
}
public static class MauiProgram
{
public static MauiApp CreateMauiApp()
{
var builder = MauiApp.CreateBuilder();
builder
.UseTelerik()
.UseMauiApp<App>()
.UseMauiCommunityToolkit()
.ConfigureFonts(fonts =>
{
fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
fonts.AddFont("OpenSans-Semibold.ttf", "OpenSansSemibold");
fonts.AddFont("telerikfontexamples.ttf", "TelerikFontExamples");
});
builder.Services.AddSingleton<IConnectivity>(Connectivity.Current)
.AddSingleton(WebAuthenticator.Default)
.AddSingleton(SecureStorage.Default)
.AddRefitClient<IUserProfileService>()
.AddSingleton<AuthService>()
.AddSingleton<JWTService>()
.AddTransient<LoginViewModel>()
.AddTransient<Login>()
return builder.Build();
}
public static IServiceCollection AddRefitClient<T>(this IServiceCollection services)
where T : class
{
services.AddSingleton(sp =>
{
var settings = new RefitSettings
{
AuthorizationHeaderValueGetter = () => sp.GetRequiredService<ISecureStorage>().GetAsync("access_token")
};
return RestService.For<T>(Constants.BaseUrl, settings);
});
return services;
}
}
File WebAuthenticatorCallbackActivity.cs
using Android.App;
using Android.Content;
using Android.Content.PM;
namespace FertilizerFarm;
[Activity(NoHistory = true, LaunchMode = LaunchMode.SingleTop, Exported = true)]
[IntentFilter(new[] { Intent.ActionView },
Categories = new[] { Intent.CategoryDefault, Intent.CategoryBrowsable },
DataScheme = CALLBACK_SCHEME)]
public class WebAuthenticatorActivity : Microsoft.Maui.Authentication.WebAuthenticatorCallbackActivity
{
const string CALLBACK_SCHEME = "myapp";
}
File LoginViewModel.cs
[RelayCommand]
async Task SocialLogin()
{
try
{
var result = await _webAuthenticator.AuthenticateAsync(new WebAuthenticatorOptions
{
CallbackUrl = new Uri($"{Constants.CallbackScheme}"),
Url = new Uri(Constants.BaseUrl + "google")
});
await _storage.SetAsync("access_token", result.AccessToken);
using var response = await _userProfile.GetProfileClaims();
if (response.IsSuccessStatusCode)
{
Claims.Clear();
var claims = response.Content.Select(x => $"{x.Key}: {x.Value}");
foreach (var claim in claims)
Claims.Add(claim);
}
}
catch (Exception ex)
{
}
}

myapp:// is the callback between the App and API
Google has no knowledge of the App and communicates only with the API
Google needs a redirect URL to find its way back to the to the API
This should be something like https://localhost:{PORT}/signin-google
These are the pages that helped me figure it out:
https://learn.microsoft.com/en-us/aspnet/core/security/authentication/social/google-logins?view=aspnetcore-6.0
https://learn.microsoft.com/en-us/dotnet/maui/platform-integration/communication/authentication?tabs=ios