Browse Source

Redesign IdentityModelAuthenticationService

pull/1103/head
Halil ibrahim Kalkan 8 years ago
parent
commit
09298d4d9a
  1. 9
      framework/src/Volo.Abp.Http.Client.IdentityModel/Volo/Abp/Http/Client/IdentityModel/IdentityModelRemoteServiceHttpClientAuthenticator.cs
  2. 17
      framework/src/Volo.Abp.IdentityModel/Volo/Abp/IdentityModel/IIdentityModelAuthenticationService.cs
  3. 9
      framework/src/Volo.Abp.IdentityModel/Volo/Abp/IdentityModel/IIdentityModelHttpClientAuthenticator.cs
  4. 4
      framework/src/Volo.Abp.IdentityModel/Volo/Abp/IdentityModel/IdentityClientConfiguration.cs
  5. 71
      framework/src/Volo.Abp.IdentityModel/Volo/Abp/IdentityModel/IdentityModelAuthenticationService.cs
  6. 25
      framework/src/Volo.Abp.IdentityModel/Volo/Abp/IdentityModel/IdentityModelHttpClientAuthenticateContext.cs
  7. 27
      framework/src/Volo.Abp.IdentityModel/Volo/Abp/IdentityModel/IdentityModelHttpClientAuthenticatorExtensions.cs

9
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; } 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) 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.Client,
context.RemoteService.GetIdentityClient() context.RemoteService.GetIdentityClient()
); );

17
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<bool> TryAuthenticateAsync(
[NotNull] HttpClient client,
string identityClientName = null);
Task<string> GetAccessTokenAsync(
IdentityClientConfiguration configuration);
}
}

9
framework/src/Volo.Abp.IdentityModel/Volo/Abp/IdentityModel/IIdentityModelHttpClientAuthenticator.cs

@ -1,9 +0,0 @@
using System.Threading.Tasks;
namespace Volo.Abp.IdentityModel
{
public interface IIdentityModelHttpClientAuthenticator
{
Task AuthenticateAsync(IdentityModelHttpClientAuthenticateContext context);
}
}

4
framework/src/Volo.Abp.IdentityModel/Volo/Abp/IdentityModel/IdentityClientConfiguration.cs

