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

问题描述 投票:2回答:2

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

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

我在Web.Core中创建了一个GoogleAuthProviderApi

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
                };
            }
        }
    }
}

我在Web.Host的AuthConfigurer.cs中注册了Google外部身份验证:

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

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

我已经强制API使用RequireHttpsAttribute进行SSL。

我在[ProjectName] WebCoreModule.cs中注册了GoogleAuthProviderApi

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>();
}

我不知道我在这里缺少什么,也不知道到底想要什么。

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

此外,对于我来说,这种外部身份验证的范围有点不清楚,例如Google和Facebook等OAuth提供商。在我看来,您要么使用OAuth进行服务器端使用,在这种情况下,我不明白为什么要通过API公开部分内容。或者您有用于JavaScript Web应用程序的OAuth,在这种情况下,您不需要在自己的服务器上使用API​​端点,只需通过Web应用程序处理整个客户端。

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

更新1

评论要求我补充一些说明。

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

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:Swagger中的控制台“欺骗”导致错误:

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

更新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]'.'
c# authentication asp.net-core configuration aspnetboilerplate
2个回答
4
投票

ASP.NET Core 1.x or MVC 5

  1. 请注意,Social Login提供程序(例如Google)的配置与External Authentication源(例如LDAP)完全不同。所以,删除这一行: Configuration.Modules.Zero().UserManagement.ExternalAuthenticationSources.Add<GoogleAuthProviderApi>();
  2. 观察GetExternalAuthenticationProvidersIExternalAuthConfiguration看起来。 所以,在IExternalAuthConfigurationPostInitialize方法中配置*WebHostModuleif (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) ) ); }

ASP.NET Core 2.x

虽然上述处理社交登录提供程序的方式可能有效,但它是no longer recommended

内置的.AddGoogle方式:

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

......用于:

var result = await _signInManager.ExternalLoginSignInAsync(
    info.LoginProvider,
    info.ProviderKey,
    isPersistent: false,
    bypassTwoFactor : true
);

获得外部身份验证方案的方法是:

var schemes = (await _signInManager.GetExternalAuthenticationSchemesAsync()).ToList();

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


0
投票

对于那些访问这个主题并且没有找到答案的人(就像我一样)。

aspnetcore 2.2和abp 4.5.0 Facebook工作示例

* WebHostModule.cs

public override void PostInitialize()
        {
            var externalAuthConfiguration = IocManager.Resolve<IExternalAuthConfiguration>();
            externalAuthConfiguration.Providers.Add(
                 new ExternalLoginProviderInfo(
                    FacebookAuthProvider.Name,
                    configuration["Authentication:Facebook:ClientId"],
                    configuration["Authentication:Facebook:Secret"],
                    typeof(FacebookAuthProvider)
                )
            );           
        }

* FacebookAuthProvider.cs

public class FacebookAuthProvider: ExternalAuthProviderApiBase
    {
        private static readonly HttpClient Client = new HttpClient();
        public const string Name = "Facebook";
        public override async Task<ExternalAuthUserInfo> GetUserInfo(string accessCode)
        {
            //gen app access token
            var appAccessTokenResponse = await Client.GetStringAsync("https://graph.facebook.com/oauth/access_token" +
              "?client_id=" + ProviderInfo.ClientId +
              "&client_secret=" + ProviderInfo.ClientSecret +
              "&grant_type=client_credentials");
            var appAccessToken = JsonConvert.DeserializeObject<FacebookAppAccessToken>(appAccessTokenResponse);
            //validate user access token
            var userAccessTokenValidationResponse = await Client.GetStringAsync("https://graph.facebook.com/v3.2/debug_token" +
                "?input_token="+ accessCode +
                "&access_token="+ appAccessToken.AccessToken);
            var userAccessTokenValidation = JsonConvert.DeserializeObject<FacebookUserAccessTokenValidation>(userAccessTokenValidationResponse);
            if (!userAccessTokenValidation.Data.IsValid)
            {
                throw new ArgumentException("login_failure Invalid facebook token.");
            }

            //get userinfo
            var userInfoResponse = await Client.GetStringAsync($"https://graph.facebook.com/v3.2/me?fields=id,email,first_name,last_name&access_token={accessCode}");
            var userInfo = JsonConvert.DeserializeObject<FacebookUserData>(userInfoResponse);

            return new ExternalAuthUserInfo
            {
                Name = userInfo.FirstName,
                EmailAddress = userInfo.Email,
                Surname=userInfo.LastName,
                Provider=Name,
                ProviderKey=userInfo.Id.ToString()
            };

        }
    }

楷模

internal class FacebookUserData
    {
        public long Id { get; set; }
        public string Email { get; set; }
        public string Name { get; set; }
        [JsonProperty("first_name")]
        public string FirstName { get; set; }
        [JsonProperty("last_name")]
        public string LastName { get; set; }
        public string Gender { get; set; }
        public string Locale { get; set; }
        public FacebookPictureData Picture { get; set; }
    }

    internal class FacebookPictureData
    {
        public FacebookPicture Data { get; set; }
    }

    internal class FacebookPicture
    {
        public int Height { get; set; }
        public int Width { get; set; }
        [JsonProperty("is_silhouette")]
        public bool IsSilhouette { get; set; }
        public string Url { get; set; }
    }

    internal class FacebookUserAccessTokenData
    {
        [JsonProperty("app_id")]
        public long AppId { get; set; }
        public string Type { get; set; }
        public string Application { get; set; }
        [JsonProperty("expires_at")]
        public long ExpiresAt { get; set; }
        [JsonProperty("is_valid")]
        public bool IsValid { get; set; }
        [JsonProperty("user_id")]
        public long UserId { get; set; }
    }

    internal class FacebookUserAccessTokenValidation
    {
        public FacebookUserAccessTokenData Data { get; set; }
    }

    internal class FacebookAppAccessToken
    {
        [JsonProperty("token_type")]
        public string TokenType { get; set; }
        [JsonProperty("access_token")]
        public string AccessToken { get; set; }
    }
© www.soinside.com 2019 - 2024. All rights reserved.