Browse Source

Backport the server builder changes to OpenIddict 1.x

pull/670/head
Kévin Chalet 8 years ago
parent
commit
16795dc5d6
  1. 4
      src/OpenIddict.Abstractions/Managers/IOpenIddictAuthorizationManager.cs
  2. 2
      src/OpenIddict.Abstractions/Stores/IOpenIddictAuthorizationStore.cs
  3. 4
      src/OpenIddict.Core/Managers/OpenIddictApplicationManager.cs
  4. 2
      src/OpenIddict.Core/Managers/OpenIddictAuthorizationManager.cs
  5. 5
      src/OpenIddict.Core/Managers/OpenIddictScopeManager.cs
  6. 2
      src/OpenIddict.EntityFramework/Stores/OpenIddictAuthorizationStore.cs
  7. 2
      src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictAuthorizationStore.cs
  8. 2
      src/OpenIddict.MongoDb/Stores/OpenIddictAuthorizationStore.cs
  9. 8
      src/OpenIddict.Server/Internal/OpenIddictServerProvider.Authentication.cs
  10. 16
      src/OpenIddict.Server/Internal/OpenIddictServerProvider.Helpers.cs
  11. 8
      src/OpenIddict.Server/Internal/OpenIddictServerProvider.Session.cs
  12. 18
      src/OpenIddict.Server/OpenIddictServerBuilder.cs
  13. 5
      src/OpenIddict.Server/OpenIddictServerExtensions.cs
  14. 10
      src/OpenIddict.Server/OpenIddictServerOptions.cs
  15. 11
      test/OpenIddict.Server.Tests/Internal/OpenIddictServerProviderTests.Authentication.cs
  16. 11
      test/OpenIddict.Server.Tests/Internal/OpenIddictServerProviderTests.Session.cs
  17. 49
      test/OpenIddict.Server.Tests/OpenIddictServerBuilderTests.cs
  18. 29
      test/OpenIddict.Server.Tests/OpenIddictServerExtensionsTests.cs

4
src/OpenIddict.Abstractions/Managers/IOpenIddictAuthorizationManager.cs

@ -110,7 +110,7 @@ namespace OpenIddict.Abstractions
/// A <see cref="Task"/> that can be used to monitor the asynchronous operation, /// A <see cref="Task"/> that can be used to monitor the asynchronous operation,
/// whose result returns the authorizations corresponding to the criteria. /// whose result returns the authorizations corresponding to the criteria.
/// </returns> /// </returns>
Task<ImmutableArray<object>> FindAsync([NotNull] string subject, [NotNull] string client, [NotNull] string status, CancellationToken cancellationToken); Task<ImmutableArray<object>> FindAsync([NotNull] string subject, [NotNull] string client, [NotNull] string status, CancellationToken cancellationToken = default);
/// <summary> /// <summary>
/// Retrieves the authorizations matching the specified parameters. /// Retrieves the authorizations matching the specified parameters.
@ -357,7 +357,7 @@ namespace OpenIddict.Abstractions
Task PopulateAsync([NotNull] object authorization, [NotNull] OpenIddictAuthorizationDescriptor descriptor, CancellationToken cancellationToken = default); Task PopulateAsync([NotNull] object authorization, [NotNull] OpenIddictAuthorizationDescriptor descriptor, CancellationToken cancellationToken = default);
/// <summary> /// <summary>
/// Removes the ad-hoc authorizations that are marked as invalid or have no valid/nonexpired token attached. /// Removes the authorizations that are marked as invalid and the ad-hoc ones that have no valid/nonexpired token attached.
/// </summary> /// </summary>
/// <param name="cancellationToken">The <see cref="CancellationToken"/> that can be used to abort the operation.</param> /// <param name="cancellationToken">The <see cref="CancellationToken"/> that can be used to abort the operation.</param>
/// <returns> /// <returns>

2
src/OpenIddict.Abstractions/Stores/IOpenIddictAuthorizationStore.cs

@ -279,7 +279,7 @@ namespace OpenIddict.Abstractions
[CanBeNull] TState state, CancellationToken cancellationToken); [CanBeNull] TState state, CancellationToken cancellationToken);
/// <summary> /// <summary>
/// Removes the ad-hoc authorizations that are marked as invalid or have no valid/nonexpired token attached. /// Removes the authorizations that are marked as invalid and the ad-hoc ones that have no valid/nonexpired token attached.
/// </summary> /// </summary>
/// <param name="cancellationToken">The <see cref="CancellationToken"/> that can be used to abort the operation.</param> /// <param name="cancellationToken">The <see cref="CancellationToken"/> that can be used to abort the operation.</param>
/// <returns> /// <returns>

