Browse Source
- 增加OAuth模块 **AbpAccountOAuthModule** ,用于定义OAuth相关设置、功能. - 重写登录视图页第三方登录区域组件 - 增加扩展登录提供者服务接口 - 增加账户模块OAuth实现模块 **AbpAccountWebOAuthModule** - 重写OAuthHandler以实现从设置系统中读取客户端配置项 **AccountAuthenticationRequestHandler**、**IOAuthHandlerOptionsProvider** - 增加默认第三方登录实现: GitHub、QQ、微信、企业微信、Bilibilipull/1224/head
44 changed files with 1383 additions and 70 deletions
@ -0,0 +1,3 @@ |
|||
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd"> |
|||
<ConfigureAwait ContinueOnCapturedContext="false" /> |
|||
</Weavers> |
|||
@ -0,0 +1,30 @@ |
|||
<?xml version="1.0" encoding="utf-8"?> |
|||
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> |
|||
<!-- This file was generated by Fody. Manual changes to this file will be lost when your project is rebuilt. --> |
|||
<xs:element name="Weavers"> |
|||
<xs:complexType> |
|||
<xs:all> |
|||
<xs:element name="ConfigureAwait" minOccurs="0" maxOccurs="1"> |
|||
<xs:complexType> |
|||
<xs:attribute name="ContinueOnCapturedContext" type="xs:boolean" /> |
|||
</xs:complexType> |
|||
</xs:element> |
|||
</xs:all> |
|||
<xs:attribute name="VerifyAssembly" type="xs:boolean"> |
|||
<xs:annotation> |
|||
<xs:documentation>'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed.</xs:documentation> |
|||
</xs:annotation> |
|||
</xs:attribute> |
|||
<xs:attribute name="VerifyIgnoreCodes" type="xs:string"> |
|||
<xs:annotation> |
|||
<xs:documentation>A comma-separated list of error codes that can be safely ignored in assembly verification.</xs:documentation> |
|||
</xs:annotation> |
|||
</xs:attribute> |
|||
<xs:attribute name="GenerateXsd" type="xs:boolean"> |
|||
<xs:annotation> |
|||
<xs:documentation>'false' to turn off automatic generation of the XML Schema file.</xs:documentation> |
|||
</xs:annotation> |
|||
</xs:attribute> |
|||
</xs:complexType> |
|||
</xs:element> |
|||
</xs:schema> |
|||
@ -0,0 +1,26 @@ |
|||
<Project Sdk="Microsoft.NET.Sdk"> |
|||
|
|||
<Import Project="..\..\..\..\configureawait.props" /> |
|||
<Import Project="..\..\..\..\common.props" /> |
|||
|
|||
<PropertyGroup> |
|||
<TargetFrameworks>netstandard2.0;netstandard2.1;net8.0;net9.0</TargetFrameworks> |
|||
<AssemblyName>LINGYUN.Abp.Account.OAuth</AssemblyName> |
|||
<PackageId>LINGYUN.Abp.Account.OAuth</PackageId> |
|||
<GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute> |
|||
<GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute> |
|||
<GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute> |
|||
<RootNamespace /> |
|||
</PropertyGroup> |
|||
|
|||
<ItemGroup> |
|||
<None Remove="LINGYUN\Abp\Account\OAuth\Localization\Resources\*.json" /> |
|||
<EmbeddedResource Include="LINGYUN\Abp\Account\OAuth\Localization\Resources\*.json" /> |
|||
</ItemGroup> |
|||
|
|||
<ItemGroup> |
|||
<PackageReference Include="Volo.Abp.Features" /> |
|||
<PackageReference Include="Volo.Abp.Settings" /> |
|||
</ItemGroup> |
|||
|
|||
</Project> |
|||
@ -0,0 +1,28 @@ |
|||
using LINGYUN.Abp.Account.OAuth.Localization; |
|||
using Volo.Abp.Features; |
|||
using Volo.Abp.Localization; |
|||
using Volo.Abp.Modularity; |
|||
using Volo.Abp.Settings; |
|||
using Volo.Abp.VirtualFileSystem; |
|||
|
|||
namespace LINGYUN.Abp.Account.OAuth; |
|||
|
|||
[DependsOn(typeof(AbpFeaturesModule))] |
|||
[DependsOn(typeof(AbpSettingsModule))] |
|||
public class AbpAccountOAuthModule : AbpModule |
|||
{ |
|||
public override void ConfigureServices(ServiceConfigurationContext context) |
|||
{ |
|||
Configure<AbpVirtualFileSystemOptions>(options => |
|||
{ |
|||
options.FileSets.AddEmbedded<AbpAccountOAuthModule>(); |
|||
}); |
|||
|
|||
Configure<AbpLocalizationOptions>(options => |
|||
{ |
|||
options.Resources |
|||
.Add<AccountOAuthResource>() |
|||
.AddVirtualJson("/LINGYUN/Abp/Account/OAuth/Localization/Resources"); |
|||
}); |
|||
} |
|||
} |
|||
@ -0,0 +1,52 @@ |
|||
using LINGYUN.Abp.Account.OAuth.Localization; |
|||
using Volo.Abp.Features; |
|||
using Volo.Abp.Localization; |
|||
using Volo.Abp.Validation.StringValues; |
|||
|
|||
namespace LINGYUN.Abp.Account.OAuth.Features; |
|||
|
|||
public class AccountOAuthFeatureDefinitionProvider : FeatureDefinitionProvider |
|||
{ |
|||
public override void Define(IFeatureDefinitionContext context) |
|||
{ |
|||
var group = context.AddGroup( |
|||
name: AccountOAuthFeatureNames.GroupName, |
|||
displayName: L("Features:ExternalOAuthLogin")); |
|||
|
|||
group.AddFeature( |
|||
name: AccountOAuthFeatureNames.GitHub.Enable, |
|||
defaultValue: "false", |
|||
displayName: L("Features:GithubOAuthEnable"), |
|||
description: L("Features:GithubOAuthEnableDesc"), |
|||
valueType: new ToggleStringValueType(new BooleanValueValidator())); |
|||
group.AddFeature( |
|||
name: AccountOAuthFeatureNames.QQ.Enable, |
|||
defaultValue: "false", |
|||
displayName: L("Features:QQOAuthEnable"), |
|||
description: L("Features:QQOAuthEnableDesc"), |
|||
valueType: new ToggleStringValueType(new BooleanValueValidator())); |
|||
group.AddFeature( |
|||
name: AccountOAuthFeatureNames.WeChat.Enable, |
|||
defaultValue: "false", |
|||
displayName: L("Features:WeChatOAuthEnable"), |
|||
description: L("Features:WeChatOAuthEnableDesc"), |
|||
valueType: new ToggleStringValueType(new BooleanValueValidator())); |
|||
group.AddFeature( |
|||
name: AccountOAuthFeatureNames.WeCom.Enable, |
|||
defaultValue: "false", |
|||
displayName: L("Features:WeComOAuthEnable"), |
|||
description: L("Features:WeComOAuthEnableDesc"), |
|||
valueType: new ToggleStringValueType(new BooleanValueValidator())); |
|||
group.AddFeature( |
|||
name: AccountOAuthFeatureNames.Bilibili.Enable, |
|||
defaultValue: "false", |
|||
displayName: L("Features:BilibiliOAuthEnable"), |
|||
description: L("Features:BilibiliOAuthEnableDesc"), |
|||
valueType: new ToggleStringValueType(new BooleanValueValidator())); |
|||
} |
|||
|
|||
private static LocalizableString L(string name) |
|||
{ |
|||
return LocalizableString.Create<AccountOAuthResource>(name); |
|||
} |
|||
} |
|||
@ -0,0 +1,46 @@ |
|||
namespace LINGYUN.Abp.Account.OAuth.Features; |
|||
|
|||
public static class AccountOAuthFeatureNames |
|||
{ |
|||
public const string GroupName = "Abp.Account.OAuth"; |
|||
public static class GitHub |
|||
{ |
|||
public const string Prefix = GroupName + ".GitHub"; |
|||
/// <summary>
|
|||
/// 启用Github认证登录
|
|||
/// </summary>
|
|||
public const string Enable = Prefix + ".Enable"; |
|||
} |
|||
public static class QQ |
|||
{ |
|||
public const string Prefix = GroupName + ".QQ"; |
|||
/// <summary>
|
|||
/// 启用QQ认证登录
|
|||
/// </summary>
|
|||
public const string Enable = Prefix + ".Enable"; |
|||
} |
|||
public static class WeChat |
|||
{ |
|||
public const string Prefix = GroupName + ".WeChat"; |
|||
/// <summary>
|
|||
/// 启用微信认证登录
|
|||
/// </summary>
|
|||
public const string Enable = Prefix + ".Enable"; |
|||
} |
|||
public static class WeCom |
|||
{ |
|||
public const string Prefix = GroupName + ".WeCom"; |
|||
/// <summary>
|
|||
/// 启用企业微信认证登录
|
|||
/// </summary>
|
|||
public const string Enable = Prefix + ".Enable"; |
|||
} |
|||
public static class Bilibili |
|||
{ |
|||
public const string Prefix = GroupName + ".Bilibili"; |
|||
/// <summary>
|
|||
/// 启用Bilibili认证登录
|
|||
/// </summary>
|
|||
public const string Enable = Prefix + ".Enable"; |
|||
} |
|||
} |
|||
@ -0,0 +1,8 @@ |
|||
using Volo.Abp.Localization; |
|||
|
|||
namespace LINGYUN.Abp.Account.OAuth.Localization; |
|||
|
|||
[LocalizationResourceName("AbpAccountOAuth")] |
|||
public class AccountOAuthResource |
|||
{ |
|||
} |
|||
@ -0,0 +1,36 @@ |
|||
{ |
|||
"culture": "en", |
|||
"texts": { |
|||
"Permission:ExternalOAuthLogin": "External Oauth Login", |
|||
"Features:ExternalOAuthLogin": "External Oauth Login", |
|||
"Features:GithubOAuthEnable": "GitHub", |
|||
"Features:GithubOAuthEnableDesc": "Enable to enable the application to support login via a GitHub account.", |
|||
"Features:QQOAuthEnable": "QQ", |
|||
"Features:QQOAuthEnableDesc": "Enable to enable the application to support login via QQ account.", |
|||
"Features:WeChatOAuthEnable": "WeChat", |
|||
"Features:WeChatOAuthEnableDesc": "Enable to enable the application to support login via the wechat official account.", |
|||
"Features:WeComOAuthEnable": "WeCom", |
|||
"Features:WeComOAuthEnableDesc": "Enable to enable the application to support login via wecom.", |
|||
"Features:BilibiliOAuthEnable": "Bilibili", |
|||
"Features:BilibiliOAuthEnableDesc": "Enable to allow the application to support login via a Bilibili account.", |
|||
"Settings:ExternalOAuthLogin": "External Oauth Login", |
|||
"Settings:GitHubAuth": "GitHub", |
|||
"Settings:GitHubClientId": "Client Id", |
|||
"Settings:GitHubClientIdDesc": "The client ID received from GitHub during registration. for details: https://docs.github.com/en/apps/oauth-apps/building-oauth-apps/authorizing-oauth-apps", |
|||
"Settings:GitHubClientSecret": "Client Secret", |
|||
"Settings:GitHubClientSecretDesc": "The client key of the OAuth application that you received from GitHub. for details: https://docs.github.com/en/apps/oauth-apps/building-oauth-apps/authorizing-oauth-apps", |
|||
"Settings:BilibiliAuth": "Bilibili", |
|||
"Settings:BilibiliClientId": "Client Id", |
|||
"Settings:BilibiliClientIdDesc": "Client Id, for details: https://open.bilibili.com/doc/4/eaf0e2b5-bde9-b9a0-9be1-019bb455701c#h1-u7B80u4ECB", |
|||
"Settings:BilibiliClientSecret": "Client Secret", |
|||
"Settings:BilibiliClientSecretDesc": "Client Secret, for details: https://open.bilibili.com/doc/4/eaf0e2b5-bde9-b9a0-9be1-019bb455701c#h1-u7B80u4ECB", |
|||
"OAuth:Microsoft": "Microsoft", |
|||
"OAuth:Twitter": "Twitter", |
|||
"OAuth:GitHub": "GitHub", |
|||
"OAuth:Google": "Google", |
|||
"OAuth:QQ": "QQ", |
|||
"OAuth:Weixin": "WeChat", |
|||
"OAuth:WorkWeixin": "WeCom", |
|||
"OAuth:Bilibili": "Bilibili" |
|||
} |
|||
} |
|||
@ -0,0 +1,36 @@ |
|||
{ |
|||
"culture": "zh-Hans", |
|||
"texts": { |
|||
"Permission:ExternalOAuthLogin": "外部登录", |
|||
"Features:ExternalOAuthLogin": "外部登录", |
|||
"Features:GithubOAuthEnable": "GitHub认证", |
|||
"Features:GithubOAuthEnableDesc": "启用以使应用程序支持通过GitHub账号登录.", |
|||
"Features:QQOAuthEnable": "QQ认证", |
|||
"Features:QQOAuthEnableDesc": "启用以使应用程序支持通过QQ账号登录.", |
|||
"Features:WeChatOAuthEnable": "微信认证", |
|||
"Features:WeChatOAuthEnableDesc": "启用以使应用程序支持通过微信公众号登录.", |
|||
"Features:WeComOAuthEnable": "企业微信认证", |
|||
"Features:WeComOAuthEnableDesc": "启用以使应用程序支持通过企业微信登录.", |
|||
"Features:BilibiliOAuthEnable": "Bilibili认证", |
|||
"Features:BilibiliOAuthEnableDesc": "启用以使应用程序支持通过Bilibili账号登录.", |
|||
"Settings:ExternalOAuthLogin": "外部登录", |
|||
"Settings:GitHubAuth": "GitHub登录", |
|||
"Settings:GitHubClientId": "Client Id", |
|||
"Settings:GitHubClientIdDesc": "注册时从 GitHub 收到的客户端 ID.详见: https://docs.github.com/en/apps/oauth-apps/building-oauth-apps/authorizing-oauth-apps", |
|||
"Settings:GitHubClientSecret": "Client Secret", |
|||
"Settings:GitHubClientSecretDesc": "您从 GitHub 收到的 OAuth 应用程序的客户端密钥.详见: https://docs.github.com/en/apps/oauth-apps/building-oauth-apps/authorizing-oauth-apps", |
|||
"Settings:BilibiliAuth": "Bilibili登录", |
|||
"Settings:BilibiliClientId": "Client Id", |
|||
"Settings:BilibiliClientIdDesc": "应用Id, 详见: https://open.bilibili.com/doc/4/eaf0e2b5-bde9-b9a0-9be1-019bb455701c#h1-u7B80u4ECB", |
|||
"Settings:BilibiliClientSecret": "Client Secret", |
|||
"Settings:BilibiliClientSecretDesc": "应用密钥, 详见: https://open.bilibili.com/doc/4/eaf0e2b5-bde9-b9a0-9be1-019bb455701c#h1-u7B80u4ECB", |
|||
"OAuth:Microsoft": "Microsoft", |
|||
"OAuth:Twitter": "Twitter", |
|||
"OAuth:GitHub": "GitHub", |
|||
"OAuth:Google": "Google", |
|||
"OAuth:QQ": "QQ", |
|||
"OAuth:Weixin": "微信", |
|||
"OAuth:WorkWeixin": "企业微信", |
|||
"OAuth:Bilibili": "Bilibili" |
|||
} |
|||
} |
|||
@ -0,0 +1,77 @@ |
|||
using LINGYUN.Abp.Account.OAuth.Localization; |
|||
using Volo.Abp.Localization; |
|||
using Volo.Abp.Settings; |
|||
|
|||
namespace LINGYUN.Abp.Account.OAuth.Settings; |
|||
|
|||
public class AccountOAuthSettingDefinitionProvider : SettingDefinitionProvider |
|||
{ |
|||
public override void Define(ISettingDefinitionContext context) |
|||
{ |
|||
context.Add(GetGitHubSettings()); |
|||
context.Add(GetBilibiliSettings()); |
|||
} |
|||
|
|||
private SettingDefinition[] GetGitHubSettings() |
|||
{ |
|||
return new SettingDefinition[] |
|||
{ |
|||
new SettingDefinition( |
|||
AccountOAuthSettingNames.GitHub.ClientId, |
|||
displayName: L("Settings:GitHubClientId"), |
|||
description: L("Settings:GitHubClientIdDesc"), |
|||
isVisibleToClients: false, |
|||
isEncrypted: true) |
|||
.WithProviders( |
|||
DefaultValueSettingValueProvider.ProviderName, |
|||
ConfigurationSettingValueProvider.ProviderName, |
|||
GlobalSettingValueProvider.ProviderName, |
|||
TenantSettingValueProvider.ProviderName), |
|||
new SettingDefinition( |
|||
AccountOAuthSettingNames.GitHub.ClientSecret, |
|||
displayName: L("Settings:GitHubClientSecret"), |
|||
description: L("Settings:GitHubClientSecretDesc"), |
|||
isVisibleToClients: false, |
|||
isEncrypted: true) |
|||
.WithProviders( |
|||
DefaultValueSettingValueProvider.ProviderName, |
|||
ConfigurationSettingValueProvider.ProviderName, |
|||
GlobalSettingValueProvider.ProviderName, |
|||
TenantSettingValueProvider.ProviderName), |
|||
}; |
|||
} |
|||
|
|||
private SettingDefinition[] GetBilibiliSettings() |
|||
{ |
|||
return new SettingDefinition[] |
|||
{ |
|||
new SettingDefinition( |
|||
AccountOAuthSettingNames.Bilibili.ClientId, |
|||
displayName: L("Settings:BilibiliClientId"), |
|||
description: L("Settings:BilibiliClientIdDesc"), |
|||
isVisibleToClients: false, |
|||
isEncrypted: true) |
|||
.WithProviders( |
|||
DefaultValueSettingValueProvider.ProviderName, |
|||
ConfigurationSettingValueProvider.ProviderName, |
|||
GlobalSettingValueProvider.ProviderName, |
|||
TenantSettingValueProvider.ProviderName), |
|||
new SettingDefinition( |
|||
AccountOAuthSettingNames.Bilibili.ClientSecret, |
|||
displayName: L("Settings:BilibiliClientSecret"), |
|||
description: L("Settings:BilibiliClientSecretDesc"), |
|||
isVisibleToClients: false, |
|||
isEncrypted: true) |
|||
.WithProviders( |
|||
DefaultValueSettingValueProvider.ProviderName, |
|||
ConfigurationSettingValueProvider.ProviderName, |
|||
GlobalSettingValueProvider.ProviderName, |
|||
TenantSettingValueProvider.ProviderName), |
|||
}; |
|||
} |
|||
|
|||
protected ILocalizableString L(string name) |
|||
{ |
|||
return LocalizableString.Create<AccountOAuthResource>(name); |
|||
} |
|||
} |
|||
@ -0,0 +1,30 @@ |
|||
namespace LINGYUN.Abp.Account.OAuth.Settings; |
|||
|
|||
public static class AccountOAuthSettingNames |
|||
{ |
|||
public const string GroupName = "Abp.Account.OAuth"; |
|||
public static class GitHub |
|||
{ |
|||
public const string Prefix = GroupName + ".GitHub"; |
|||
/// <summary>
|
|||
/// ClientId
|
|||
/// </summary>
|
|||
public const string ClientId = Prefix + ".ClientId"; |
|||
/// <summary>
|
|||
/// ClientSecret
|
|||
/// </summary>
|
|||
public const string ClientSecret = Prefix + ".ClientSecret"; |
|||
} |
|||
public static class Bilibili |
|||
{ |
|||
public const string Prefix = GroupName + ".Bilibili"; |
|||
/// <summary>
|
|||
/// ClientId
|
|||
/// </summary>
|
|||
public const string ClientId = Prefix + ".ClientId"; |
|||
/// <summary>
|
|||
/// ClientSecret
|
|||
/// </summary>
|
|||
public const string ClientSecret = Prefix + ".ClientSecret"; |
|||
} |
|||
} |
|||
@ -0,0 +1,105 @@ |
|||
using AspNet.Security.OAuth.Bilibili; |
|||
using AspNet.Security.OAuth.GitHub; |
|||
using AspNet.Security.OAuth.QQ; |
|||
using AspNet.Security.OAuth.Weixin; |
|||
using AspNet.Security.OAuth.WorkWeixin; |
|||
using LINGYUN.Abp.Account.OAuth; |
|||
using LINGYUN.Abp.Account.OAuth.Localization; |
|||
using LINGYUN.Abp.Account.Web.OAuth.ExternalProviders.Bilibili; |
|||
using LINGYUN.Abp.Account.Web.OAuth.ExternalProviders.GitHub; |
|||
using LINGYUN.Abp.Account.Web.OAuth.ExternalProviders.QQ; |
|||
using LINGYUN.Abp.Account.Web.OAuth.ExternalProviders.WeChat; |
|||
using LINGYUN.Abp.Account.Web.OAuth.ExternalProviders.WeCom; |
|||
using LINGYUN.Abp.Account.Web.OAuth.Microsoft.Extensions.DependencyInjection; |
|||
using LINGYUN.Abp.Tencent.QQ; |
|||
using LINGYUN.Abp.WeChat.Official; |
|||
using LINGYUN.Abp.WeChat.Work; |
|||
using Microsoft.Extensions.DependencyInjection; |
|||
using Volo.Abp.Account.Localization; |
|||
using Volo.Abp.AspNetCore.Mvc.Localization; |
|||
using Volo.Abp.Localization; |
|||
using Volo.Abp.Modularity; |
|||
using Volo.Abp.VirtualFileSystem; |
|||
|
|||
namespace LINGYUN.Abp.Account.Web.OAuth; |
|||
|
|||
[DependsOn(typeof(AbpAccountWebModule))] |
|||
[DependsOn(typeof(AbpAccountOAuthModule))] |
|||
[DependsOn(typeof(AbpTencentQQModule))] |
|||
[DependsOn(typeof(AbpWeChatOfficialModule))] |
|||
[DependsOn(typeof(AbpWeChatWorkModule))] |
|||
public class AbpAccountWebOAuthModule : AbpModule |
|||
{ |
|||
public override void PreConfigureServices(ServiceConfigurationContext context) |
|||
{ |
|||
context.Services.PreConfigure<AbpMvcDataAnnotationsLocalizationOptions>(options => |
|||
{ |
|||
options.AddAssemblyResource(typeof(AccountResource), typeof(AbpAccountWebOAuthModule).Assembly); |
|||
}); |
|||
|
|||
PreConfigure<IMvcBuilder>(mvcBuilder => |
|||
{ |
|||
mvcBuilder.AddApplicationPartIfNotExists(typeof(AbpAccountWebOAuthModule).Assembly); |
|||
}); |
|||
} |
|||
|
|||
public override void ConfigureServices(ServiceConfigurationContext context) |
|||
{ |
|||
Configure<AbpVirtualFileSystemOptions>(options => |
|||
{ |
|||
options.FileSets.AddEmbedded<AbpAccountWebOAuthModule>("LINGYUN.Abp.Account.Web.OAuth"); |
|||
}); |
|||
|
|||
Configure<AbpLocalizationOptions>(options => |
|||
{ |
|||
options.Resources |
|||
.Get<AccountResource>() |
|||
.AddBaseTypes(typeof(AccountOAuthResource)); |
|||
}); |
|||
|
|||
context.Services |
|||
.AddAuthentication() |
|||
.AddGitHub(options => |
|||
{ |
|||
options.ClientId = "ClientId"; |
|||
options.ClientSecret = "ClientSecret"; |
|||
|
|||
options.Scope.Add("user:email"); |
|||
}).UseSettingProvider< |
|||
GitHubAuthenticationOptions, |
|||
GitHubAuthenticationHandler, |
|||
GitHubAuthHandlerOptionsProvider>() |
|||
.AddQQ(options => |
|||
{ |
|||
options.ClientId = "ClientId"; |
|||
options.ClientSecret = "ClientSecret"; |
|||
}).UseSettingProvider< |
|||
QQAuthenticationOptions, |
|||
QQAuthenticationHandler, |
|||
QQAuthHandlerOptionsProvider>() |
|||
.AddWeixin(options => |
|||
{ |
|||
options.ClientId = "ClientId"; |
|||
options.ClientSecret = "ClientSecret"; |
|||
}).UseSettingProvider< |
|||
WeixinAuthenticationOptions, |
|||
WeixinAuthenticationHandler, |
|||
WeChatAuthHandlerOptionsProvider>() |
|||
.AddWorkWeixin(options => |
|||
{ |
|||
options.ClientId = "ClientId"; |
|||
options.ClientSecret = "ClientSecret"; |
|||
}).UseSettingProvider< |
|||
WorkWeixinAuthenticationOptions, |
|||
WorkWeixinAuthenticationHandler, |
|||
WeComAuthHandlerOptionsProvider>() |
|||
.AddBilibili(options => |
|||
{ |
|||
options.ClientId = "ClientId"; |
|||
options.ClientSecret = "ClientSecret"; |
|||
}).UseSettingProvider< |
|||
BilibiliAuthenticationOptions, |
|||
BilibiliAuthenticationHandler, |
|||
BilibiliAuthHandlerOptionsProvider>(); |
|||
} |
|||
} |
|||
@ -0,0 +1,81 @@ |
|||
using Microsoft.AspNetCore.Authentication; |
|||
using Microsoft.AspNetCore.Http; |
|||
using System; |
|||
using System.Security.Claims; |
|||
using System.Threading.Tasks; |
|||
|
|||
namespace LINGYUN.Abp.Account.Web.OAuth.ExternalProviders; |
|||
|
|||
public class AccountAuthenticationRequestHandler<TOptions, THandler> : IAuthenticationRequestHandler |
|||
where TOptions : RemoteAuthenticationOptions, new() |
|||
where THandler : RemoteAuthenticationHandler<TOptions> |
|||
{ |
|||
protected THandler InnerHandler { get; } |
|||
protected IOAuthHandlerOptionsProvider<TOptions> OptionsProvider { get; } |
|||
public AccountAuthenticationRequestHandler( |
|||
THandler innerHandler, |
|||
IOAuthHandlerOptionsProvider<TOptions> optionsProvider) |
|||
{ |
|||
InnerHandler = innerHandler; |
|||
OptionsProvider = optionsProvider; |
|||
} |
|||
|
|||
public virtual async Task InitializeAsync(AuthenticationScheme scheme, HttpContext context) |
|||
{ |
|||
await InnerHandler.InitializeAsync(scheme, context); |
|||
} |
|||
|
|||
public virtual async Task<AuthenticateResult> AuthenticateAsync() |
|||
{ |
|||
return await InnerHandler.AuthenticateAsync(); |
|||
} |
|||
|
|||
public virtual async Task ChallengeAsync(AuthenticationProperties? properties) |
|||
{ |
|||
await InitializeOptionsAsync(); |
|||
|
|||
await InnerHandler.ChallengeAsync(properties); |
|||
} |
|||
|
|||
public virtual async Task ForbidAsync(AuthenticationProperties? properties) |
|||
{ |
|||
await InnerHandler.ForbidAsync(properties); |
|||
} |
|||
|
|||
public async Task SignOutAsync(AuthenticationProperties properties) |
|||
{ |
|||
if (!(InnerHandler is IAuthenticationSignOutHandler signOutHandler)) |
|||
{ |
|||
throw new InvalidOperationException($"The authentication handler registered for scheme '{InnerHandler.Scheme}' is '{InnerHandler.GetType().Name}' which cannot be used for SignOutAsync"); |
|||
} |
|||
|
|||
await InitializeOptionsAsync(); |
|||
await signOutHandler.SignOutAsync(properties); |
|||
} |
|||
|
|||
public async Task SignInAsync(ClaimsPrincipal user, AuthenticationProperties properties) |
|||
{ |
|||
if (!(InnerHandler is IAuthenticationSignInHandler signInHandler)) |
|||
{ |
|||
throw new InvalidOperationException($"The authentication handler registered for scheme '{InnerHandler.Scheme}' is '{InnerHandler.GetType().Name}' which cannot be used for SignInAsync"); |
|||
} |
|||
|
|||
await InitializeOptionsAsync(); |
|||
await signInHandler.SignInAsync(user, properties); |
|||
} |
|||
|
|||
public virtual async Task<bool> HandleRequestAsync() |
|||
{ |
|||
if (await InnerHandler.ShouldHandleRequestAsync()) |
|||
{ |
|||
await InitializeOptionsAsync(); |
|||
} |
|||
|
|||
return await InnerHandler.HandleRequestAsync(); |
|||
} |
|||
|
|||
protected async virtual Task InitializeOptionsAsync() |
|||
{ |
|||
await OptionsProvider.SetOptionsAsync(InnerHandler.Options); |
|||
} |
|||
} |
|||
@ -0,0 +1,29 @@ |
|||
using AspNet.Security.OAuth.Bilibili; |
|||
using LINGYUN.Abp.Account.OAuth.Settings; |
|||
using System; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp.Settings; |
|||
|
|||
namespace LINGYUN.Abp.Account.Web.OAuth.ExternalProviders.Bilibili; |
|||
|
|||
public class BilibiliAuthHandlerOptionsProvider : OAuthHandlerOptionsProvider<BilibiliAuthenticationOptions> |
|||
{ |
|||
public BilibiliAuthHandlerOptionsProvider(ISettingProvider settingProvider) : base(settingProvider) |
|||
{ |
|||
} |
|||
|
|||
public async override Task SetOptionsAsync(BilibiliAuthenticationOptions options) |
|||
{ |
|||
var clientId = await SettingProvider.GetOrNullAsync(AccountOAuthSettingNames.Bilibili.ClientId); |
|||
var clientSecret = await SettingProvider.GetOrNullAsync(AccountOAuthSettingNames.Bilibili.ClientSecret); |
|||
|
|||
if (!clientId.IsNullOrWhiteSpace()) |
|||
{ |
|||
options.ClientId = clientId; |
|||
} |
|||
if (!clientSecret.IsNullOrWhiteSpace()) |
|||
{ |
|||
options.ClientSecret = clientSecret; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,29 @@ |
|||
using AspNet.Security.OAuth.GitHub; |
|||
using LINGYUN.Abp.Account.OAuth.Settings; |
|||
using System; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp.Settings; |
|||
|
|||
namespace LINGYUN.Abp.Account.Web.OAuth.ExternalProviders.GitHub; |
|||
|
|||
public class GitHubAuthHandlerOptionsProvider : OAuthHandlerOptionsProvider<GitHubAuthenticationOptions> |
|||
{ |
|||
public GitHubAuthHandlerOptionsProvider(ISettingProvider settingProvider) : base(settingProvider) |
|||
{ |
|||
} |
|||
|
|||
public async override Task SetOptionsAsync(GitHubAuthenticationOptions options) |
|||
{ |
|||
var clientId = await SettingProvider.GetOrNullAsync(AccountOAuthSettingNames.GitHub.ClientId); |
|||
var clientSecret = await SettingProvider.GetOrNullAsync(AccountOAuthSettingNames.GitHub.ClientSecret); |
|||
|
|||
if (!clientId.IsNullOrWhiteSpace()) |
|||
{ |
|||
options.ClientId = clientId; |
|||
} |
|||
if (!clientSecret.IsNullOrWhiteSpace()) |
|||
{ |
|||
options.ClientSecret = clientSecret; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,10 @@ |
|||
using Microsoft.AspNetCore.Authentication; |
|||
using System.Threading.Tasks; |
|||
|
|||
namespace LINGYUN.Abp.Account.Web.OAuth.ExternalProviders; |
|||
|
|||
public interface IOAuthHandlerOptionsProvider<TOptions> |
|||
where TOptions : RemoteAuthenticationOptions, new() |
|||
{ |
|||
Task SetOptionsAsync(TOptions options); |
|||
} |
|||
@ -0,0 +1,68 @@ |
|||
using AspNet.Security.OAuth.Bilibili; |
|||
using AspNet.Security.OAuth.GitHub; |
|||
using AspNet.Security.OAuth.QQ; |
|||
using AspNet.Security.OAuth.Weixin; |
|||
using AspNet.Security.OAuth.WorkWeixin; |
|||
using LINGYUN.Abp.Account.OAuth.Features; |
|||
using LINGYUN.Abp.Account.Web.ExternalProviders; |
|||
using LINGYUN.Abp.Account.Web.Models; |
|||
using LINGYUN.Abp.Account.Web.OAuth.Pages.Account.Components.ExternalProviders; |
|||
using Microsoft.AspNetCore.Authentication; |
|||
using Microsoft.Extensions.Localization; |
|||
using System.Collections.Generic; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp.Account.Localization; |
|||
using Volo.Abp.DependencyInjection; |
|||
using Volo.Abp.Features; |
|||
|
|||
namespace LINGYUN.Abp.Account.Web.OAuth.ExternalProviders; |
|||
|
|||
public class OAuthExternalProviderService : IExternalProviderService, ITransientDependency |
|||
{ |
|||
private static readonly Dictionary<string, string> _providerFeaturesMap = new Dictionary<string, string> |
|||
{ |
|||
[GitHubAuthenticationDefaults.AuthenticationScheme] = AccountOAuthFeatureNames.GitHub.Enable, |
|||
[QQAuthenticationDefaults.AuthenticationScheme] = AccountOAuthFeatureNames.QQ.Enable, |
|||
[WeixinAuthenticationDefaults.AuthenticationScheme] = AccountOAuthFeatureNames.WeChat.Enable, |
|||
[WorkWeixinAuthenticationDefaults.AuthenticationScheme] = AccountOAuthFeatureNames.WeCom.Enable, |
|||
[BilibiliAuthenticationDefaults.AuthenticationScheme] = AccountOAuthFeatureNames.Bilibili.Enable |
|||
}; |
|||
|
|||
private readonly IFeatureChecker _featureChecker; |
|||
private readonly IStringLocalizer<AccountResource> _stringLocalizer; |
|||
private readonly IAuthenticationSchemeProvider _authenticationSchemeProvider; |
|||
public OAuthExternalProviderService( |
|||
IFeatureChecker featureChecker, |
|||
IStringLocalizer<AccountResource> stringLocalizer, |
|||
IAuthenticationSchemeProvider authenticationSchemeProvider) |
|||
{ |
|||
_featureChecker = featureChecker; |
|||
_stringLocalizer = stringLocalizer; |
|||
_authenticationSchemeProvider = authenticationSchemeProvider; |
|||
} |
|||
public async virtual Task<List<ExternalLoginProviderModel>> GetAllAsync() |
|||
{ |
|||
var models = new List<ExternalLoginProviderModel>(); |
|||
|
|||
var schemas = await _authenticationSchemeProvider.GetAllSchemesAsync(); |
|||
|
|||
foreach (var schema in schemas) |
|||
{ |
|||
if (_providerFeaturesMap.TryGetValue(schema.Name, out var schemaFeature)) |
|||
{ |
|||
if (await _featureChecker.IsEnabledAsync(schemaFeature)) |
|||
{ |
|||
models.Add(new ExternalLoginProviderModel |
|||
{ |
|||
Name = schema.Name, |
|||
AuthenticationScheme = schema.Name, |
|||
DisplayName = _stringLocalizer[$"OAuth:{schema.Name}"], |
|||
ComponentType = typeof(ExternalProviderViewComponent), |
|||
}); |
|||
} |
|||
} |
|||
} |
|||
|
|||
return models; |
|||
} |
|||
} |
|||
@ -0,0 +1,18 @@ |
|||
using Microsoft.AspNetCore.Authentication; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp.DependencyInjection; |
|||
using Volo.Abp.Settings; |
|||
|
|||
namespace LINGYUN.Abp.Account.Web.OAuth.ExternalProviders; |
|||
|
|||
public abstract class OAuthHandlerOptionsProvider<TOptions> : IOAuthHandlerOptionsProvider<TOptions>, ITransientDependency |
|||
where TOptions : RemoteAuthenticationOptions, new() |
|||
{ |
|||
protected ISettingProvider SettingProvider { get; } |
|||
public OAuthHandlerOptionsProvider(ISettingProvider settingProvider) |
|||
{ |
|||
SettingProvider = settingProvider; |
|||
} |
|||
|
|||
public abstract Task SetOptionsAsync(TOptions options); |
|||
} |
|||
@ -0,0 +1,29 @@ |
|||
using AspNet.Security.OAuth.QQ; |
|||
using LINGYUN.Abp.Tencent.QQ.Settings; |
|||
using System; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp.Settings; |
|||
|
|||
namespace LINGYUN.Abp.Account.Web.OAuth.ExternalProviders.QQ; |
|||
|
|||
public class QQAuthHandlerOptionsProvider : OAuthHandlerOptionsProvider<QQAuthenticationOptions> |
|||
{ |
|||
public QQAuthHandlerOptionsProvider(ISettingProvider settingProvider) : base(settingProvider) |
|||
{ |
|||
} |
|||
|
|||
public async override Task SetOptionsAsync(QQAuthenticationOptions options) |
|||
{ |
|||
var clientId = await SettingProvider.GetOrNullAsync(TencentQQSettingNames.QQConnect.AppId); |
|||
var clientSecret = await SettingProvider.GetOrNullAsync(TencentQQSettingNames.QQConnect.AppKey); |
|||
|
|||
if (!clientId.IsNullOrWhiteSpace()) |
|||
{ |
|||
options.ClientId = clientId; |
|||
} |
|||
if (!clientSecret.IsNullOrWhiteSpace()) |
|||
{ |
|||
options.ClientSecret = clientSecret; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,29 @@ |
|||
using AspNet.Security.OAuth.Weixin; |
|||
using LINGYUN.Abp.WeChat.Official.Settings; |
|||
using System; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp.Settings; |
|||
|
|||
namespace LINGYUN.Abp.Account.Web.OAuth.ExternalProviders.WeChat; |
|||
|
|||
public class WeChatAuthHandlerOptionsProvider : OAuthHandlerOptionsProvider<WeixinAuthenticationOptions> |
|||
{ |
|||
public WeChatAuthHandlerOptionsProvider(ISettingProvider settingProvider) : base(settingProvider) |
|||
{ |
|||
} |
|||
|
|||
public async override Task SetOptionsAsync(WeixinAuthenticationOptions options) |
|||
{ |
|||
var clientId = await SettingProvider.GetOrNullAsync(WeChatOfficialSettingNames.AppId); |
|||
var clientSecret = await SettingProvider.GetOrNullAsync(WeChatOfficialSettingNames.AppSecret); |
|||
|
|||
if (!clientId.IsNullOrWhiteSpace()) |
|||
{ |
|||
options.ClientId = clientId; |
|||
} |
|||
if (!clientSecret.IsNullOrWhiteSpace()) |
|||
{ |
|||
options.ClientSecret = clientSecret; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,34 @@ |
|||
using AspNet.Security.OAuth.WorkWeixin; |
|||
using LINGYUN.Abp.WeChat.Work.Settings; |
|||
using System; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp.Settings; |
|||
|
|||
namespace LINGYUN.Abp.Account.Web.OAuth.ExternalProviders.WeCom; |
|||
|
|||
public class WeComAuthHandlerOptionsProvider : OAuthHandlerOptionsProvider<WorkWeixinAuthenticationOptions> |
|||
{ |
|||
public WeComAuthHandlerOptionsProvider(ISettingProvider settingProvider) : base(settingProvider) |
|||
{ |
|||
} |
|||
|
|||
public async override Task SetOptionsAsync(WorkWeixinAuthenticationOptions options) |
|||
{ |
|||
var clientId = await SettingProvider.GetOrNullAsync(WeChatWorkSettingNames.Connection.CorpId); |
|||
var clientSecret = await SettingProvider.GetOrNullAsync(WeChatWorkSettingNames.Connection.Secret); |
|||
var agentId = await SettingProvider.GetOrNullAsync(WeChatWorkSettingNames.Connection.AgentId); |
|||
|
|||
if (!clientId.IsNullOrWhiteSpace()) |
|||
{ |
|||
options.ClientId = clientId; |
|||
} |
|||
if (!clientSecret.IsNullOrWhiteSpace()) |
|||
{ |
|||
options.ClientSecret = clientSecret; |
|||
} |
|||
if (!agentId.IsNullOrWhiteSpace()) |
|||
{ |
|||
options.AgentId = agentId; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,3 @@ |
|||
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd"> |
|||
<ConfigureAwait ContinueOnCapturedContext="false" /> |
|||
</Weavers> |
|||
@ -0,0 +1,30 @@ |
|||
<?xml version="1.0" encoding="utf-8"?> |
|||
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> |
|||
<!-- This file was generated by Fody. Manual changes to this file will be lost when your project is rebuilt. --> |
|||
<xs:element name="Weavers"> |
|||
<xs:complexType> |
|||
<xs:all> |
|||
<xs:element name="ConfigureAwait" minOccurs="0" maxOccurs="1"> |
|||
<xs:complexType> |
|||
<xs:attribute name="ContinueOnCapturedContext" type="xs:boolean" /> |
|||
</xs:complexType> |
|||
</xs:element> |
|||
</xs:all> |
|||
<xs:attribute name="VerifyAssembly" type="xs:boolean"> |
|||
<xs:annotation> |
|||
<xs:documentation>'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed.</xs:documentation> |
|||
</xs:annotation> |
|||
</xs:attribute> |
|||
<xs:attribute name="VerifyIgnoreCodes" type="xs:string"> |
|||
<xs:annotation> |
|||
<xs:documentation>A comma-separated list of error codes that can be safely ignored in assembly verification.</xs:documentation> |
|||
</xs:annotation> |
|||
</xs:attribute> |
|||
<xs:attribute name="GenerateXsd" type="xs:boolean"> |
|||
<xs:annotation> |
|||
<xs:documentation>'false' to turn off automatic generation of the XML Schema file.</xs:documentation> |
|||
</xs:annotation> |
|||
</xs:attribute> |
|||
</xs:complexType> |
|||
</xs:element> |
|||
</xs:schema> |
|||
@ -0,0 +1,44 @@ |
|||
<Project Sdk="Microsoft.NET.Sdk.Web"> |
|||
|
|||
<Import Project="..\..\..\..\configureawait.props" /> |
|||
<Import Project="..\..\..\..\common.props" /> |
|||
|
|||
<PropertyGroup> |
|||
<TargetFramework>net9.0</TargetFramework> |
|||
<AssemblyName>LINGYUN.Abp.Account.Web.OAuth</AssemblyName> |
|||
<PackageId>LINGYUN.Abp.Account.Web.OAuth</PackageId> |
|||
<GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute> |
|||
<GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute> |
|||
<GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute> |
|||
<RootNamespace>LINGYUN.Abp.Account.Web.OAuth</RootNamespace> |
|||
<OutputType>Library</OutputType> |
|||
<IsPackable>true</IsPackable> |
|||
<Nullable>enable</Nullable> |
|||
</PropertyGroup> |
|||
|
|||
<ItemGroup> |
|||
<EmbeddedResource Include="wwwroot\**\*.js" /> |
|||
<EmbeddedResource Include="wwwroot\**\*.css" /> |
|||
<EmbeddedResource Include="wwwroot\**\*.png" /> |
|||
<Content Remove="wwwroot\**\*.js" /> |
|||
<Content Remove="wwwroot\**\*.css" /> |
|||
<Content Remove="wwwroot\**\*.png" /> |
|||
</ItemGroup> |
|||
|
|||
<ItemGroup> |
|||
<PackageReference Include="AspNet.Security.OAuth.Bilibili" /> |
|||
<PackageReference Include="AspNet.Security.OAuth.GitHub" /> |
|||
<PackageReference Include="AspNet.Security.OAuth.QQ" /> |
|||
<PackageReference Include="AspNet.Security.OAuth.Weixin" /> |
|||
<PackageReference Include="AspNet.Security.OAuth.WorkWeixin" /> |
|||
</ItemGroup> |
|||
|
|||
<ItemGroup> |
|||
<ProjectReference Include="..\..\..\framework\cloud-tencent\LINGYUN.Abp.Tencent.QQ\LINGYUN.Abp.Tencent.QQ.csproj" /> |
|||
<ProjectReference Include="..\..\..\framework\wechat\LINGYUN.Abp.WeChat.Official\LINGYUN.Abp.WeChat.Official.csproj" /> |
|||
<ProjectReference Include="..\..\..\framework\wechat\LINGYUN.Abp.WeChat.Work\LINGYUN.Abp.WeChat.Work.csproj" /> |
|||
<ProjectReference Include="..\LINGYUN.Abp.Account.OAuth\LINGYUN.Abp.Account.OAuth.csproj" /> |
|||
<ProjectReference Include="..\LINGYUN.Abp.Account.Web\LINGYUN.Abp.Account.Web.csproj" /> |
|||
</ItemGroup> |
|||
|
|||
</Project> |
|||
@ -0,0 +1,32 @@ |
|||
using JetBrains.Annotations; |
|||
using LINGYUN.Abp.Account.Web.OAuth.ExternalProviders; |
|||
using Microsoft.AspNetCore.Authentication; |
|||
using Microsoft.Extensions.DependencyInjection; |
|||
using Microsoft.Extensions.DependencyInjection.Extensions; |
|||
using System; |
|||
using System.Linq; |
|||
using Volo.Abp; |
|||
|
|||
namespace LINGYUN.Abp.Account.Web.OAuth.Microsoft.Extensions.DependencyInjection; |
|||
|
|||
public static class AuthenticationBuilderExtensions |
|||
{ |
|||
public static AuthenticationBuilder UseSettingProvider<TOptions, THandler, TOptionsProvider>( |
|||
[NotNull] this AuthenticationBuilder authenticationBuilder) |
|||
where TOptions : RemoteAuthenticationOptions, new() |
|||
where THandler : RemoteAuthenticationHandler<TOptions> |
|||
where TOptionsProvider : IOAuthHandlerOptionsProvider<TOptions> |
|||
{ |
|||
Check.NotNull(authenticationBuilder, nameof(authenticationBuilder)); |
|||
|
|||
var handler = authenticationBuilder.Services.LastOrDefault(x => x.ServiceType == typeof(THandler)); |
|||
authenticationBuilder.Services.Replace(new ServiceDescriptor( |
|||
typeof(THandler), |
|||
provider => new AccountAuthenticationRequestHandler<TOptions, THandler>( |
|||
(THandler)ActivatorUtilities.CreateInstance(provider, typeof(THandler)), |
|||
provider.GetRequiredService<TOptionsProvider>()), |
|||
handler?.Lifetime ?? ServiceLifetime.Transient)); |
|||
|
|||
return authenticationBuilder; |
|||
} |
|||
} |
|||
@ -0,0 +1,14 @@ |
|||
@using Microsoft.AspNetCore.Mvc.Localization |
|||
@using Volo.Abp.Account.Localization |
|||
@inject IHtmlLocalizer<AccountResource> L |
|||
@model LINGYUN.Abp.Account.Web.Models.ExternalLoginProviderModel |
|||
|
|||
<button |
|||
type="submit" |
|||
class="btn btn-outline-secondary m-1" |
|||
name="provider" |
|||
value="@Model.AuthenticationScheme" |
|||
title="@L["LogInUsingYourProviderAccount", @Model.DisplayName]"> |
|||
<img src="~/images/bilibili_logo_18x18.png" /> |
|||
<span>@Model.DisplayName</span> |
|||
</button> |
|||
@ -0,0 +1,13 @@ |
|||
using LINGYUN.Abp.Account.Web.Models; |
|||
using Microsoft.AspNetCore.Mvc; |
|||
using Volo.Abp.AspNetCore.Mvc; |
|||
|
|||
namespace LINGYUN.Abp.Account.Web.OAuth.Pages.Account.Components.ExternalProviders; |
|||
|
|||
public class ExternalProviderViewComponent : AbpViewComponent |
|||
{ |
|||
public virtual IViewComponentResult Invoke(ExternalLoginProviderModel model) |
|||
{ |
|||
return View($"~/Pages/Account/Components/ExternalProviders/{model.AuthenticationScheme}/Default.cshtml", model); |
|||
} |
|||
} |
|||
@ -0,0 +1,14 @@ |
|||
@using Microsoft.AspNetCore.Mvc.Localization |
|||
@using Volo.Abp.Account.Localization |
|||
@inject IHtmlLocalizer<AccountResource> L |
|||
@model LINGYUN.Abp.Account.Web.Models.ExternalLoginProviderModel |
|||
|
|||
<button |
|||
type="submit" |
|||
class="btn btn-outline-secondary m-1" |
|||
name="provider" |
|||
value="@Model.AuthenticationScheme" |
|||
title="@L["LogInUsingYourProviderAccount", @Model.DisplayName]"> |
|||
<i class="fa fa-github"></i> |
|||
<span>@Model.DisplayName</span> |
|||
</button> |
|||
@ -0,0 +1,14 @@ |
|||
@using Microsoft.AspNetCore.Mvc.Localization |
|||
@using Volo.Abp.Account.Localization |
|||
@inject IHtmlLocalizer<AccountResource> L |
|||
@model LINGYUN.Abp.Account.Web.Models.ExternalLoginProviderModel |
|||
|
|||
<button |
|||
type="submit" |
|||
class="btn btn-outline-secondary m-1" |
|||
name="provider" |
|||
value="@Model.AuthenticationScheme" |
|||
title="@L["LogInUsingYourProviderAccount", @Model.DisplayName]"> |
|||
<img src="~/images/qq_logo_15x18.png" /> |
|||
<span>@Model.DisplayName</span> |
|||
</button> |
|||
@ -0,0 +1,14 @@ |
|||
@using Microsoft.AspNetCore.Mvc.Localization |
|||
@using Volo.Abp.Account.Localization |
|||
@inject IHtmlLocalizer<AccountResource> L |
|||
@model LINGYUN.Abp.Account.Web.Models.ExternalLoginProviderModel |
|||
|
|||
<button |
|||
type="submit" |
|||
class="btn btn-outline-secondary m-1" |
|||
name="provider" |
|||
value="@Model.AuthenticationScheme" |
|||
title="@L["LogInUsingYourProviderAccount", @Model.DisplayName]"> |
|||
<i class="fa fa-weixin"></i> |
|||
<span>@Model.DisplayName</span> |
|||
</button> |
|||
@ -0,0 +1,13 @@ |
|||
@using Microsoft.AspNetCore.Mvc.Localization |
|||
@using Volo.Abp.Account.Localization |
|||
@inject IHtmlLocalizer<AccountResource> L |
|||
@model LINGYUN.Abp.Account.Web.Models.ExternalLoginProviderModel |
|||
|
|||
<button |
|||
type="submit" |
|||
class="btn btn-outline-secondary m-1" |
|||
name="provider" |
|||
value="@Model.AuthenticationScheme" |
|||
title="@L["LogInUsingYourProviderAccount", @Model.DisplayName]"> |
|||
<img src="~/images/wecom_logo_77x18.png" /> |
|||
</button> |
|||
@ -0,0 +1,12 @@ |
|||
{ |
|||
"profiles": { |
|||
"LINGYUN.Abp.Account.Web.OAuth": { |
|||
"commandName": "Project", |
|||
"launchBrowser": true, |
|||
"environmentVariables": { |
|||
"ASPNETCORE_ENVIRONMENT": "Development" |
|||
}, |
|||
"applicationUrl": "https://localhost:50897;http://localhost:50898" |
|||
} |
|||
} |
|||
} |
|||
|
After Width: | Height: | Size: 2.0 KiB |
|
After Width: | Height: | Size: 628 B |
|
After Width: | Height: | Size: 1022 B |
@ -0,0 +1,10 @@ |
|||
using LINGYUN.Abp.Account.Web.Models; |
|||
using System.Collections.Generic; |
|||
using System.Threading.Tasks; |
|||
|
|||
namespace LINGYUN.Abp.Account.Web.ExternalProviders; |
|||
|
|||
public interface IExternalProviderService |
|||
{ |
|||
Task<List<ExternalLoginProviderModel>> GetAllAsync(); |
|||
} |
|||
@ -0,0 +1,11 @@ |
|||
using System; |
|||
|
|||
namespace LINGYUN.Abp.Account.Web.Models; |
|||
|
|||
public class ExternalLoginProviderModel |
|||
{ |
|||
public Type ComponentType { get; set; } |
|||
public string Name { get; set; } |
|||
public string DisplayName { get; set; } |
|||
public string AuthenticationScheme { get; set; } |
|||
} |
|||
Loading…
Reference in new issue