From 33ad12f89de8892f69f57976159c23fe17814e72 Mon Sep 17 00:00:00 2001 From: Halil ibrahim Kalkan Date: Thu, 3 Jan 2019 16:47:08 +0300 Subject: [PATCH] Resolved #710: Introduce Volo.Abp.Http.Client.IdentityModel package. --- framework/Volo.Abp.sln | 11 ++++- .../AbpHttpClientIdentityModelModule.cs | 12 +++++ .../IdentityModelHttpClientAuthenticator.cs | 44 +++++++++++++++++++ .../Volo.Abp.Http.Client.IdentityModel.csproj | 20 +++++++++ .../HttpClientAuthenticateContext.cs | 23 ++++++++++ .../HttpContextAccessTokenProvider.cs | 24 ---------- .../Authentication/IAccessTokenProvider.cs | 10 ----- .../IHttpClientAuthenticator.cs | 9 ++++ .../NullHttpClientAuthenticator.cs | 14 ++++++ .../DynamicHttpProxyInterceptor.cs | 20 ++++----- nupkg/common.ps1 | 3 +- 11 files changed, 143 insertions(+), 47 deletions(-) create mode 100644 framework/src/Volo.Abp.Http.Client.IdentityModel/NewFolder/Abp/Http/Client/IdentityModel/AbpHttpClientIdentityModelModule.cs create mode 100644 framework/src/Volo.Abp.Http.Client.IdentityModel/NewFolder/Abp/Http/Client/IdentityModel/IdentityModelHttpClientAuthenticator.cs create mode 100644 framework/src/Volo.Abp.Http.Client.IdentityModel/Volo.Abp.Http.Client.IdentityModel.csproj create mode 100644 framework/src/Volo.Abp.Http.Client/Volo/Abp/Http/Client/Authentication/HttpClientAuthenticateContext.cs delete mode 100644 framework/src/Volo.Abp.Http.Client/Volo/Abp/Http/Client/Authentication/HttpContextAccessTokenProvider.cs delete mode 100644 framework/src/Volo.Abp.Http.Client/Volo/Abp/Http/Client/Authentication/IAccessTokenProvider.cs create mode 100644 framework/src/Volo.Abp.Http.Client/Volo/Abp/Http/Client/Authentication/IHttpClientAuthenticator.cs create mode 100644 framework/src/Volo.Abp.Http.Client/Volo/Abp/Http/Client/Authentication/NullHttpClientAuthenticator.cs diff --git a/framework/Volo.Abp.sln b/framework/Volo.Abp.sln index 92c46299f4..36aef8acce 100644 --- a/framework/Volo.Abp.sln +++ b/framework/Volo.Abp.sln @@ -214,9 +214,11 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Volo.Abp.EntityFrameworkCor EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Volo.Abp.Localization.Abstractions", "src\Volo.Abp.Localization.Abstractions\Volo.Abp.Localization.Abstractions.csproj", "{20513A4E-FAC7-4106-8976-5D79A3BDFED1}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Abp.Security.Tests", "test\Volo.Abp.Security.Tests\Volo.Abp.Security.Tests.csproj", "{7CE07034-7E02-4C78-B981-F1039412CA5E}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Volo.Abp.Security.Tests", "test\Volo.Abp.Security.Tests\Volo.Abp.Security.Tests.csproj", "{7CE07034-7E02-4C78-B981-F1039412CA5E}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Abp.Settings.Tests", "test\Volo.Abp.Settings.Tests\Volo.Abp.Settings.Tests.csproj", "{5F3A2D1E-EA89-40A7-8D2F-FB4EB2092403}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Volo.Abp.Settings.Tests", "test\Volo.Abp.Settings.Tests\Volo.Abp.Settings.Tests.csproj", "{5F3A2D1E-EA89-40A7-8D2F-FB4EB2092403}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Abp.Http.Client.IdentityModel", "src\Volo.Abp.Http.Client.IdentityModel\Volo.Abp.Http.Client.IdentityModel.csproj", "{D211A446-38FA-4F97-9A95-1F004A0FFF69}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -616,6 +618,10 @@ Global {5F3A2D1E-EA89-40A7-8D2F-FB4EB2092403}.Debug|Any CPU.Build.0 = Debug|Any CPU {5F3A2D1E-EA89-40A7-8D2F-FB4EB2092403}.Release|Any CPU.ActiveCfg = Release|Any CPU {5F3A2D1E-EA89-40A7-8D2F-FB4EB2092403}.Release|Any CPU.Build.0 = Release|Any CPU + {D211A446-38FA-4F97-9A95-1F004A0FFF69}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D211A446-38FA-4F97-9A95-1F004A0FFF69}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D211A446-38FA-4F97-9A95-1F004A0FFF69}.Release|Any CPU.ActiveCfg = Release|Any CPU + {D211A446-38FA-4F97-9A95-1F004A0FFF69}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -721,6 +727,7 @@ Global {20513A4E-FAC7-4106-8976-5D79A3BDFED1} = {5DF0E140-0513-4D0D-BE2E-3D4D85CD70E6} {7CE07034-7E02-4C78-B981-F1039412CA5E} = {447C8A77-E5F0-4538-8687-7383196D04EA} {5F3A2D1E-EA89-40A7-8D2F-FB4EB2092403} = {447C8A77-E5F0-4538-8687-7383196D04EA} + {D211A446-38FA-4F97-9A95-1F004A0FFF69} = {5DF0E140-0513-4D0D-BE2E-3D4D85CD70E6} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {BB97ECF4-9A84-433F-A80B-2A3285BDD1D5} diff --git a/framework/src/Volo.Abp.Http.Client.IdentityModel/NewFolder/Abp/Http/Client/IdentityModel/AbpHttpClientIdentityModelModule.cs b/framework/src/Volo.Abp.Http.Client.IdentityModel/NewFolder/Abp/Http/Client/IdentityModel/AbpHttpClientIdentityModelModule.cs new file mode 100644 index 0000000000..d6128e68d3 --- /dev/null +++ b/framework/src/Volo.Abp.Http.Client.IdentityModel/NewFolder/Abp/Http/Client/IdentityModel/AbpHttpClientIdentityModelModule.cs @@ -0,0 +1,12 @@ +using Volo.Abp.Modularity; + +namespace Volo.Abp.Http.Client.IdentityModel +{ + [DependsOn( + typeof(AbpHttpClientModule) + )] + public class AbpHttpClientIdentityModelModule : AbpModule + { + + } +} diff --git a/framework/src/Volo.Abp.Http.Client.IdentityModel/NewFolder/Abp/Http/Client/IdentityModel/IdentityModelHttpClientAuthenticator.cs b/framework/src/Volo.Abp.Http.Client.IdentityModel/NewFolder/Abp/Http/Client/IdentityModel/IdentityModelHttpClientAuthenticator.cs new file mode 100644 index 0000000000..e45cfbfae3 --- /dev/null +++ b/framework/src/Volo.Abp.Http.Client.IdentityModel/NewFolder/Abp/Http/Client/IdentityModel/IdentityModelHttpClientAuthenticator.cs @@ -0,0 +1,44 @@ +using System.Net.Http.Headers; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Authentication; +using Microsoft.AspNetCore.Http; +using Volo.Abp.DependencyInjection; +using Volo.Abp.Http.Client.Authentication; + +namespace NewFolder.Abp.Http.Client.IdentityModel +{ + [Dependency(ReplaceServices = true)] + public class IdentityModelHttpClientAuthenticator : IHttpClientAuthenticator, ITransientDependency + { + public IHttpContextAccessor HttpContextAccessor { get; set; } + + public async Task Authenticate(HttpClientAuthenticateContext context) + { + var accessToken = await GetAccessTokenFromHttpContextOrNullAsync() ?? + await GetAccessTokenFromServerOrNullAsync(context); + + if (accessToken != null) + { + //TODO: "Bearer" should be configurable + context.Client.DefaultRequestHeaders.Authorization + = new AuthenticationHeaderValue("Bearer", accessToken); + } + } + + protected virtual Task GetAccessTokenFromServerOrNullAsync(HttpClientAuthenticateContext context) + { + return Task.FromResult((string) null); + } + + protected virtual async Task GetAccessTokenFromHttpContextOrNullAsync() + { + var httpContext = HttpContextAccessor?.HttpContext; + if (httpContext == null) + { + return null; + } + + return await httpContext.GetTokenAsync("access_token"); + } + } +} diff --git a/framework/src/Volo.Abp.Http.Client.IdentityModel/Volo.Abp.Http.Client.IdentityModel.csproj b/framework/src/Volo.Abp.Http.Client.IdentityModel/Volo.Abp.Http.Client.IdentityModel.csproj new file mode 100644 index 0000000000..fe60970058 --- /dev/null +++ b/framework/src/Volo.Abp.Http.Client.IdentityModel/Volo.Abp.Http.Client.IdentityModel.csproj @@ -0,0 +1,20 @@ + + + + + + netstandard2.0 + Volo.Abp.Http.Client.IdentityModel + Volo.Abp.Http.Client.IdentityModel + $(AssetTargetFallback);portable-net45+win8+wp8+wpa81; + false + false + false + + + + + + + + \ No newline at end of file diff --git a/framework/src/Volo.Abp.Http.Client/Volo/Abp/Http/Client/Authentication/HttpClientAuthenticateContext.cs b/framework/src/Volo.Abp.Http.Client/Volo/Abp/Http/Client/Authentication/HttpClientAuthenticateContext.cs new file mode 100644 index 0000000000..4bf660ff42 --- /dev/null +++ b/framework/src/Volo.Abp.Http.Client/Volo/Abp/Http/Client/Authentication/HttpClientAuthenticateContext.cs @@ -0,0 +1,23 @@ +using System.Net.Http; + +namespace Volo.Abp.Http.Client.Authentication +{ + public class HttpClientAuthenticateContext + { + public HttpClient Client { get; } + + public HttpRequestMessage Request { get; } + + public string RemoteServiceName { get; } + + public HttpClientAuthenticateContext( + HttpClient client, + HttpRequestMessage request, + string remoteServiceName) + { + Client = client; + Request = request; + RemoteServiceName = remoteServiceName; + } + } +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.Http.Client/Volo/Abp/Http/Client/Authentication/HttpContextAccessTokenProvider.cs b/framework/src/Volo.Abp.Http.Client/Volo/Abp/Http/Client/Authentication/HttpContextAccessTokenProvider.cs deleted file mode 100644 index 03049f46c6..0000000000 --- a/framework/src/Volo.Abp.Http.Client/Volo/Abp/Http/Client/Authentication/HttpContextAccessTokenProvider.cs +++ /dev/null @@ -1,24 +0,0 @@ -using System.Threading.Tasks; -using Microsoft.AspNetCore.Authentication; -using Microsoft.AspNetCore.Http; -using Volo.Abp.DependencyInjection; -using Volo.Abp.Http.Client.DynamicProxying; - -namespace Volo.Abp.Http.Client.Authentication -{ - public class HttpContextAccessTokenProvider : IAccessTokenProvider, ISingletonDependency - { - public IHttpContextAccessor HttpContextAccessor { get; set; } - - public async Task GetOrNullAsync(DynamicHttpClientProxyConfig config) - { - var httpContext = HttpContextAccessor?.HttpContext; - if (httpContext == null) - { - return null; - } - - return await httpContext.GetTokenAsync("access_token"); - } - } -} \ No newline at end of file diff --git a/framework/src/Volo.Abp.Http.Client/Volo/Abp/Http/Client/Authentication/IAccessTokenProvider.cs b/framework/src/Volo.Abp.Http.Client/Volo/Abp/Http/Client/Authentication/IAccessTokenProvider.cs deleted file mode 100644 index 386a5cb416..0000000000 --- a/framework/src/Volo.Abp.Http.Client/Volo/Abp/Http/Client/Authentication/IAccessTokenProvider.cs +++ /dev/null @@ -1,10 +0,0 @@ -using System.Threading.Tasks; -using Volo.Abp.Http.Client.DynamicProxying; - -namespace Volo.Abp.Http.Client.Authentication -{ - public interface IAccessTokenProvider - { - Task GetOrNullAsync(DynamicHttpClientProxyConfig config); - } -} diff --git a/framework/src/Volo.Abp.Http.Client/Volo/Abp/Http/Client/Authentication/IHttpClientAuthenticator.cs b/framework/src/Volo.Abp.Http.Client/Volo/Abp/Http/Client/Authentication/IHttpClientAuthenticator.cs new file mode 100644 index 0000000000..83d6f9dd31 --- /dev/null +++ b/framework/src/Volo.Abp.Http.Client/Volo/Abp/Http/Client/Authentication/IHttpClientAuthenticator.cs @@ -0,0 +1,9 @@ +using System.Threading.Tasks; + +namespace Volo.Abp.Http.Client.Authentication +{ + public interface IHttpClientAuthenticator + { + Task Authenticate(HttpClientAuthenticateContext context); + } +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.Http.Client/Volo/Abp/Http/Client/Authentication/NullHttpClientAuthenticator.cs b/framework/src/Volo.Abp.Http.Client/Volo/Abp/Http/Client/Authentication/NullHttpClientAuthenticator.cs new file mode 100644 index 0000000000..a22ebd3674 --- /dev/null +++ b/framework/src/Volo.Abp.Http.Client/Volo/Abp/Http/Client/Authentication/NullHttpClientAuthenticator.cs @@ -0,0 +1,14 @@ +using System.Threading.Tasks; +using Volo.Abp.DependencyInjection; + +namespace Volo.Abp.Http.Client.Authentication +{ + [Dependency(TryRegister = true)] + public class NullHttpClientAuthenticator : IHttpClientAuthenticator, ISingletonDependency + { + public Task Authenticate(HttpClientAuthenticateContext context) + { + return Task.CompletedTask; + } + } +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.Http.Client/Volo/Abp/Http/Client/DynamicProxying/DynamicHttpProxyInterceptor.cs b/framework/src/Volo.Abp.Http.Client/Volo/Abp/Http/Client/DynamicProxying/DynamicHttpProxyInterceptor.cs index b84c8c087c..f265f5c3c8 100644 --- a/framework/src/Volo.Abp.Http.Client/Volo/Abp/Http/Client/DynamicProxying/DynamicHttpProxyInterceptor.cs +++ b/framework/src/Volo.Abp.Http.Client/Volo/Abp/Http/Client/DynamicProxying/DynamicHttpProxyInterceptor.cs @@ -2,7 +2,6 @@ using System.Collections.Generic; using System.Linq; using System.Net.Http; -using System.Net.Http.Headers; using System.Reflection; using System.Threading.Tasks; using Microsoft.Extensions.Options; @@ -28,7 +27,7 @@ namespace Volo.Abp.Http.Client.DynamicProxying private readonly RemoteServiceOptions _remoteServiceOptions; private readonly AbpHttpClientOptions _clientOptions; private readonly IJsonSerializer _jsonSerializer; - private readonly IAccessTokenProvider _accessTokenProvider; + private readonly IHttpClientAuthenticator _clientAuthenticator; static DynamicHttpProxyInterceptor() { @@ -43,12 +42,12 @@ namespace Volo.Abp.Http.Client.DynamicProxying IOptionsSnapshot remoteServiceOptions, IApiDescriptionFinder apiDescriptionFinder, IJsonSerializer jsonSerializer, - IAccessTokenProvider accessTokenProvider) + IHttpClientAuthenticator clientAuthenticator) { _httpClientFactory = httpClientFactory; _apiDescriptionFinder = apiDescriptionFinder; _jsonSerializer = jsonSerializer; - _accessTokenProvider = accessTokenProvider; + _clientAuthenticator = clientAuthenticator; _clientOptions = clientOptions.Value; _remoteServiceOptions = remoteServiceOptions.Value; } @@ -123,12 +122,13 @@ namespace Volo.Abp.Http.Client.DynamicProxying AddHeaders(invocation, action, requestMessage, apiVersion); - var accessToken = await _accessTokenProvider.GetOrNullAsync(clientConfig); - if (accessToken != null) - { - //TODO: "Bearer" should not be static. - client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken); - } + await _clientAuthenticator.Authenticate( + new HttpClientAuthenticateContext( + client, + requestMessage, + clientConfig.RemoteServiceName + ) + ); var response = await client.SendAsync(requestMessage); diff --git a/nupkg/common.ps1 b/nupkg/common.ps1 index ba244db63c..ba084c1175 100644 --- a/nupkg/common.ps1 +++ b/nupkg/common.ps1 @@ -62,7 +62,8 @@ $projects = ( "framework/src/Volo.Abp.HangFire", "framework/src/Volo.Abp.Http", "framework/src/Volo.Abp.Http.Abstractions", - "framework/src/Volo.Abp.Http.Client", + "framework/src/Volo.Abp.Http.Client", + "framework/src/Volo.Abp.Http.Client.IdentityModel", "framework/src/Volo.Abp.Json", "framework/src/Volo.Abp.Localization", "framework/src/Volo.Abp.Localization.Abstractions",