4
src/OpenIddict.Core/Managers/OpenIddictApplicationManager.cs

@ -90,7 +90,7 @@ namespace OpenIddict.Core
/// A <see cref="Task"/> that can be used to monitor the asynchronous operation. /// A <see cref="Task"/> that can be used to monitor the asynchronous operation.
/// </returns> /// </returns>
public virtual Task CreateAsync([NotNull] TApplication application, CancellationToken cancellationToken = default) public virtual Task CreateAsync([NotNull] TApplication application, CancellationToken cancellationToken = default)
=> CreateAsync(application, /* secret: */ null, cancellationToken); => CreateAsync(application, secret: null, cancellationToken);
/// <summary> /// <summary>
/// Creates a new application. /// Creates a new application.
@ -181,7 +181,7 @@ namespace OpenIddict.Core
var secret = await Store.GetClientSecretAsync(application, cancellationToken); var secret = await Store.GetClientSecretAsync(application, cancellationToken);
if (!string.IsNullOrEmpty(secret)) if (!string.IsNullOrEmpty(secret))
{ {
await Store.SetClientSecretAsync(application, /* secret: */ null, cancellationToken); await Store.SetClientSecretAsync(application, secret: null, cancellationToken);
await CreateAsync(application, secret, cancellationToken); await CreateAsync(application, secret, cancellationToken);
} }
else else

2
src/OpenIddict.Core/Managers/OpenIddictAuthorizationManager.cs

@ -887,7 +887,7 @@ namespace OpenIddict.Core
} }
/// <summary> /// <summary>
/// Removes the ad-hoc authorizations that are marked as invalid or have no valid/nonexpired token attached. /// Removes the authorizations that are marked as invalid and the ad-hoc ones that have no valid/nonexpired token attached.
/// </summary> /// </summary>
/// <param name="cancellationToken">The <see cref="CancellationToken"/> that can be used to abort the operation.</param> /// <param name="cancellationToken">The <see cref="CancellationToken"/> that can be used to abort the operation.</param>
/// <returns> /// <returns>

5
src/OpenIddict.Core/Managers/OpenIddictScopeManager.cs

@ -211,6 +211,11 @@ namespace OpenIddict.Core
public virtual async Task<ImmutableArray<TScope>> FindByNamesAsync( public virtual async Task<ImmutableArray<TScope>> FindByNamesAsync(
ImmutableArray<string> names, CancellationToken cancellationToken = default) ImmutableArray<string> names, CancellationToken cancellationToken = default)
{ {
if (names.IsDefaultOrEmpty)
{
return ImmutableArray.Create<TScope>();
}
if (names.Any(name => string.IsNullOrEmpty(name))) if (names.Any(name => string.IsNullOrEmpty(name)))
{ {
throw new ArgumentException("Scope names cannot be null or empty.", nameof(names)); throw new ArgumentException("Scope names cannot be null or empty.", nameof(names));

2
src/OpenIddict.EntityFramework/Stores/OpenIddictAuthorizationStore.cs

@ -699,7 +699,7 @@ namespace OpenIddict.EntityFramework
} }
/// <summary> /// <summary>
/// Removes the ad-hoc authorizations that are marked as invalid or have no valid/nonexpired token attached. /// Removes the authorizations that are marked as invalid and the ad-hoc ones that have no valid/nonexpired token attached.
/// </summary> /// </summary>
/// <param name="cancellationToken">The <see cref="CancellationToken"/> that can be used to abort the operation.</param> /// <param name="cancellationToken">The <see cref="CancellationToken"/> that can be used to abort the operation.</param>
/// <returns> /// <returns>

2
src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictAuthorizationStore.cs

@ -752,7 +752,7 @@ namespace OpenIddict.EntityFrameworkCore
} }
/// <summary> /// <summary>
/// Removes the ad-hoc authorizations that are marked as invalid or have no valid/nonexpired token attached. /// Removes the authorizations that are marked as invalid and the ad-hoc ones that have no valid/nonexpired token attached.
/// </summary> /// </summary>
/// <param name="cancellationToken">The <see cref="CancellationToken"/> that can be used to abort the operation.</param> /// <param name="cancellationToken">The <see cref="CancellationToken"/> that can be used to abort the operation.</param>
/// <returns> /// <returns>

