Skip to content

Commit

Permalink
Implemented special auth0 client credential flow
Browse files Browse the repository at this point in the history
  • Loading branch information
fancyDevelopment committed Apr 15, 2024
1 parent e7bd8cd commit 96a6cfe
Showing 3 changed files with 97 additions and 17 deletions.
Original file line number Diff line number Diff line change
@@ -64,7 +64,7 @@ internal async Task<string> SaveTokenForNewSessionAsync(OpenIdConnectMessage tok
{
// Create a new guid for the new session
string sessionId = Guid.NewGuid().ToString();
await SaveOrUpdateTokenAsync (sessionId, tokenResponse);
await SaveOrUpdateTokenAsync(sessionId, tokenResponse);
return sessionId;
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
using Fancy.ResourceLinker.Gateway.Authentication;
using Fancy.ResourceLinker.Gateway.Common;
using Microsoft.Extensions.Logging;

namespace Fancy.ResourceLinker.Gateway.Routing.Auth;

/// <summary>
/// A route authentication strategy running the OAuth client credential flow only.
/// </summary>
/// <remarks>
/// In some situations, auth0 requires an audience parameter in the request. This once can be added with this auth strategy.
/// </remarks>
internal class Auth0ClientCredentialOnlyAuthStrategy : ClientCredentialOnlyAuthStrategy
{
/// <summary>
/// The name of the auth strategy.
/// </summary>
public new const string NAME = "Auth0ClientCredentialOnly";

// <summary>
/// The auth0 audience.
/// </summary>
private string _audience = string.Empty;

/// <summary>
/// Initializes a new instance of the <see cref="ClientCredentialOnlyAuthStrategy" /> class.
/// </summary>
/// <param name="discoveryDocumentService">The discovery document service.</param>
/// <param name="logger">The logger.</param>
public Auth0ClientCredentialOnlyAuthStrategy(DiscoveryDocumentService discoveryDocumentService, ILogger<Auth0ClientCredentialOnlyAuthStrategy> logger) : base(discoveryDocumentService, logger)
{
}

/// <summary>
/// Gets the name of the strategy.
/// </summary>
/// <value>
/// The name.
/// </value>
public override string Name => NAME;

/// <summary>
/// Initializes the authentication strategy based on the gateway authentication settings and the route authentication settings asynchronous.
/// </summary>
/// <param name="gatewayAuthenticationSettings">The gateway authentication settigns.</param>
/// <param name="routeAuthenticationSettings">The route authentication settigns.</param>
public override Task InitializeAsync(GatewayAuthenticationSettings? gatewayAuthenticationSettings, RouteAuthenticationSettings routeAuthenticationSettings)
{
if (routeAuthenticationSettings.Options.ContainsKey("Audience"))
{
_audience = routeAuthenticationSettings.Options["Audience"];
}

return base.InitializeAsync(gatewayAuthenticationSettings, routeAuthenticationSettings);
}

/// <summary>
/// Sets up the token request.
/// </summary>
/// <returns>The token request.</returns>
protected override Dictionary<string, string> SetUpTokenRequest()
{
return new Dictionary<string, string>
{
{ "grant_type", "client_credentials" },
{ "client_id", _clientId },
{ "client_secret", _clientSecret },
{ "scope", _scope }
};
}
}
Original file line number Diff line number Diff line change
@@ -65,32 +65,32 @@ internal class ClientCredentialOnlyAuthStrategy : IRouteAuthenticationStrategy
/// <summary>
/// The discovery document.
/// </summary>
private DiscoveryDocument? _discoveryDocument;
protected DiscoveryDocument? _discoveryDocument;

/// <summary>
/// The client identifier.
/// </summary>
private string _clientId = string.Empty;
protected string _clientId = string.Empty;

/// <summary>
/// The client secret.
/// </summary>
private string _clientSecret = string.Empty;
protected string _clientSecret = string.Empty;

/// <summary>
/// The scope.
/// </summary>
private string _scope = string.Empty;
protected string _scope = string.Empty;

/// <summary>
/// The is initialized.
/// </summary>
private bool _isInitialized = false;
protected bool _isInitialized = false;

/// <summary>
/// The current token response.
/// </summary>
private ClientCredentialsTokenResponse? _currentTokenResponse;
protected ClientCredentialsTokenResponse? _currentTokenResponse;

/// <summary>
/// Initializes a new instance of the <see cref="ClientCredentialOnlyAuthStrategy" /> class.
@@ -109,14 +109,14 @@ public ClientCredentialOnlyAuthStrategy(DiscoveryDocumentService discoveryDocume
/// <value>
/// The name.
/// </value>
public string Name => NAME;
public virtual string Name => NAME;

/// <summary>
/// Initializes the authentication strategy based on the gateway authentication settings and the route authentication settings asynchronous.
/// </summary>
/// <param name="gatewayAuthenticationSettings">The gateway authentication settigns.</param>
/// <param name="routeAuthenticationSettings">The route authentication settigns.</param>
public async Task InitializeAsync(GatewayAuthenticationSettings? gatewayAuthenticationSettings, RouteAuthenticationSettings routeAuthenticationSettings)
public virtual async Task InitializeAsync(GatewayAuthenticationSettings? gatewayAuthenticationSettings, RouteAuthenticationSettings routeAuthenticationSettings)
{
string authority;

@@ -210,6 +210,21 @@ public async Task SetAuthenticationAsync(IServiceProvider serviceProvider, HttpR
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);
}

/// <summary>
/// Sets up the token request.
/// </summary>
/// <returns>The token request.</returns>
protected virtual Dictionary<string, string> SetUpTokenRequest()
{
return new Dictionary<string, string>
{
{ "grant_type", "client_credentials" },
{ "client_id", _clientId },
{ "client_secret", _clientSecret },
{ "scope", _scope }
};
}

/// <summary>
/// Gets the access token asynchronous.
/// </summary>
@@ -230,13 +245,7 @@ private async Task<string> GetAccessTokenAsync()
/// <returns></returns>
private async Task<ClientCredentialsTokenResponse> GetTokenViaClientCredentialsAsync()
{
var payload = new Dictionary<string, string>
{
{ "grant_type", "client_credentials" },
{ "client_id", _clientId },
{ "client_secret", _clientSecret },
{ "scope", _scope }
};
Dictionary<string, string> payload = SetUpTokenRequest();

HttpClient httpClient = new HttpClient();

@@ -262,7 +271,7 @@ private async Task<ClientCredentialsTokenResponse> GetTokenViaClientCredentialsA

ClientCredentialsTokenResponse? result = await response.Content.ReadFromJsonAsync<ClientCredentialsTokenResponse>();

if(result == null)
if (result == null)
{
throw new InvalidOperationException("Could not deserialize client credential token response");
}

0 comments on commit 96a6cfe

Please sign in to comment.