diff --git a/framework/src/Volo.Abp.Http.Client.IdentityModel/Volo/Abp/Http/Client/IdentityModel/IdentityModelRemoteServiceHttpClientAuthenticator.cs b/framework/src/Volo.Abp.Http.Client.IdentityModel/Volo/Abp/Http/Client/IdentityModel/IdentityModelRemoteServiceHttpClientAuthenticator.cs index e7b41784c7..91d1c4cb9b 100644 --- a/framework/src/Volo.Abp.Http.Client.IdentityModel/Volo/Abp/Http/Client/IdentityModel/IdentityModelRemoteServiceHttpClientAuthenticator.cs +++ b/framework/src/Volo.Abp.Http.Client.IdentityModel/Volo/Abp/Http/Client/IdentityModel/IdentityModelRemoteServiceHttpClientAuthenticator.cs @@ -13,11 +13,12 @@ namespace Volo.Abp.Http.Client.IdentityModel { public IHttpContextAccessor HttpContextAccessor { get; set; } - protected IIdentityModelHttpClientAuthenticator IdentityModelHttpClientAuthenticator { get; } + protected IIdentityModelAuthenticationService IdentityModelAuthenticationService { get; } - public IdentityModelRemoteServiceHttpClientAuthenticator(IIdentityModelHttpClientAuthenticator identityModelHttpClientAuthenticator) + public IdentityModelRemoteServiceHttpClientAuthenticator( + IIdentityModelAuthenticationService identityModelAuthenticationService) { - IdentityModelHttpClientAuthenticator = identityModelHttpClientAuthenticator; + IdentityModelAuthenticationService = identityModelAuthenticationService; } public async Task Authenticate(RemoteServiceHttpClientAuthenticateContext context) @@ -32,7 +33,7 @@ namespace Volo.Abp.Http.Client.IdentityModel } } - await IdentityModelHttpClientAuthenticator.AuthenticateAsync( + await IdentityModelAuthenticationService.TryAuthenticateAsync( context.Client, context.RemoteService.GetIdentityClient() ); diff --git a/framework/src/Volo.Abp.IdentityModel/Volo/Abp/IdentityModel/IIdentityModelAuthenticationService.cs b/framework/src/Volo.Abp.IdentityModel/Volo/Abp/IdentityModel/IIdentityModelAuthenticationService.cs new file mode 100644 index 0000000000..4acfac2ad7 --- /dev/null +++ b/framework/src/Volo.Abp.IdentityModel/Volo/Abp/IdentityModel/IIdentityModelAuthenticationService.cs @@ -0,0 +1,17 @@ +using System.Net.Http; +using System.Threading.Tasks; +using JetBrains.Annotations; + +namespace Volo.Abp.IdentityModel +{ + //TODO: Re-consider this interface! + public interface IIdentityModelAuthenticationService + { + Task TryAuthenticateAsync( + [NotNull] HttpClient client, + string identityClientName = null); + + Task GetAccessTokenAsync( + IdentityClientConfiguration configuration); + } +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.IdentityModel/Volo/Abp/IdentityModel/IIdentityModelHttpClientAuthenticator.cs b/framework/src/Volo.Abp.IdentityModel/Volo/Abp/IdentityModel/IIdentityModelHttpClientAuthenticator.cs deleted file mode 100644 index 09a16735ff..0000000000 --- a/framework/src/Volo.Abp.IdentityModel/Volo/Abp/IdentityModel/IIdentityModelHttpClientAuthenticator.cs +++ /dev/null @@ -1,9 +0,0 @@ -using System.Threading.Tasks; - -namespace Volo.Abp.IdentityModel -{ - public interface IIdentityModelHttpClientAuthenticator - { - Task AuthenticateAsync(IdentityModelHttpClientAuthenticateContext context); - } -} \ No newline at end of file diff --git a/framework/src/Volo.Abp.IdentityModel/Volo/Abp/IdentityModel/IdentityClientConfiguration.cs b/framework/src/Volo.Abp.IdentityModel/Volo/Abp/IdentityModel/IdentityClientConfiguration.cs index 9e891ccafa..35ca881f7f 100644 --- a/framework/src/Volo.Abp.IdentityModel/Volo/Abp/IdentityModel/IdentityClientConfiguration.cs +++ b/framework/src/Volo.Abp.IdentityModel/Volo/Abp/IdentityModel/IdentityClientConfiguration.cs @@ -77,12 +77,16 @@ namespace Volo.Abp.IdentityModel } public IdentityClientConfiguration( + string authority, + string scope, string clientId, string clientSecret, string grantType = OidcConstants.GrantTypes.ClientCredentials, string userName = null, string userPassword = null) { + this[nameof(Authority)] = authority; + this[nameof(Scope)] = scope; this[nameof(ClientId)] = clientId; this[nameof(ClientSecret)] = clientSecret; this[nameof(GrantType)] = grantType; diff --git a/framework/src/Volo.Abp.IdentityModel/Volo/Abp/IdentityModel/IdentityModelRemoteServiceHttpClientAuthenticator.cs b/framework/src/Volo.Abp.IdentityModel/Volo/Abp/IdentityModel/IdentityModelAuthenticationService.cs similarity index 55% rename from framework/src/Volo.Abp.IdentityModel/Volo/Abp/IdentityModel/IdentityModelRemoteServiceHttpClientAuthenticator.cs rename to framework/src/Volo.Abp.IdentityModel/Volo/Abp/IdentityModel/IdentityModelAuthenticationService.cs index ad956aee1e..4f316ec357 100644 --- a/framework/src/Volo.Abp.IdentityModel/Volo/Abp/IdentityModel/IdentityModelRemoteServiceHttpClientAuthenticator.cs +++ b/framework/src/Volo.Abp.IdentityModel/Volo/Abp/IdentityModel/IdentityModelAuthenticationService.cs @@ -1,78 +1,89 @@ -using System; -using System.Collections.Generic; -using System.Net.Http.Headers; -using System.Threading.Tasks; -using IdentityModel; +using IdentityModel; using IdentityModel.Client; +using JetBrains.Annotations; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging.Abstractions; using Microsoft.Extensions.Options; +using System; +using System.Collections.Generic; +using System.Net.Http; +using System.Net.Http.Headers; +using System.Threading.Tasks; using Volo.Abp.DependencyInjection; namespace Volo.Abp.IdentityModel { [Dependency(ReplaceServices = true)] - public class IdentityModelHttpClientAuthenticator : IIdentityModelHttpClientAuthenticator, ITransientDependency + public class IdentityModelAuthenticationService : IIdentityModelAuthenticationService, ITransientDependency { - public ILogger Logger { get; set; } + public ILogger Logger { get; set; } protected IdentityClientOptions ClientOptions { get; } - - public IdentityModelHttpClientAuthenticator( + + public IdentityModelAuthenticationService( IOptions options) { ClientOptions = options.Value; - Logger = NullLogger.Instance; + Logger = NullLogger.Instance; } - public async Task AuthenticateAsync(IdentityModelHttpClientAuthenticateContext context) + public async Task TryAuthenticateAsync( + [NotNull] HttpClient client, + string identityClientName = null) { - var accessToken = await GetAccessTokenFromServerOrNullAsync(context); - - if (accessToken != null) + var accessToken = await GetAccessTokenOrNullAsync(identityClientName); + if (accessToken == null) { - //TODO: "Bearer" should be configurable - context.Client.DefaultRequestHeaders.Authorization - = new AuthenticationHeaderValue("Bearer", accessToken); + return false; } - } - protected virtual async Task GetAccessTokenFromServerOrNullAsync(IdentityModelHttpClientAuthenticateContext context) - { - //TODO: Better logging + SetAccessToken(client, accessToken); + return true; - var configuration = GetClientConfiguration(context); + } + protected virtual async Task GetAccessTokenOrNullAsync(string identityClientName) + { + var configuration = GetClientConfiguration(identityClientName); if (configuration == null) { - Logger.LogWarning($"Could not find {nameof(IdentityClientConfiguration)} for {context.IdentityClientName}. Either define a configuration for {context.IdentityClientName} or set a default configuration."); + Logger.LogWarning($"Could not find {nameof(IdentityClientConfiguration)} for {identityClientName}. Either define a configuration for {identityClientName} or set a default configuration."); return null; } + return await GetAccessTokenAsync(configuration); + } + + public virtual async Task GetAccessTokenAsync(IdentityClientConfiguration configuration) + { var discoveryResponse = await GetDiscoveryResponse(configuration); if (discoveryResponse.IsError) { - Logger.LogError($"Could not retrieve the OpenId Connect discovery document! ErrorType: {discoveryResponse.ErrorType}. Error: {discoveryResponse.Error}"); - return null; + 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) { - Logger.LogError($"Could not get token from the OpenId Connect server! ErrorType: {tokenResponse.ErrorType}. Error: {tokenResponse.Error}. ErrorDescription: {tokenResponse.ErrorDescription}. HttpStatusCode: {tokenResponse.HttpStatusCode}"); - return 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}"); } return tokenResponse.AccessToken; } - private IdentityClientConfiguration GetClientConfiguration(IdentityModelHttpClientAuthenticateContext context) + protected virtual void SetAccessToken(HttpClient client, string accessToken) + { + //TODO: "Bearer" should be configurable + client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken); + } + + private IdentityClientConfiguration GetClientConfiguration(string identityClientName = null) { - if (context.IdentityClientName.IsNullOrEmpty()) + if (identityClientName.IsNullOrEmpty()) { return ClientOptions.IdentityClients.Default; } - return ClientOptions.IdentityClients.GetOrDefault(context.IdentityClientName) ?? + return ClientOptions.IdentityClients.GetOrDefault(identityClientName) ?? ClientOptions.IdentityClients.Default; } diff --git a/framework/src/Volo.Abp.IdentityModel/Volo/Abp/IdentityModel/IdentityModelHttpClientAuthenticateContext.cs b/framework/src/Volo.Abp.IdentityModel/Volo/Abp/IdentityModel/IdentityModelHttpClientAuthenticateContext.cs deleted file mode 100644 index 441129aee7..0000000000 --- a/framework/src/Volo.Abp.IdentityModel/Volo/Abp/IdentityModel/IdentityModelHttpClientAuthenticateContext.cs +++ /dev/null @@ -1,25 +0,0 @@ -using System.Net.Http; -using JetBrains.Annotations; - -namespace Volo.Abp.IdentityModel -{ - public class IdentityModelHttpClientAuthenticateContext - { - public HttpClient Client { get; } - - /// - /// The identity client name configured with the . - /// - public string IdentityClientName { get; } - - /// object to be authenticated - /// The identity client name configured with the . - public IdentityModelHttpClientAuthenticateContext( - [NotNull] HttpClient client, - string identityClientName = null) - { - Client = Check.NotNull(client, nameof(client)); - IdentityClientName = identityClientName; - } - } -} diff --git a/framework/src/Volo.Abp.IdentityModel/Volo/Abp/IdentityModel/IdentityModelHttpClientAuthenticatorExtensions.cs b/framework/src/Volo.Abp.IdentityModel/Volo/Abp/IdentityModel/IdentityModelHttpClientAuthenticatorExtensions.cs deleted file mode 100644 index c40b0d8398..0000000000 --- a/framework/src/Volo.Abp.IdentityModel/Volo/Abp/IdentityModel/IdentityModelHttpClientAuthenticatorExtensions.cs +++ /dev/null @@ -1,27 +0,0 @@ -using System.Net.Http; -using System.Threading.Tasks; -using JetBrains.Annotations; - -namespace Volo.Abp.IdentityModel -{ - public static class IdentityModelHttpClientAuthenticatorExtensions - { - /// Authenticator object - /// object to be authenticated - /// The identity client name configured with the . - public static Task AuthenticateAsync( - [NotNull] this IIdentityModelHttpClientAuthenticator authenticator, - [NotNull] HttpClient client, - string identityClientName = null) - { - Check.NotNull(authenticator, nameof(authenticator)); - - return authenticator.AuthenticateAsync( - new IdentityModelHttpClientAuthenticateContext( - client, - identityClientName - ) - ); - } - } -}