2
src/OpenIddict.MongoDb/Stores/OpenIddictAuthorizationStore.cs

@ -617,7 +617,7 @@ namespace OpenIddict.MongoDb
} }
/// <summary> /// <summary>
/// Removes the ad-hoc authorizations that are marked as invalid or have no valid/nonexpired token attached. /// Removes the authorizations that are marked as invalid and the ad-hoc ones that have no valid/nonexpired token attached.
/// </summary> /// </summary>
/// <param name="cancellationToken">The <see cref="CancellationToken"/> that can be used to abort the operation.</param> /// <param name="cancellationToken">The <see cref="CancellationToken"/> that can be used to abort the operation.</param>
/// <returns> /// <returns>

8
src/OpenIddict.Server/Internal/OpenIddictServerProvider.Authentication.cs

@ -15,8 +15,6 @@ using AspNet.Security.OpenIdConnect.Server;
using JetBrains.Annotations; using JetBrains.Annotations;
using Microsoft.AspNetCore.Diagnostics; using Microsoft.AspNetCore.Diagnostics;
using Microsoft.AspNetCore.WebUtilities; using Microsoft.AspNetCore.WebUtilities;
using Microsoft.Extensions.Caching.Distributed;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using Microsoft.IdentityModel.Tokens; using Microsoft.IdentityModel.Tokens;
using Newtonsoft.Json; using Newtonsoft.Json;
@ -479,11 +477,7 @@ namespace OpenIddict.Server.Internal
// to avoid collisions with the other types of cached requests. // to avoid collisions with the other types of cached requests.
var key = OpenIddictConstants.Environment.AuthorizationRequest + context.Request.RequestId; var key = OpenIddictConstants.Environment.AuthorizationRequest + context.Request.RequestId;
await options.Cache.SetAsync(key, stream.ToArray(), new DistributedCacheEntryOptions await options.Cache.SetAsync(key, stream.ToArray(), options.RequestCachingPolicy);
{
AbsoluteExpiration = context.Options.SystemClock.UtcNow + TimeSpan.FromMinutes(30),
SlidingExpiration = TimeSpan.FromMinutes(10)
});
// Create a new authorization request containing only the request_id parameter. // Create a new authorization request containing only the request_id parameter.
var address = QueryHelpers.AddQueryString( var address = QueryHelpers.AddQueryString(

16
src/OpenIddict.Server/Internal/OpenIddictServerProvider.Helpers.cs

@ -591,8 +591,8 @@ namespace OpenIddict.Server.Internal
if (property.Key.EndsWith(OpenIddictConstants.PropertyTypes.Boolean)) if (property.Key.EndsWith(OpenIddictConstants.PropertyTypes.Boolean))
{ {
var name = property.Key.Substring( var name = property.Key.Substring(
/* index: */ 0, startIndex: 0,
/* length: */ property.Key.LastIndexOf(OpenIddictConstants.PropertyTypes.Boolean)); length: property.Key.LastIndexOf(OpenIddictConstants.PropertyTypes.Boolean));
bool value; bool value;
@ -615,8 +615,8 @@ namespace OpenIddict.Server.Internal
else if (property.Key.EndsWith(OpenIddictConstants.PropertyTypes.Integer)) else if (property.Key.EndsWith(OpenIddictConstants.PropertyTypes.Integer))
{ {
var name = property.Key.Substring( var name = property.Key.Substring(
/* index: */ 0, startIndex: 0,
/* length: */ property.Key.LastIndexOf(OpenIddictConstants.PropertyTypes.Integer)); length: property.Key.LastIndexOf(OpenIddictConstants.PropertyTypes.Integer));
long value; long value;
@ -639,8 +639,8 @@ namespace OpenIddict.Server.Internal
else if (property.Key.EndsWith(OpenIddictConstants.PropertyTypes.Json)) else if (property.Key.EndsWith(OpenIddictConstants.PropertyTypes.Json))
{ {
var name = property.Key.Substring( var name = property.Key.Substring(
/* index: */ 0, startIndex: 0,
/* length: */ property.Key.LastIndexOf(OpenIddictConstants.PropertyTypes.Json)); length: property.Key.LastIndexOf(OpenIddictConstants.PropertyTypes.Json));
if (request.IsAuthorizationRequest() || request.IsLogoutRequest()) if (request.IsAuthorizationRequest() || request.IsLogoutRequest())
{ {
@ -671,8 +671,8 @@ namespace OpenIddict.Server.Internal
else if (property.Key.EndsWith(OpenIddictConstants.PropertyTypes.String)) else if (property.Key.EndsWith(OpenIddictConstants.PropertyTypes.String))
{ {
var name = property.Key.Substring( var name = property.Key.Substring(
/* index: */ 0, startIndex: 0,
/* length: */ property.Key.LastIndexOf(OpenIddictConstants.PropertyTypes.String)); length: property.Key.LastIndexOf(OpenIddictConstants.PropertyTypes.String));
yield return Tuple.Create(property.Key, name, new OpenIdConnectParameter(property.Value)); yield return Tuple.Create(property.Key, name, new OpenIdConnectParameter(property.Value));
} }

8
src/OpenIddict.Server/Internal/OpenIddictServerProvider.Session.cs

@ -12,8 +12,6 @@ using AspNet.Security.OpenIdConnect.Server;
using JetBrains.Annotations; using JetBrains.Annotations;
using Microsoft.AspNetCore.Diagnostics; using Microsoft.AspNetCore.Diagnostics;
using Microsoft.AspNetCore.WebUtilities; using Microsoft.AspNetCore.WebUtilities;
using Microsoft.Extensions.Caching.Distributed;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using Microsoft.IdentityModel.Tokens; using Microsoft.IdentityModel.Tokens;
using Newtonsoft.Json; using Newtonsoft.Json;
@ -196,11 +194,7 @@ namespace OpenIddict.Server.Internal
// to avoid collisions with the other types of cached requests. // to avoid collisions with the other types of cached requests.
var key = OpenIddictConstants.Environment.LogoutRequest + context.Request.RequestId; var key = OpenIddictConstants.Environment.LogoutRequest + context.Request.RequestId;
await options.Cache.SetAsync(key, stream.ToArray(), new DistributedCacheEntryOptions await options.Cache.SetAsync(key, stream.ToArray(), options.RequestCachingPolicy);
{
AbsoluteExpiration = context.Options.SystemClock.UtcNow + TimeSpan.FromMinutes(30),
SlidingExpiration = TimeSpan.FromMinutes(10)
});
// Create a new logout request containing only the request_id parameter. // Create a new logout request containing only the request_id parameter.
var address = QueryHelpers.AddQueryString( var address = QueryHelpers.AddQueryString(

18
src/OpenIddict.Server/OpenIddictServerBuilder.cs

@ -19,6 +19,7 @@ using JetBrains.Annotations;
using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.DataProtection; using Microsoft.AspNetCore.DataProtection;
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Caching.Distributed;
using Microsoft.IdentityModel.Tokens; using Microsoft.IdentityModel.Tokens;
using OpenIddict.Server; using OpenIddict.Server;
@ -699,6 +700,23 @@ namespace Microsoft.Extensions.DependencyInjection
public OpenIddictServerBuilder SetRefreshTokenLifetime(TimeSpan lifetime) public OpenIddictServerBuilder SetRefreshTokenLifetime(TimeSpan lifetime)
=> Configure(options => options.RefreshTokenLifetime = lifetime); => Configure(options => options.RefreshTokenLifetime = lifetime);
/// <summary>
/// Sets the caching policy used to determine how long the authorization and
/// end session requests should be cached by the distributed cache implementation.
/// Note: the specified policy is only used when request caching is explicitly enabled.
/// </summary>
/// <param name="policy">The request caching policy.</param>
/// <returns>The <see cref="OpenIddictServerBuilder"/>.</returns>
public OpenIddictServerBuilder SetRequestCachingPolicy([NotNull] DistributedCacheEntryOptions policy)
{
if (policy == null)
{
throw new ArgumentNullException(nameof(policy));
}
return Configure(options => options.RequestCachingPolicy = policy);
}
/// <summary> /// <summary>
/// Sets the issuer address, which is used as the base address /// Sets the issuer address, which is used as the base address
/// for the endpoint URIs returned from the discovery endpoint. /// for the endpoint URIs returned from the discovery endpoint.

5
src/OpenIddict.Server/OpenIddictServerExtensions.cs

@ -182,6 +182,11 @@ namespace Microsoft.Extensions.DependencyInjection
"The token endpoint must be enabled to use the authorization code, client credentials, password and refresh token flows."); "The token endpoint must be enabled to use the authorization code, client credentials, password and refresh token flows.");
} }
if (options.EnableRequestCaching && options.RequestCachingPolicy == null)
{
throw new InvalidOperationException("A caching policy must be specified when enabling request caching.");
}
if (options.RevocationEndpointPath.HasValue && options.DisableTokenStorage) if (options.RevocationEndpointPath.HasValue && options.DisableTokenStorage)
{ {
throw new InvalidOperationException("The revocation endpoint cannot be enabled when token storage is disabled."); throw new InvalidOperationException("The revocation endpoint cannot be enabled when token storage is disabled.");

10
src/OpenIddict.Server/OpenIddictServerOptions.cs

@ -112,6 +112,16 @@ namespace OpenIddict.Server
/// </summary> /// </summary>
public RandomNumberGenerator RandomNumberGenerator { get; set; } = RandomNumberGenerator.Create(); public RandomNumberGenerator RandomNumberGenerator { get; set; } = RandomNumberGenerator.Create();
/// <summary>
/// Gets or sets the caching policy used to determine how long the authorization
/// and end session requests should be cached by the distributed cache implementation.
/// </summary>
public DistributedCacheEntryOptions RequestCachingPolicy { get; set; } = new DistributedCacheEntryOptions
{
AbsoluteExpirationRelativeToNow = TimeSpan.FromHours(1),
SlidingExpiration = TimeSpan.FromMinutes(30)
};
/// <summary> /// <summary>
/// Gets the OAuth2/OpenID Connect scopes enabled for this application. /// Gets the OAuth2/OpenID Connect scopes enabled for this application.
/// </summary> /// </summary>

11
test/OpenIddict.Server.Tests/Internal/OpenIddictServerProviderTests.Authentication.cs

@ -4,6 +4,7 @@
* the license and the contributors participating to this project. * the license and the contributors participating to this project.
*/ */
using System;
using System.Collections.Immutable; using System.Collections.Immutable;
using System.IO; using System.IO;
using System.Net.Http; using System.Net.Http;
@ -828,6 +829,12 @@ namespace OpenIddict.Server.Internal.Tests
builder.EnableRequestCaching(); builder.EnableRequestCaching();
builder.SetRequestCachingPolicy(new DistributedCacheEntryOptions
{
AbsoluteExpirationRelativeToNow = TimeSpan.FromDays(42),
SlidingExpiration = TimeSpan.FromSeconds(42)
});
builder.Configure(options => options.RandomNumberGenerator = generator.Object); builder.Configure(options => options.RandomNumberGenerator = generator.Object);
}); });
@ -850,7 +857,9 @@ namespace OpenIddict.Server.Internal.Tests
cache.Verify(mock => mock.SetAsync( cache.Verify(mock => mock.SetAsync(
OpenIddictConstants.Environment.AuthorizationRequest + identifier, OpenIddictConstants.Environment.AuthorizationRequest + identifier,
It.IsAny<byte[]>(), It.IsAny<byte[]>(),
It.IsAny<DistributedCacheEntryOptions>()), Times.Once()); It.Is<DistributedCacheEntryOptions>(options =>
options.AbsoluteExpirationRelativeToNow == TimeSpan.FromDays(42) &&
options.SlidingExpiration == TimeSpan.FromSeconds(42))), Times.Once());
generator.Verify(mock => mock.GetBytes(It.Is<byte[]>(bytes => bytes.Length == 256 / 8)), Times.Once()); generator.Verify(mock => mock.GetBytes(It.Is<byte[]>(bytes => bytes.Length == 256 / 8)), Times.Once());
} }

11
test/OpenIddict.Server.Tests/Internal/OpenIddictServerProviderTests.Session.cs

@ -4,6 +4,7 @@
* the license and the contributors participating to this project. * the license and the contributors participating to this project.
*/ */
using System;
using System.Collections.Immutable; using System.Collections.Immutable;
using System.Net.Http; using System.Net.Http;
using System.Security.Cryptography; using System.Security.Cryptography;
@ -136,6 +137,12 @@ namespace OpenIddict.Server.Internal.Tests
builder.EnableRequestCaching(); builder.EnableRequestCaching();
builder.SetRequestCachingPolicy(new DistributedCacheEntryOptions
{
AbsoluteExpirationRelativeToNow = TimeSpan.FromDays(42),
SlidingExpiration = TimeSpan.FromSeconds(42)
});
builder.Configure(options => options.RandomNumberGenerator = generator.Object); builder.Configure(options => options.RandomNumberGenerator = generator.Object);
}); });
@ -156,7 +163,9 @@ namespace OpenIddict.Server.Internal.Tests
cache.Verify(mock => mock.SetAsync( cache.Verify(mock => mock.SetAsync(
OpenIddictConstants.Environment.LogoutRequest + identifier, OpenIddictConstants.Environment.LogoutRequest + identifier,
It.IsAny<byte[]>(), It.IsAny<byte[]>(),
It.IsAny<DistributedCacheEntryOptions>()), Times.Once()); It.Is<DistributedCacheEntryOptions>(options =>
options.AbsoluteExpirationRelativeToNow == TimeSpan.FromDays(42) &&
options.SlidingExpiration == TimeSpan.FromSeconds(42))), Times.Once());
generator.Verify(mock => mock.GetBytes(It.Is<byte[]>(bytes => bytes.Length == 256 / 8)), Times.Once()); generator.Verify(mock => mock.GetBytes(It.Is<byte[]>(bytes => bytes.Length == 256 / 8)), Times.Once());
} }

