Skip to content

Commit

Permalink
Merge pull request #1454 from matt-goldman/main
Browse files Browse the repository at this point in the history
Provide abstraction for IdentityServerTools
  • Loading branch information
AndersAbel authored Nov 20, 2023
2 parents 73dd86a + a95cda9 commit 0b6f4b5
Show file tree
Hide file tree
Showing 5 changed files with 68 additions and 37 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,13 @@ public static IIdentityServerBuilder AddCoreServices(this IIdentityServerBuilder
builder.Services.AddTransient<IJwtRequestValidator, JwtRequestValidator>();

builder.Services.AddTransient<ReturnUrlParser>();

#pragma warning disable CS0618 // Type or member is obsolete
builder.Services.AddTransient<IIdentityServerTools, IdentityServerTools>();
// We've added the IIdentityServerTools interface to allow mocking, but keep the old
// direct class registration around if anyone has a dependency on it.
builder.Services.AddTransient<IdentityServerTools>();
#pragma warning restore CS0618 // Type or member is obsolete

builder.Services.AddTransient<IReturnUrlParser, OidcReturnUrlParser>();
builder.Services.AddScoped<IUserSession, DefaultUserSession>();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@
namespace Duende.IdentityServer;

/// <summary>
/// Extensions for IdentityServerTools
/// Extensions for IIdentityServerTools
/// </summary>
public static class IdentityServerToolsExtensions
public static class IIdentityServerToolsExtensions
{
/// <summary>
/// Issues the client JWT.
Expand All @@ -27,7 +27,7 @@ public static class IdentityServerToolsExtensions
/// <param name="audiences">The audiences.</param>
/// <param name="additionalClaims">Additional claims</param>
/// <returns></returns>
public static async Task<string> IssueClientJwtAsync(this IdentityServerTools tools,
public static async Task<string> IssueClientJwtAsync(this IIdentityServerTools tools,
string clientId,
int lifetime,
IEnumerable<string> scopes = null,
Expand Down
87 changes: 56 additions & 31 deletions src/IdentityServer/IdentityServerTools.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,29 +15,10 @@
namespace Duende.IdentityServer;

/// <summary>
/// Class for useful helpers for interacting with IdentityServer
/// Useful helpers for interacting with IdentityServer.
/// </summary>
public class IdentityServerTools
public interface IIdentityServerTools
{
internal readonly IServiceProvider ServiceProvider;
internal readonly IIssuerNameService IssuerNameService;
private readonly ITokenCreationService _tokenCreation;
private readonly IClock _clock;

/// <summary>
/// Initializes a new instance of the <see cref="IdentityServerTools" /> class.
/// </summary>
/// <param name="serviceProvider">The provider.</param>
/// <param name="issuerNameService">The issuer name service</param>
/// <param name="tokenCreation">The token creation service.</param>
/// <param name="clock">The clock.</param>
public IdentityServerTools(IServiceProvider serviceProvider, IIssuerNameService issuerNameService, ITokenCreationService tokenCreation, IClock clock)
{
ServiceProvider = serviceProvider;
IssuerNameService = issuerNameService;
_tokenCreation = tokenCreation;
_clock = clock;
}

/// <summary>
/// Issues a JWT.
Expand All @@ -46,11 +27,7 @@ public IdentityServerTools(IServiceProvider serviceProvider, IIssuerNameService
/// <param name="claims">The claims.</param>
/// <returns></returns>
/// <exception cref="System.ArgumentNullException">claims</exception>
public virtual async Task<string> IssueJwtAsync(int lifetime, IEnumerable<Claim> claims)
{
var issuer = await IssuerNameService.GetCurrentAsync();
return await IssueJwtAsync(lifetime, issuer, claims);
}
Task<string> IssueJwtAsync(int lifetime, IEnumerable<Claim> claims);

/// <summary>
/// Issues a JWT.
Expand All @@ -60,11 +37,7 @@ public virtual async Task<string> IssueJwtAsync(int lifetime, IEnumerable<Claim>
/// <param name="claims">The claims.</param>
/// <returns></returns>
/// <exception cref="System.ArgumentNullException">claims</exception>
public virtual Task<string> IssueJwtAsync(int lifetime, string issuer, IEnumerable<Claim> claims)
{
var tokenType = OidcConstants.TokenTypes.AccessToken;
return IssueJwtAsync(lifetime, issuer, tokenType, claims);
}
Task<string> IssueJwtAsync(int lifetime, string issuer, IEnumerable<Claim> claims);

/// <summary>
/// Issues a JWT.
Expand All @@ -75,6 +48,58 @@ public virtual Task<string> IssueJwtAsync(int lifetime, string issuer, IEnumerab
/// <param name="claims">The claims.</param>
/// <returns></returns>
/// <exception cref="System.ArgumentNullException">claims</exception>
Task<string> IssueJwtAsync(int lifetime, string issuer, string tokenType, IEnumerable<Claim> claims);

/// <summary>
/// Service Provider to resolve services.
/// </summary>
public IServiceProvider ServiceProvider { get; }

/// <summary>
/// Issuer name service
/// </summary>
public IIssuerNameService IssuerNameService { get; }
}

/// <summary>
/// Class for useful helpers for interacting with IdentityServer
/// </summary>
[Obsolete("Do not reference the IdentityServerTools implementation directly, use the IIdentityServerTools interface")]
public class IdentityServerTools : IIdentityServerTools
{
/// <inheritdoc/>
public IServiceProvider ServiceProvider { get; }

/// <inheritdoc/>
public IIssuerNameService IssuerNameService { get; }

private readonly ITokenCreationService _tokenCreation;
private readonly IClock _clock;

/// <inheritdoc/>
public IdentityServerTools(IServiceProvider serviceProvider, IIssuerNameService issuerNameService, ITokenCreationService tokenCreation, IClock clock)
{
ServiceProvider = serviceProvider;
IssuerNameService = issuerNameService;
_tokenCreation = tokenCreation;
_clock = clock;
}

/// <inheritdoc/>
public virtual async Task<string> IssueJwtAsync(int lifetime, IEnumerable<Claim> claims)
{
var issuer = await IssuerNameService.GetCurrentAsync();
return await IssueJwtAsync(lifetime, issuer, claims);
}

/// <inheritdoc/>
public virtual Task<string> IssueJwtAsync(int lifetime, string issuer, IEnumerable<Claim> claims)
{
var tokenType = OidcConstants.TokenTypes.AccessToken;
return IssueJwtAsync(lifetime, issuer, tokenType, claims);
}

/// <inheritdoc/>
public virtual async Task<string> IssueJwtAsync(int lifetime, string issuer, string tokenType, IEnumerable<Claim> claims)
{
if (String.IsNullOrWhiteSpace(issuer)) throw new ArgumentNullException(nameof(issuer));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ public class DefaultBackChannelLogoutService : IBackChannelLogoutService
/// <summary>
/// The IdentityServerTools used to create and the JWT.
/// </summary>
protected IdentityServerTools Tools { get; }
protected IIdentityServerTools Tools { get; }

/// <summary>
/// The ILogoutNotificationService to build the back channel logout requests.
Expand All @@ -58,7 +58,7 @@ public class DefaultBackChannelLogoutService : IBackChannelLogoutService
/// <param name="logger"></param>
public DefaultBackChannelLogoutService(
IClock clock,
IdentityServerTools tools,
IIdentityServerTools tools,
ILogoutNotificationService logoutNotificationService,
IBackChannelLogoutHttpClient backChannelLogoutHttpClient,
ILogger<IBackChannelLogoutService> logger)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1428,7 +1428,7 @@ public async Task valid_id_token_hint_should_return_success()
{
_mockPipeline.Options.IssuerUri = IdentityServerPipeline.BaseUrl;

var tokenService = _mockPipeline.Resolve<IdentityServerTools>();
var tokenService = _mockPipeline.Resolve<IIdentityServerTools>();
var id_token = await tokenService.IssueJwtAsync(600, new Claim[] {
new Claim("sub", _user.SubjectId),
new Claim("aud", _cibaClient.ClientId),
Expand Down

0 comments on commit 0b6f4b5

Please sign in to comment.