Browse Source

add inter-service invocation interface authorization cache

pull/21/head
cKey 6 years ago
parent
commit
8afad1fd21
  1. 2
      aspnet-core/modules/common/LINGYUN.Abp.BlobStoring.Qiniu/LINGYUN.Abp.BlobStoring.Qiniu.csproj
  2. 20
      aspnet-core/modules/common/LINGYUN.Abp.IdentityModel/LINGYUN.Abp.IdentityModel.csproj
  3. 13
      aspnet-core/modules/common/LINGYUN.Abp.IdentityModel/LINGYUN/Abp/IdentityModel/AbpCachedIdentityModelModule.cs
  4. 27
      aspnet-core/modules/common/LINGYUN.Abp.IdentityModel/LINGYUN/Abp/IdentityModel/IdentityModelAuthenticationCacheItem.cs
  5. 107
      aspnet-core/modules/common/LINGYUN.Abp.IdentityModel/LINGYUN/Abp/IdentityModel/IdentityModelCachedAuthenticationService.cs
  6. 19
      aspnet-core/modules/common/LINGYUN.Abp.IdentityModel/README.md

2
aspnet-core/modules/common/LINGYUN.Abp.BlobStoring.Qiniu/LINGYUN.Abp.BlobStoring.Qiniu.csproj

@ -5,7 +5,7 @@
<RootNamespace /><GeneratePackageOnBuild>true</GeneratePackageOnBuild>
<Version>3.0.0</Version>
<Authors>LINGYUN</Authors>
<Description>阿里云Oss对象存储Abp集成</Description>
<Description>七牛云Oss对象存储Abp集成</Description>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">

20
aspnet-core/modules/common/LINGYUN.Abp.IdentityModel/LINGYUN.Abp.IdentityModel.csproj

@ -0,0 +1,20 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<RootNamespace />
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
<Version>3.0.0</Version>
<Authors>LINGYUN</Authors>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
<OutputPath>D:\LocalNuget</OutputPath>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Volo.Abp.Caching" Version="3.0.0" />
<PackageReference Include="Volo.Abp.IdentityModel" Version="3.0.0" />
</ItemGroup>
</Project>

13
aspnet-core/modules/common/LINGYUN.Abp.IdentityModel/LINGYUN/Abp/IdentityModel/AbpCachedIdentityModelModule.cs

@ -0,0 +1,13 @@
using Volo.Abp.IdentityModel;
using Volo.Abp.Modularity;
using Volo.Abp.Security;
namespace LINGYUN.Abp.IdentityModel
{
[DependsOn(
typeof(AbpIdentityModelModule),
typeof(AbpSecurityModule))]
public class AbpCachedIdentityModelModule : AbpModule
{
}
}

27
aspnet-core/modules/common/LINGYUN.Abp.IdentityModel/LINGYUN/Abp/IdentityModel/IdentityModelAuthenticationCacheItem.cs

@ -0,0 +1,27 @@
using System;
namespace LINGYUN.Abp.IdentityModel
{
public class IdentityModelAuthenticationCacheItem
{
public string AccessToken { get; set; }
public IdentityModelAuthenticationCacheItem()
{
}
public IdentityModelAuthenticationCacheItem(string accessToken)
{
AccessToken = accessToken;
}
public static string CalculateCacheKey(string grantType, string clientId, string userName = null)
{
if (userName.IsNullOrWhiteSpace())
{
return "gt:" + grantType + ",ci:" + clientId;
}
return "gt:" + grantType + ",ci:" + clientId + ",un:" + userName;
}
}
}

107
aspnet-core/modules/common/LINGYUN.Abp.IdentityModel/LINGYUN/Abp/IdentityModel/IdentityModelCachedAuthenticationService.cs