49
test/OpenIddict.Server.Tests/OpenIddictServerBuilderTests.cs

@ -12,6 +12,7 @@ using System.Threading.Tasks;
using AspNet.Security.OpenIdConnect.Primitives; using AspNet.Security.OpenIdConnect.Primitives;
using Microsoft.AspNetCore.DataProtection; using Microsoft.AspNetCore.DataProtection;
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Caching.Distributed;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
using Microsoft.IdentityModel.Tokens; using Microsoft.IdentityModel.Tokens;
@ -630,6 +631,54 @@ namespace OpenIddict.Server.Tests
Assert.Equal(TimeSpan.FromMinutes(42), options.RefreshTokenLifetime); Assert.Equal(TimeSpan.FromMinutes(42), options.RefreshTokenLifetime);
} }
[Fact]
public void SetRequestCachingPolicy_ThrowsAnExceptionForNullPolicy()
{
// Arrange
var services = CreateServices();
var builder = CreateBuilder(services);
// Act and assert
var exception = Assert.Throws<ArgumentNullException>(() => builder.SetRequestCachingPolicy(null));
Assert.Equal("policy", exception.ParamName);
}
[Fact]
public void SetRequestCachingPolicy_PolicyIsUpdated()
{
// Arrange
var services = CreateServices();
var builder = CreateBuilder(services);
var policy = new DistributedCacheEntryOptions
{
AbsoluteExpirationRelativeToNow = TimeSpan.FromDays(42),
SlidingExpiration = TimeSpan.FromSeconds(42)
};
// Act
builder.SetRequestCachingPolicy(policy);
var options = GetOptions(services);
// Assert
Assert.Same(policy, options.RequestCachingPolicy);
}
[Fact]
public void SetIssuer_ThrowsAnExceptionForNullIssuer()
{
// Arrange
var services = CreateServices();
var builder = CreateBuilder(services);
// Act and assert
var exception = Assert.Throws<ArgumentNullException>(() => builder.SetIssuer(null));
Assert.Equal("address", exception.ParamName);
}
[Fact] [Fact]
public void SetIssuer_AddressIsReplaced() public void SetIssuer_AddressIsReplaced()
{ {

29
test/OpenIddict.Server.Tests/OpenIddictServerExtensionsTests.cs

@ -269,6 +269,35 @@ namespace OpenIddict.Server.Tests
"client credentials, password and refresh token flows.", exception.Message); "client credentials, password and refresh token flows.", exception.Message);
} }
[Fact]
public void UseOpenIddictServer_ThrowsAnExceptionWhenCachingPolicyIsNullAndRequestCachingEnabled()
{
// Arrange
var services = new ServiceCollection();
services.AddOpenIddict()
.AddCore(options =>
{
options.SetDefaultApplicationEntity<OpenIddictApplication>()
.SetDefaultAuthorizationEntity<OpenIddictAuthorization>()
.SetDefaultScopeEntity<OpenIddictScope>()
.SetDefaultTokenEntity<OpenIddictToken>();
})
.AddServer()
.EnableAuthorizationEndpoint("/connect/authorize")
.AllowImplicitFlow()
.EnableRequestCaching()
.Configure(options => options.RequestCachingPolicy = null);
var builder = new ApplicationBuilder(services.BuildServiceProvider());
// Act and assert
var exception = Assert.Throws<InvalidOperationException>(() => builder.UseOpenIddictServer());
Assert.Equal("A caching policy must be specified when enabling request caching.", exception.Message);
}
[Fact] [Fact]
public void UseOpenIddictServer_ThrowsAnExceptionWhenTokenStorageIsDisabled() public void UseOpenIddictServer_ThrowsAnExceptionWhenTokenStorageIsDisabled()
{ {

Loading…
Cancel
Save