I'm trying to authenticate users through Google. I'm using the ABP startup template for ASP.NET Core with Vue.
Here's what I have done so far:
I've created a GoogleAuthProviderApi
in Web.Core:
using System;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authentication.Google;
using Newtonsoft.Json.Linq;
namespace Mindbus.MindbooksSEO.Authentication.External.Google
{
public class GoogleAuthProviderApi : ExternalAuthProviderApiBase
{
public const string Name = "Google";
public override async Task<ExternalAuthUserInfo> GetUserInfo(string accessCode)
{
using (var client = new HttpClient())
{
client.DefaultRequestHeaders.UserAgent.ParseAdd("Microsoft ASP.NET Core OAuth middleware");
client.DefaultRequestHeaders.Accept.ParseAdd("application/json");
client.Timeout = TimeSpan.FromSeconds(30);
client.MaxResponseContentBufferSize = 1024 * 1024 * 10; // 10 MB
var request = new HttpRequestMessage(HttpMethod.Get, GoogleDefaults.UserInformationEndpoint);
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", accessCode);
var response = await client.SendAsync(request);
response.EnsureSuccessStatusCode();
var payload = JObject.Parse(await response.Content.ReadAsStringAsync());
return new ExternalAuthUserInfo
{
//Name = GoogleHelper.GetName(payload),
EmailAddress = GoogleHelper.GetEmail(payload),
//Surname = GoogleHelper.GetFamilyName(payload),
//ProviderKey = GoogleHelper.GetId(payload),
Provider = Name
};
}
}
}
}
I've registered the Google External Authentication in AuthConfigurer.cs in Web.Host:
if (bool.Parse(configuration["Authentication:Google:IsEnabled"]))
{
services.AddAuthentication().AddGoogle(googleOptions =>
{
googleOptions.ClientId = configuration["Authentication:Google:ClientId"];
googleOptions.ClientSecret = configuration["Authentication:Google:ClientSecret"];
});
}
I've added the settings to appsettings.json in Web.Host, and created the corresponding secrets (ClientId and ClientSecret) in the Secret Manager tool.
I've forced the API to SSL with the RequireHttpsAttribute
.
I've registered the GoogleAuthProviderApi
in the [ProjectName]WebCoreModule.cs:
public override void PreInitialize()
{
Configuration.DefaultNameOrConnectionString = _appConfiguration.GetConnectionString(
MindbooksSEOConsts.ConnectionStringName
);
// Use database for language management
Configuration.Modules.Zero().LanguageManagement.EnableDbLocalization();
Configuration.Modules.AbpAspNetCore()
.CreateControllersForAppServices(
typeof(MindbooksSEOApplicationModule).GetAssembly()
);
ConfigureTokenAuth();
Configuration.Modules.Zero().UserManagement.ExternalAuthenticationSources.Add<GoogleAuthProviderApi>();
}
I don't know what I'm missing here, nor do I know what to expect exactly.
I would have thought that a call to the api/TokenAuth/GetExternalAuthenticationProviders endpoint would at least give me a list with Google in it, but this request returns with an empty array in the results.
Additionally, it's a bit unclear to me what the scope of this external authentication is, in the case of OAuth providers such as Google and Facebook. It seems to me that you either have OAuth for server-side usage, in which case I don't understand why you would expose part of it through the API. Or you have OAuth for JavaScript web apps, in which case you don't need an API endpoint on your own server, you just handle the entire thing client-side through the web app.
So, what's the purpose exactly of the External Authenticate API endpoint? Is it so that your own server acts as a proxy for authentication? So that you can have both client-side and server-side usage of the External (Google) API?
Update 1
The comments require me to add some clarification.
#1: If I add the Abp.TenantId
header in Postman, the response remains the same:
GET /api/TokenAuth/GetExternalAuthenticationProviders HTTP/1.1
Host: localhost:44300
Accept: application/json
Abp.TenantId: 2
Cache-Control: no-cache
Postman-Token: 0cb72e57-4b9a-474d-b60d-492fa727a7a2
#2: The console "tricks" in Swagger result in errors:
abp.swagger.login()
undefined
VM40:49 POST https://localhost:44300/api/TokenAuth/Authenticate 500 ()
abp.swagger.login @ VM40:49
(anonymous) @ VM84:1
abp.swagger.addAuthToken()
false
Update 2
I think there's something wrong with the GoogleAuthProviderApi
. After I made the debugger break on all CLR Exceptions, I caught the following error:
'Mindbus.MindbooksSEO.Authentication.External.Google.GoogleAuthProviderApi' to type
'Abp.Authorization.Users.IExternalAuthenticationSource`2
[Mindbus.MindbooksSEO.MultiTenancy.Tenant,
Mindbus.MindbooksSEO.Authorization.Users.User]'.'