如何在ASP.NET Boilerplate中设置社交登录?

gij*_*ijs 5 c# authentication configuration asp.net-core aspnetboilerplate

我正在尝试通过Google对用户进行身份验证。我正在使用Vue的ASP.NET Core的ABP启动模板。

到目前为止,这是我所做的:

GoogleAuthProviderApi在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
                };
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我已经登记在谷歌外部认证AuthConfigurer.cs在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"];
    });
}
Run Code Online (Sandbox Code Playgroud)

我已将设置添加到Web.Host中的appsettings.json中,并在Secret Manager工具中创建了相应的机密(ClientIdClientSecret)。

我已通过强制将API转换为SSL RequireHttpsAttribute

我已经GoogleAuthProviderApi[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>();
}
Run Code Online (Sandbox Code Playgroud)

我不知道我在这里想念的东西,也不知道确切地期待着什么。

我以为,对api / TokenAuth / GetExternalAuthenticationProviders端点的调用至少会给我一个包含Google的列表,但是此请求返回的结果中包含一个空数组。

此外,对于OAuth提供程序(例如Google和Facebook),我对这种外部身份验证的范围还不清楚。在我看来,您可以使用OAuth进行服务器端使用,在这种情况下,我不明白为什么要通过API公开其中的一部分。或者,您拥有适用于JavaScript的OAuth Web应用程序,在这种情况下,您不需要在自己的服务器上使用API​​终结点,只需通过Web应用程序处理客户端的全部操作即可。

那么,外部身份验证API端点的确切目的是什么?是这样让您自己的服务器充当身份验证的代理吗?这样您就可以同时在客户端和服务器端使用外部(Google)API?

更新1

这些评论要求我增加一些澄清。

#1:如果我Abp.TenantId在Postman中添加标题,则响应保持不变:

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
Run Code Online (Sandbox Code Playgroud)

#2:Swagger中的控制台“技巧”导致错误:

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
Run Code Online (Sandbox Code Playgroud)

更新2

我认为GoogleAuthProviderApi。在所有CLR异常上使调试器中断后,我捕获了以下错误:

'Mindbus.MindbooksSEO.Authentication.External.Google.GoogleAuthProviderApi' to type
 'Abp.Authorization.Users.IExternalAuthenticationSource`2
[Mindbus.MindbooksSEO.MultiTenancy.Tenant,
Mindbus.MindbooksSEO.Authorization.Users.User]'.'
Run Code Online (Sandbox Code Playgroud)

aar*_*ron 4

ASP.NET Core 1.x 或 MVC 5

  1. 请注意,社交登录 提供商(例如 Google)的配置与外部身份验证 (例如 LDAP)有很大不同。因此,删除这一行:

    Configuration.Modules.Zero().UserManagement.ExternalAuthenticationSources.Add<GoogleAuthProviderApi>();

  2. 观察GetExternalAuthenticationProviders看起来在IExternalAuthConfiguration. 因此,在方法中
    配置:IExternalAuthConfigurationPostInitialize*WebHostModule

    if (bool.Parse(configuration["Authentication:Google:IsEnabled"]))
    {
        var externalAuthConfiguration = IocManager.Resolve<IExternalAuthConfiguration>();
    
        externalAuthConfiguration.Providers.Add(
            new ExternalLoginProviderInfo(
                GoogleAuthProviderApi.Name,
                configuration["Authentication:Google:ClientId"],
                configuration["Authentication:Google:ClientSecret"],
                typeof(GoogleAuthProviderApi)
            )
        );
    }
    
    Run Code Online (Sandbox Code Playgroud)

ASP.NET 核心 2.x

尽管上述处理社交登录提供商的方法可能有效,但不再推荐

内置.AddGoogle方式:

if (bool.Parse(configuration["Authentication:Google:IsEnabled"]))
{
    services.AddAuthentication().AddGoogle(googleOptions =>
    {
        googleOptions.ClientId = configuration["Authentication:Google:ClientId"];
        googleOptions.ClientSecret = configuration["Authentication:Google:ClientSecret"];
    });
}
Run Code Online (Sandbox Code Playgroud)

...适用于:

var result = await _signInManager.ExternalLoginSignInAsync(
    info.LoginProvider,
    info.ProviderKey,
    isPersistent: false,
    bypassTwoFactor : true
);
Run Code Online (Sandbox Code Playgroud)

而获取外部认证方案的方式是:

var schemes = (await _signInManager.GetExternalAuthenticationSchemesAsync()).ToList();
Run Code Online (Sandbox Code Playgroud)

您可以修改GetExternalAuthenticationProviders以返回此数据。