@ -0,0 +1,107 @@
using IdentityModel.Client;
using Microsoft.Extensions.Caching.Distributed;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using System;
using System.Net.Http;
using System.Threading.Tasks;
using Volo.Abp;
using Volo.Abp.Caching;
using Volo.Abp.DependencyInjection;
using Volo.Abp.IdentityModel;
using Volo.Abp.MultiTenancy;
using Volo.Abp.Security.Encryption;
using Volo.Abp.Threading;
namespace LINGYUN.Abp.IdentityModel
{
[Dependency(ServiceLifetime.Transient, ReplaceServices = true)]
[ExposeServices(
typeof(IIdentityModelAuthenticationService),
typeof(IdentityModelAuthenticationService))]
public class IdentityModelCachedAuthenticationService : IdentityModelAuthenticationService
{
protected IStringEncryptionService EncryptionService { get; }
protected IDistributedCache<IdentityModelAuthenticationCacheItem> Cache { get; }
public IdentityModelCachedAuthenticationService(
IOptions<AbpIdentityClientOptions> options,
ICancellationTokenProvider cancellationTokenProvider,
IHttpClientFactory httpClientFactory,
ICurrentTenant currentTenant,
IStringEncryptionService encryptionService,
IDistributedCache<IdentityModelAuthenticationCacheItem> cache,
IOptions<IdentityModelHttpRequestMessageOptions> identityModelHttpRequestMessageOptions)
: base(options, cancellationTokenProvider, httpClientFactory, currentTenant, identityModelHttpRequestMessageOptions)
{
Cache = cache;
EncryptionService = encryptionService;
}
public override async Task<string> GetAccessTokenAsync(IdentityClientConfiguration configuration)
{
var accessTokenCacheItem = await GetCacheItemAsync(configuration);
// 需要解密
return EncryptionService.Decrypt(accessTokenCacheItem.AccessToken);
}
protected virtual async Task<IdentityModelAuthenticationCacheItem> GetCacheItemAsync(IdentityClientConfiguration configuration)
{
var cacheKey = IdentityModelAuthenticationCacheItem.CalculateCacheKey(configuration.GrantType, configuration.ClientId, configuration.UserName);
Logger.LogDebug($"IdentityModelCachedAuthenticationService.GetCacheItemAsync: {cacheKey}");
var cacheItem = await Cache.GetAsync(cacheKey);
if (cacheItem != null)
{
Logger.LogDebug($"Found in the cache: {cacheKey}");
return cacheItem;
}
Logger.LogDebug($"Not found in the cache: {cacheKey}");
var tokenResponse = await GetAccessTokenResponseAsync(configuration);
// 需要加密
var accessToken = EncryptionService.Encrypt(tokenResponse.AccessToken);
cacheItem = new IdentityModelAuthenticationCacheItem(accessToken);
var cacheEntryOptions = new DistributedCacheEntryOptions
{
// 缓存前两分钟过期
AbsoluteExpiration = DateTimeOffset.Now.AddSeconds(tokenResponse.ExpiresIn - 120)
};
Logger.LogDebug($"Setting the cache item: {cacheKey}");
await Cache.SetAsync(cacheKey, cacheItem, cacheEntryOptions);
Logger.LogDebug($"Finished setting the cache item: {cacheKey}");
return cacheItem;
}
protected virtual async Task<TokenResponse> GetAccessTokenResponseAsync(IdentityClientConfiguration configuration)
{
var discoveryResponse = await GetDiscoveryResponse(configuration);
if (discoveryResponse.IsError)
{
throw new AbpException($"Could not retrieve the OpenId Connect discovery document! ErrorType: {discoveryResponse.ErrorType}. Error: {discoveryResponse.Error}");
}
var tokenResponse = await GetTokenResponse(discoveryResponse, configuration);
if (tokenResponse.IsError)
{
if (tokenResponse.ErrorDescription != null)
{
throw new AbpException($"Could not get token from the OpenId Connect server! ErrorType: {tokenResponse.ErrorType}. Error: {tokenResponse.Error}. ErrorDescription: {tokenResponse.ErrorDescription}. HttpStatusCode: {tokenResponse.HttpStatusCode}");
}
var rawError = tokenResponse.Raw;
var withoutInnerException = rawError.Split(new string[] { "<eof/>" }, StringSplitOptions.RemoveEmptyEntries);
throw new AbpException(withoutInnerException[0]);
}
return tokenResponse;
}
}
}

19
aspnet-core/modules/common/LINGYUN.Abp.IdentityModel/README.md

@ -0,0 +1,19 @@
# LINGYUN.Abp.IdentityModel
abp框架 **IIdentityModelAuthenticationService**接口缓存版本
因官方**Volo.Abp.IdentityModel**模块没有对接口授权缓存,每次内部调用都会请求IDS服务器,会加重IDS服务器压力,
创建使用缓存的接口实现
## 配置使用
模块按需引用,需要配置**Volo.Abp.IdentityModel**模块所需配置项
```csharp
[DependsOn(typeof(AbpCachedIdentityModelModule))]
public class YouProjectModule : AbpModule
{
// other
}
```
Loading…
Cancel
Save