Browse Source

feat: add link user login support

pull/501/head
cKey 4 years ago
parent
commit
b063162d24
  1. 7
      aspnet-core/LINGYUN.MicroService.All.sln
  2. 23
      aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.LinkUser/LINGYUN.Abp.IdentityServer.LinkUser.csproj
  3. 37
      aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.LinkUser/LINGYUN/Abp/IdentityServer/LinkUser/AbpIdentityServerLinkUserModule.cs
  4. 148
      aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.LinkUser/LINGYUN/Abp/IdentityServer/LinkUser/LinkUserGrantValidator.cs
  5. 8
      aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.LinkUser/LINGYUN/Abp/IdentityServer/LinkUser/Localization/en.json
  6. 8
      aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.LinkUser/LINGYUN/Abp/IdentityServer/LinkUser/Localization/zh-Hans.json

7
aspnet-core/LINGYUN.MicroService.All.sln

@ -380,6 +380,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.BlobStoring.Ten
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.OssManagement.Tencent", "modules\oss-management\LINGYUN.Abp.OssManagement.Tencent\LINGYUN.Abp.OssManagement.Tencent.csproj", "{31E60E23-FD98-4D5E-A137-2B3F2968BA09}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LINGYUN.Abp.IdentityServer.LinkUser", "modules\identityServer\LINGYUN.Abp.IdentityServer.LinkUser\LINGYUN.Abp.IdentityServer.LinkUser.csproj", "{25378F9D-2A66-4568-AAC6-E9282ACA3DD3}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@ -982,6 +984,10 @@ Global
{31E60E23-FD98-4D5E-A137-2B3F2968BA09}.Debug|Any CPU.Build.0 = Debug|Any CPU
{31E60E23-FD98-4D5E-A137-2B3F2968BA09}.Release|Any CPU.ActiveCfg = Release|Any CPU
{31E60E23-FD98-4D5E-A137-2B3F2968BA09}.Release|Any CPU.Build.0 = Release|Any CPU
{25378F9D-2A66-4568-AAC6-E9282ACA3DD3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{25378F9D-2A66-4568-AAC6-E9282ACA3DD3}.Debug|Any CPU.Build.0 = Debug|Any CPU
{25378F9D-2A66-4568-AAC6-E9282ACA3DD3}.Release|Any CPU.ActiveCfg = Release|Any CPU
{25378F9D-2A66-4568-AAC6-E9282ACA3DD3}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@ -1167,6 +1173,7 @@ Global
{8FE2725C-6829-4778-93BA-A53260697AFB} = {3B96F4D8-4993-419B-BCEB-AFE4ED39449F}
{A4B972EC-9F0B-4405-9965-766FABC9B07E} = {3B96F4D8-4993-419B-BCEB-AFE4ED39449F}
{31E60E23-FD98-4D5E-A137-2B3F2968BA09} = {B05CB08F-C088-4D6D-97EE-A94A5D1AE4A6}
{25378F9D-2A66-4568-AAC6-E9282ACA3DD3} = {0439B173-F41E-4CE0-A44A-CCB70328F272}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {C95FDF91-16F2-4A8B-A4BE-0E62D1B66718}

23
aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.LinkUser/LINGYUN.Abp.IdentityServer.LinkUser.csproj

@ -0,0 +1,23 @@
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="..\..\..\configureawait.props" />
<Import Project="..\..\..\common.props" />
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<RootNamespace />
</PropertyGroup>
<ItemGroup>
<None Remove="LINGYUN\Abp\IdentityServer\LinkUser\Localization\*.json" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="LINGYUN\Abp\IdentityServer\LinkUser\Localization\*.json" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Volo.Abp.IdentityServer.Domain" Version="$(VoloAbpPackageVersion)" />
</ItemGroup>
</Project>

37
aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.LinkUser/LINGYUN/Abp/IdentityServer/LinkUser/AbpIdentityServerLinkUserModule.cs

@ -0,0 +1,37 @@
using Microsoft.Extensions.DependencyInjection;
using Volo.Abp.IdentityServer;
using Volo.Abp.IdentityServer.Localization;
using Volo.Abp.Localization;
using Volo.Abp.Modularity;
using Volo.Abp.VirtualFileSystem;
namespace LINGYUN.Abp.IdentityServer.LinkUser;
[DependsOn(typeof(AbpIdentityServerDomainModule))]
public class AbpIdentityServerLinkUserModule : AbpModule
{
public override void PreConfigureServices(ServiceConfigurationContext context)
{
var configuration = context.Services.GetConfiguration();
PreConfigure<IIdentityServerBuilder>(builder =>
{
builder.AddExtensionGrantValidator<LinkUserGrantValidator>();
});
}
public override void ConfigureServices(ServiceConfigurationContext context)
{
Configure<AbpVirtualFileSystemOptions>(options =>
{
options.FileSets.AddEmbedded<AbpIdentityServerLinkUserModule>();
});
Configure<AbpLocalizationOptions>(options =>
{
options.Resources
.Get<AbpIdentityServerResource>()
.AddVirtualJson("/LINGYUN/Abp/IdentityServer/LinkUser/Localization");
});
}
}

148
aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.LinkUser/LINGYUN/Abp/IdentityServer/LinkUser/LinkUserGrantValidator.cs

@ -0,0 +1,148 @@
using IdentityServer4.Validation;
using Microsoft.Extensions.Localization;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Security.Claims;
using System.Threading.Tasks;
using Volo.Abp.Identity;
using Volo.Abp.IdentityServer.Localization;
using Volo.Abp.MultiTenancy;
using Volo.Abp.Security.Claims;
using Volo.Abp.Users;
namespace LINGYUN.Abp.IdentityServer.LinkUser;
public class LinkUserGrantValidator : IExtensionGrantValidator
{
public const string ExtensionGrantType = "link_user";
public string GrantType => ExtensionGrantType;
protected ITokenValidator TokenValidator { get; }
protected IdentityLinkUserManager IdentityLinkUserManager { get; }
protected ICurrentTenant CurrentTenant { get; }
protected ICurrentUser CurrentUser { get; }
protected ICurrentPrincipalAccessor CurrentPrincipalAccessor { get; }
protected IdentityUserManager UserManager { get; }
protected IdentitySecurityLogManager IdentitySecurityLogManager { get; }
protected ILogger<LinkUserGrantValidator> Logger { get; }
protected IStringLocalizer<AbpIdentityServerResource> Localizer { get; }
public LinkUserGrantValidator(
ITokenValidator tokenValidator,
IdentityLinkUserManager identityLinkUserManager,
ICurrentTenant currentTenant,
ICurrentUser currentUser,
IdentityUserManager userManager,
ICurrentPrincipalAccessor currentPrincipalAccessor,
IdentitySecurityLogManager identitySecurityLogManager,
ILogger<LinkUserGrantValidator> logger,
IStringLocalizer<AbpIdentityServerResource> localizer)
{
TokenValidator = tokenValidator;
IdentityLinkUserManager = identityLinkUserManager;
CurrentTenant = currentTenant;
CurrentUser = currentUser;
UserManager = userManager;
CurrentPrincipalAccessor = currentPrincipalAccessor;
IdentitySecurityLogManager = identitySecurityLogManager;
Logger = logger;
Localizer = localizer;
}
public virtual async Task ValidateAsync(ExtensionGrantValidationContext context)
{
var accessToken = context.Request.Raw["access_token"];
if (accessToken.IsNullOrWhiteSpace())
{
context.Result = new GrantValidationResult
{
IsError = true,
Error = Localizer["InvalidAccessToken"]
};
return;
}
var result = await TokenValidator.ValidateAccessTokenAsync(accessToken);
if (result.IsError)
{
context.Result = new GrantValidationResult
{
IsError = true,
Error = result.Error,
ErrorDescription = result.ErrorDescription
};
return;
}
using (CurrentPrincipalAccessor.Change(result.Claims))
{
if (!Guid.TryParse(context.Request.Raw["LinkUserId"], out var linkUserId))
{
context.Result = new GrantValidationResult
{
IsError = true,
Error = Localizer["InvalidLinkUserId"]
};
return;
}
Guid? linkTenantId = null;
if (!context.Request.Raw["LinkTenantId"].IsNullOrWhiteSpace())
{
if (!Guid.TryParse(context.Request.Raw["LinkTenantId"], out var parsedGuid))
{
context.Result = new GrantValidationResult
{
IsError = true,
Error = Localizer["InvalidLinkTenantId"]
};
return;
}
linkTenantId = parsedGuid;
}
var isLinked = await IdentityLinkUserManager.IsLinkedAsync(
new IdentityLinkUserInfo(CurrentUser.GetId(), CurrentTenant.Id),
new IdentityLinkUserInfo(linkUserId, linkTenantId));
if (isLinked)
{
using (CurrentTenant.Change(linkTenantId))
{
var user = await UserManager.GetByIdAsync(linkUserId);
var sub = await UserManager.GetUserIdAsync(user);
var additionalClaims = new List<Claim>();
await AddCustomClaimsAsync(additionalClaims, user, context);
context.Result = new GrantValidationResult(
sub,
GrantType,
additionalClaims.ToArray()
);
}
}
else
{
context.Result = new GrantValidationResult
{
IsError = true,
Error = Localizer["TheTargetUserIsNotLinkedToYou"]
};
}
}
}
protected virtual Task AddCustomClaimsAsync(List<Claim> customClaims, IdentityUser user, ExtensionGrantValidationContext context)
{
if (user.TenantId.HasValue)
{
customClaims.Add(new Claim(AbpClaimTypes.TenantId, user.TenantId?.ToString()));
}
return Task.CompletedTask;
}
}

8
aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.LinkUser/LINGYUN/Abp/IdentityServer/LinkUser/Localization/en.json

@ -0,0 +1,8 @@
{
"culture": "en",
"texts": {
"InvalidAccessToken": "Invalid access token.",
"InvalidLinkUserId": "Invalid link user id.",
"InvalidLinkTenantId": "Invalid link tenant id."
}
}

8
aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.LinkUser/LINGYUN/Abp/IdentityServer/LinkUser/Localization/zh-Hans.json

@ -0,0 +1,8 @@
{
"culture": "zh-Hans",
"texts": {
"InvalidAccessToken": "无效的访问令牌.",
"InvalidLinkUserId": "无效的链接用户标识.",
"InvalidLinkTenantId": "无效的链接租户标识."
}
}
Loading…
Cancel
Save