@ -77,12 +77,16 @@ namespace Volo.Abp.IdentityModel
} }
public IdentityClientConfiguration( public IdentityClientConfiguration(
string authority,
string scope,
string clientId, string clientId,
string clientSecret, string clientSecret,
string grantType = OidcConstants.GrantTypes.ClientCredentials, string grantType = OidcConstants.GrantTypes.ClientCredentials,
string userName = null, string userName = null,
string userPassword = null) string userPassword = null)
{ {
this[nameof(Authority)] = authority;
this[nameof(Scope)] = scope;
this[nameof(ClientId)] = clientId; this[nameof(ClientId)] = clientId;
this[nameof(ClientSecret)] = clientSecret; this[nameof(ClientSecret)] = clientSecret;
this[nameof(GrantType)] = grantType; this[nameof(GrantType)] = grantType;

71
framework/src/Volo.Abp.IdentityModel/Volo/Abp/IdentityModel/IdentityModelRemoteServiceHttpClientAuthenticator.cs → framework/src/Volo.Abp.IdentityModel/Volo/Abp/IdentityModel/IdentityModelAuthenticationService.cs

@ -1,78 +1,89 @@
using System; using IdentityModel;
using System.Collections.Generic;
using System.Net.Http.Headers;
using System.Threading.Tasks;
using IdentityModel;
using IdentityModel.Client; using IdentityModel.Client;
using JetBrains.Annotations;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions; using Microsoft.Extensions.Logging.Abstractions;
using Microsoft.Extensions.Options; 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; using Volo.Abp.DependencyInjection;
namespace Volo.Abp.IdentityModel namespace Volo.Abp.IdentityModel
{ {
[Dependency(ReplaceServices = true)] [Dependency(ReplaceServices = true)]
public class IdentityModelHttpClientAuthenticator : IIdentityModelHttpClientAuthenticator, ITransientDependency public class IdentityModelAuthenticationService : IIdentityModelAuthenticationService, ITransientDependency
{ {
public ILogger<IdentityModelHttpClientAuthenticator> Logger { get; set; } public ILogger<IdentityModelAuthenticationService> Logger { get; set; }
protected IdentityClientOptions ClientOptions { get; } protected IdentityClientOptions ClientOptions { get; }
public IdentityModelHttpClientAuthenticator( public IdentityModelAuthenticationService(
IOptions<IdentityClientOptions> options) IOptions<IdentityClientOptions> options)
{ {
ClientOptions = options.Value; ClientOptions = options.Value;
Logger = NullLogger<IdentityModelHttpClientAuthenticator>.Instance; Logger = NullLogger<IdentityModelAuthenticationService>.Instance;
} }
public async Task AuthenticateAsync(IdentityModelHttpClientAuthenticateContext context) public async Task<bool> TryAuthenticateAsync(
[NotNull] HttpClient client,
string identityClientName = null)
{ {
var accessToken = await GetAccessTokenFromServerOrNullAsync(context); var accessToken = await GetAccessTokenOrNullAsync(identityClientName);
if (accessToken == null)
if (accessToken != null)
{ {
//TODO: "Bearer" should be configurable return false;
context.Client.DefaultRequestHeaders.Authorization
= new AuthenticationHeaderValue("Bearer", accessToken);
} }
}
protected virtual async Task<string> GetAccessTokenFromServerOrNullAsync(IdentityModelHttpClientAuthenticateContext context) SetAccessToken(client, accessToken);
{ return true;
//TODO: Better logging
var configuration = GetClientConfiguration(context); }
protected virtual async Task<string> GetAccessTokenOrNullAsync(string identityClientName)
{
var configuration = GetClientConfiguration(identityClientName);
if (configuration == null) 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 null;
} }
return await GetAccessTokenAsync(configuration);
}
public virtual async Task<string> GetAccessTokenAsync(IdentityClientConfiguration configuration)
{
var discoveryResponse = await GetDiscoveryResponse(configuration); var discoveryResponse = await GetDiscoveryResponse(configuration);
if (discoveryResponse.IsError) if (discoveryResponse.IsError)
{ {
Logger.LogError($"Could not retrieve the OpenId Connect discovery document! ErrorType: {discoveryResponse.ErrorType}. Error: {discoveryResponse.Error}"); throw new AbpException($"Could not retrieve the OpenId Connect discovery document! ErrorType: {discoveryResponse.ErrorType}. Error: {discoveryResponse.Error}");
return null;
} }
var tokenResponse = await GetTokenResponse(discoveryResponse, configuration); var tokenResponse = await GetTokenResponse(discoveryResponse, configuration);
if (tokenResponse.IsError) 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}"); 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 null;
} }
return tokenResponse.AccessToken; 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.Default;
} }
return ClientOptions.IdentityClients.GetOrDefault(context.IdentityClientName) ?? return ClientOptions.IdentityClients.GetOrDefault(identityClientName) ??
ClientOptions.IdentityClients.Default; ClientOptions.IdentityClients.Default;
} }

25
framework/src/Volo.Abp.IdentityModel/Volo/Abp/IdentityModel/IdentityModelHttpClientAuthenticateContext.cs

@ -1,25 +0,0 @@
using System.Net.Http;
using JetBrains.Annotations;
namespace Volo.Abp.IdentityModel
{
public class IdentityModelHttpClientAuthenticateContext
{
public HttpClient Client { get; }
/// <summary>
/// The identity client name configured with the <see cref="IdentityClientOptions"/>.
/// </summary>
public string IdentityClientName { get; }
/// <param name="client"><see cref="HttpClient"/> object to be authenticated</param>
/// <param name="identityClientName">The identity client name configured with the <see cref="IdentityClientOptions"/>.</param>
public IdentityModelHttpClientAuthenticateContext(
[NotNull] HttpClient client,
string identityClientName = null)
{
Client = Check.NotNull(client, nameof(client));
IdentityClientName = identityClientName;
}
}
}

27
framework/src/Volo.Abp.IdentityModel/Volo/Abp/IdentityModel/IdentityModelHttpClientAuthenticatorExtensions.cs

@ -1,27 +0,0 @@
using System.Net.Http;
using System.Threading.Tasks;
using JetBrains.Annotations;
namespace Volo.Abp.IdentityModel
{
public static class IdentityModelHttpClientAuthenticatorExtensions
{
/// <param name="authenticator">Authenticator object</param>
/// <param name="client"><see cref="HttpClient"/> object to be authenticated</param>
/// <param name="identityClientName">The identity client name configured with the <see cref="IdentityClientOptions"/>.</param>
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
)
);
}
}
}
Loading…
Cancel
Save