From 8f9c6f109d6df2366796efa5f1180288f7499ea1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Chalet?= Date: Wed, 13 Jun 2018 16:36:57 +0200 Subject: [PATCH 1/2] Enable scope validation and reject unidentified token/revocation requests by default --- samples/Mvc.Server/Startup.cs | 17 +++++++----- ...OpenIddictServerProvider.Authentication.cs | 2 +- .../OpenIddictServerProvider.Exchange.cs | 4 +-- .../OpenIddictServerProvider.Revocation.cs | 2 +- .../OpenIddictServerBuilder.cs | 26 +++++++++---------- .../OpenIddictServerOptions.cs | 18 ++++++------- ...ddictServerProviderTests.Authentication.cs | 4 --- .../OpenIddictServerProviderTests.Exchange.cs | 14 ++++------ ...penIddictServerProviderTests.Revocation.cs | 5 +++- .../Internal/OpenIddictServerProviderTests.cs | 3 +++ .../OpenIddictServerBuilderTests.cs | 12 ++++----- 11 files changed, 53 insertions(+), 54 deletions(-) diff --git a/samples/Mvc.Server/Startup.cs b/samples/Mvc.Server/Startup.cs index c51e82f3..c7977242 100644 --- a/samples/Mvc.Server/Startup.cs +++ b/samples/Mvc.Server/Startup.cs @@ -101,9 +101,6 @@ namespace Mvc.Server OpenIdConnectConstants.Scopes.Profile, OpenIddictConstants.Scopes.Roles); - // Make the "client_id" parameter mandatory when sending a token request. - options.RequireClientIdentification(); - // When request caching is enabled, authorization and logout requests // are stored in the distributed cache by OpenIddict and the user agent // is redirected to the same page with a single parameter (request_id). @@ -111,10 +108,6 @@ namespace Mvc.Server // an external authentication provider like Google, Facebook or Twitter. options.EnableRequestCaching(); - // Enable scope validation, so that authorization and token requests - // that specify unregistered scopes are automatically rejected. - options.EnableScopeValidation(); - // During development, you can disable the HTTPS requirement. options.DisableHttpsRequirement(); @@ -123,6 +116,16 @@ namespace Mvc.Server // // options.UseJsonWebTokens(); // options.AddEphemeralSigningKey(); + + // Note: if you don't want to specify a client_id when sending + // a token or revocation request, uncomment the following line: + // + // options.AcceptAnonymousClients(); + + // Note: if you want to process authorization and token requests + // that specify non-registered scopes, uncomment the following line: + // + // options.DisableScopeValidation(); }) // Register the OpenIddict validation handler. diff --git a/src/OpenIddict.Server/Internal/OpenIddictServerProvider.Authentication.cs b/src/OpenIddict.Server/Internal/OpenIddictServerProvider.Authentication.cs index 2caaa150..a2e92059 100644 --- a/src/OpenIddict.Server/Internal/OpenIddictServerProvider.Authentication.cs +++ b/src/OpenIddict.Server/Internal/OpenIddictServerProvider.Authentication.cs @@ -180,7 +180,7 @@ namespace OpenIddict.Server } // Validates scopes, unless scope validation was explicitly disabled. - if (options.EnableScopeValidation) + if (!options.DisableScopeValidation) { var scopes = new HashSet(context.Request.GetScopes(), StringComparer.Ordinal); scopes.ExceptWith(options.Scopes); diff --git a/src/OpenIddict.Server/Internal/OpenIddictServerProvider.Exchange.cs b/src/OpenIddict.Server/Internal/OpenIddictServerProvider.Exchange.cs index c03d9703..458c3cb1 100644 --- a/src/OpenIddict.Server/Internal/OpenIddictServerProvider.Exchange.cs +++ b/src/OpenIddict.Server/Internal/OpenIddictServerProvider.Exchange.cs @@ -78,7 +78,7 @@ namespace OpenIddict.Server } // Validates scopes, unless scope validation was explicitly disabled. - if (options.EnableScopeValidation) + if (!options.DisableScopeValidation) { var scopes = new HashSet(context.Request.GetScopes(), StringComparer.Ordinal); scopes.ExceptWith(options.Scopes); @@ -127,7 +127,7 @@ namespace OpenIddict.Server if (string.IsNullOrEmpty(context.ClientId)) { // Reject the request if client identification is mandatory. - if (options.RequireClientIdentification) + if (!options.AcceptAnonymousClients) { _logger.LogError("The token request was rejected becaused the " + "mandatory client_id parameter was missing or empty."); diff --git a/src/OpenIddict.Server/Internal/OpenIddictServerProvider.Revocation.cs b/src/OpenIddict.Server/Internal/OpenIddictServerProvider.Revocation.cs index b6dbbfab..aceaacb9 100644 --- a/src/OpenIddict.Server/Internal/OpenIddictServerProvider.Revocation.cs +++ b/src/OpenIddict.Server/Internal/OpenIddictServerProvider.Revocation.cs @@ -55,7 +55,7 @@ namespace OpenIddict.Server if (string.IsNullOrEmpty(context.ClientId)) { // Reject the request if client identification is mandatory. - if (options.RequireClientIdentification) + if (!options.AcceptAnonymousClients) { _logger.LogError("The revocation request was rejected becaused the " + "mandatory client_id parameter was missing or empty."); diff --git a/src/OpenIddict.Server/OpenIddictServerBuilder.cs b/src/OpenIddict.Server/OpenIddictServerBuilder.cs index fb7b4a93..c75dd76f 100644 --- a/src/OpenIddict.Server/OpenIddictServerBuilder.cs +++ b/src/OpenIddict.Server/OpenIddictServerBuilder.cs @@ -66,6 +66,14 @@ namespace Microsoft.Extensions.DependencyInjection return this; } + /// + /// Makes client identification optional so that token and revocation + /// requests that don't specify a client_id are not automatically rejected. + /// + /// The . + public OpenIddictServerBuilder AcceptAnonymousClients() + => Configure(options => options.AcceptAnonymousClients = true); + /// /// Registers (and generates if necessary) a user-specific development /// certificate used to sign the JWT tokens issued by OpenIddict. @@ -462,12 +470,12 @@ namespace Microsoft.Extensions.DependencyInjection } /// - /// Rejects authorization and token requests that specify scopes that have not been - /// registered using or the scope manager. + /// Allows processing authorization and token requests that specify scopes that have not + /// been registered using or the scope manager. /// /// The . - public OpenIddictServerBuilder EnableScopeValidation() - => Configure(options => options.EnableScopeValidation = true); + public OpenIddictServerBuilder DisableScopeValidation() + => Configure(options => options.DisableScopeValidation = true); /// /// Enables the token endpoint. @@ -595,16 +603,6 @@ namespace Microsoft.Extensions.DependencyInjection return Configure(options => options.Scopes.UnionWith(scopes)); } - /// - /// Makes client identification mandatory so that token and revocation - /// requests that don't specify a client_id are automatically rejected. - /// Note: enabling this option doesn't prevent public clients from using - /// the token and revocation endpoints, but specifying a client_id is required. - /// - /// The . - public OpenIddictServerBuilder RequireClientIdentification() - => Configure(options => options.RequireClientIdentification = true); - /// /// Sets the access token lifetime, after which client applications must retrieve /// a new access token by making a grant_type=refresh_token token request diff --git a/src/OpenIddict.Server/OpenIddictServerOptions.cs b/src/OpenIddict.Server/OpenIddictServerOptions.cs index d29c6c21..d9afb20a 100644 --- a/src/OpenIddict.Server/OpenIddictServerOptions.cs +++ b/src/OpenIddict.Server/OpenIddictServerOptions.cs @@ -27,6 +27,13 @@ namespace OpenIddict.Server ProviderType = typeof(OpenIddictServerProvider); } + /// + /// Gets or sets a boolean determining whether client identification is optional. + /// Enabling this option allows client applications to communicate with the token + /// and revocation endpoints without having to send their client identifier. + /// + public bool AcceptAnonymousClients { get; set; } + /// /// Gets or sets the user-provided that the OpenIddict server /// invokes to enable developer control over the entire authentication/authorization process. @@ -84,9 +91,9 @@ namespace OpenIddict.Server public bool EnableRequestCaching { get; set; } /// - /// Gets or sets a boolean indicating whether scope validation is enabled. + /// Gets or sets a boolean indicating whether scope validation is disabled. /// - public bool EnableScopeValidation { get; set; } + public bool DisableScopeValidation { get; set; } /// /// Gets the OAuth2/OpenID Connect flows enabled for this application. @@ -98,13 +105,6 @@ namespace OpenIddict.Server /// public RandomNumberGenerator RandomNumberGenerator { get; set; } = RandomNumberGenerator.Create(); - /// - /// Gets or sets a boolean determining whether client identification is required. - /// Enabling this option requires registering a client application and sending a - /// valid client_id when communicating with the token and revocation endpoints. - /// - public bool RequireClientIdentification { get; set; } - /// /// Gets the OAuth2/OpenID Connect scopes enabled for this application. /// diff --git a/test/OpenIddict.Server.Tests/Internal/OpenIddictServerProviderTests.Authentication.cs b/test/OpenIddict.Server.Tests/Internal/OpenIddictServerProviderTests.Authentication.cs index adef3266..1181ba82 100644 --- a/test/OpenIddict.Server.Tests/Internal/OpenIddictServerProviderTests.Authentication.cs +++ b/test/OpenIddict.Server.Tests/Internal/OpenIddictServerProviderTests.Authentication.cs @@ -205,8 +205,6 @@ namespace OpenIddict.Server.Tests It.IsAny())) .ReturnsAsync(ImmutableArray.Create()); })); - - builder.EnableScopeValidation(); }); var client = new OpenIdConnectClient(server.CreateClient()); @@ -257,7 +255,6 @@ namespace OpenIddict.Server.Tests .ReturnsAsync(true); })); - builder.EnableScopeValidation(); builder.RegisterScopes("registered_scope"); }); @@ -331,7 +328,6 @@ namespace OpenIddict.Server.Tests builder.RegisterScopes("scope_registered_in_options"); - builder.EnableScopeValidation(); builder.Services.AddSingleton(manager); }); diff --git a/test/OpenIddict.Server.Tests/Internal/OpenIddictServerProviderTests.Exchange.cs b/test/OpenIddict.Server.Tests/Internal/OpenIddictServerProviderTests.Exchange.cs index a43804c7..46447828 100644 --- a/test/OpenIddict.Server.Tests/Internal/OpenIddictServerProviderTests.Exchange.cs +++ b/test/OpenIddict.Server.Tests/Internal/OpenIddictServerProviderTests.Exchange.cs @@ -81,10 +81,7 @@ namespace OpenIddict.Server.Tests public async Task ValidateTokenRequest_AuthorizationCodeRequestIsRejectedWhenRedirectUriIsMissing() { // Arrange - var server = CreateAuthorizationServer(builder => - { - builder.EnableScopeValidation(); - }); + var server = CreateAuthorizationServer(); var client = new OpenIdConnectClient(server.CreateClient()); @@ -115,8 +112,6 @@ namespace OpenIddict.Server.Tests It.IsAny())) .ReturnsAsync(ImmutableArray.Create()); })); - - builder.EnableScopeValidation(); }); var client = new OpenIdConnectClient(server.CreateClient()); @@ -141,7 +136,6 @@ namespace OpenIddict.Server.Tests // Arrange var server = CreateAuthorizationServer(builder => { - builder.EnableScopeValidation(); builder.RegisterScopes("registered_scope"); }); @@ -182,7 +176,6 @@ namespace OpenIddict.Server.Tests var server = CreateAuthorizationServer(builder => { - builder.EnableScopeValidation(); builder.RegisterScopes("scope_registered_in_options"); builder.Services.AddSingleton(manager); @@ -254,7 +247,10 @@ namespace OpenIddict.Server.Tests public async Task ValidateTokenRequest_RequestWithoutClientIdIsRejectedWhenClientIdentificationIsRequired() { // Arrange - var server = CreateAuthorizationServer(builder => builder.RequireClientIdentification()); + var server = CreateAuthorizationServer(builder => + { + builder.Configure(options => options.AcceptAnonymousClients = false); + }); var client = new OpenIdConnectClient(server.CreateClient()); diff --git a/test/OpenIddict.Server.Tests/Internal/OpenIddictServerProviderTests.Revocation.cs b/test/OpenIddict.Server.Tests/Internal/OpenIddictServerProviderTests.Revocation.cs index 215437fc..6ea51325 100644 --- a/test/OpenIddict.Server.Tests/Internal/OpenIddictServerProviderTests.Revocation.cs +++ b/test/OpenIddict.Server.Tests/Internal/OpenIddictServerProviderTests.Revocation.cs @@ -49,7 +49,10 @@ namespace OpenIddict.Server.Tests public async Task ValidateRevocationRequest_RequestWithoutClientIdIsRejectedWhenClientIdentificationIsRequired() { // Arrange - var server = CreateAuthorizationServer(builder => builder.RequireClientIdentification()); + var server = CreateAuthorizationServer(builder => + { + builder.Configure(options => options.AcceptAnonymousClients = false); + }); var client = new OpenIdConnectClient(server.CreateClient()); diff --git a/test/OpenIddict.Server.Tests/Internal/OpenIddictServerProviderTests.cs b/test/OpenIddict.Server.Tests/Internal/OpenIddictServerProviderTests.cs index 18009f25..07ed1970 100644 --- a/test/OpenIddict.Server.Tests/Internal/OpenIddictServerProviderTests.cs +++ b/test/OpenIddict.Server.Tests/Internal/OpenIddictServerProviderTests.cs @@ -1450,6 +1450,9 @@ namespace OpenIddict.Server.Tests .AddServer(options => { + // Accept anonymous clients by default. + options.AcceptAnonymousClients(); + // Disable the transport security requirement during testing. options.DisableHttpsRequirement(); diff --git a/test/OpenIddict.Server.Tests/OpenIddictServerBuilderTests.cs b/test/OpenIddict.Server.Tests/OpenIddictServerBuilderTests.cs index ac2c5441..e93abfd8 100644 --- a/test/OpenIddict.Server.Tests/OpenIddictServerBuilderTests.cs +++ b/test/OpenIddict.Server.Tests/OpenIddictServerBuilderTests.cs @@ -457,19 +457,19 @@ namespace OpenIddict.Server.Tests } [Fact] - public void EnableScopeValidation_ScopeValidationIsDisabled() + public void DisableScopeValidation_ScopeValidationIsDisabled() { // Arrange var services = CreateServices(); var builder = CreateBuilder(services); // Act - builder.EnableScopeValidation(); + builder.DisableScopeValidation(); var options = GetOptions(services); // Assert - Assert.True(options.EnableScopeValidation); + Assert.True(options.DisableScopeValidation); } [Fact] @@ -505,19 +505,19 @@ namespace OpenIddict.Server.Tests } [Fact] - public void RequireClientIdentification_ClientIdentificationIsEnforced() + public void AcceptAnonymousClients_ClientIdentificationIsOptional() { // Arrange var services = CreateServices(); var builder = CreateBuilder(services); // Act - builder.RequireClientIdentification(); + builder.AcceptAnonymousClients(); var options = GetOptions(services); // Assert - Assert.True(options.RequireClientIdentification); + Assert.True(options.AcceptAnonymousClients); } [Fact] From 7e10bedb73e28dd3d732012b7e055824d76927a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Chalet?= Date: Wed, 13 Jun 2018 21:02:45 +0200 Subject: [PATCH 2/2] Remove implicit permissions and introduce OpenIddictServerBuilder.IgnoreEndpointPermissions()/IgnoreGrantTypePermissions()/IgnoreScopePermissions() --- samples/Mvc.Server/Startup.cs | 17 +- .../Managers/IOpenIddictApplicationManager.cs | 11 - .../OpenIddictConstants.cs | 11 + .../Managers/OpenIddictApplicationManager.cs | 139 +--------- ...OpenIddictServerProvider.Authentication.cs | 129 ++++----- .../OpenIddictServerProvider.Exchange.cs | 43 +-- .../OpenIddictServerProvider.Introspection.cs | 5 +- .../OpenIddictServerProvider.Revocation.cs | 3 +- .../OpenIddictServerProvider.Session.cs | 29 +- .../OpenIddictServerBuilder.cs | 24 ++ .../OpenIddictServerOptions.cs | 21 ++ ...ddictServerProviderTests.Authentication.cs | 91 +------ .../OpenIddictServerProviderTests.Exchange.cs | 251 +----------------- ...IddictServerProviderTests.Introspection.cs | 46 +--- ...penIddictServerProviderTests.Revocation.cs | 24 +- ...IddictServerProviderTests.Serialization.cs | 156 ----------- .../OpenIddictServerProviderTests.Session.cs | 19 +- .../Internal/OpenIddictServerProviderTests.cs | 65 +---- 18 files changed, 231 insertions(+), 853 deletions(-) diff --git a/samples/Mvc.Server/Startup.cs b/samples/Mvc.Server/Startup.cs index c7977242..b6015c12 100644 --- a/samples/Mvc.Server/Startup.cs +++ b/samples/Mvc.Server/Startup.cs @@ -126,6 +126,13 @@ namespace Mvc.Server // that specify non-registered scopes, uncomment the following line: // // options.DisableScopeValidation(); + + // Note: if you don't want to use permissions, you can disable + // permission enforcement by uncommenting the following lines: + // + // options.IgnoreEndpointPermissions() + // .IgnoreGrantTypePermissions() + // .IgnoreScopePermissions(); }) // Register the OpenIddict validation handler. @@ -180,7 +187,10 @@ namespace Mvc.Server OpenIddictConstants.Permissions.Endpoints.Logout, OpenIddictConstants.Permissions.Endpoints.Token, OpenIddictConstants.Permissions.GrantTypes.AuthorizationCode, - OpenIddictConstants.Permissions.GrantTypes.RefreshToken + OpenIddictConstants.Permissions.GrantTypes.RefreshToken, + OpenIddictConstants.Permissions.Scopes.Email, + OpenIddictConstants.Permissions.Scopes.Profile, + OpenIddictConstants.Permissions.Scopes.Roles } }; @@ -207,7 +217,10 @@ namespace Mvc.Server { OpenIddictConstants.Permissions.Endpoints.Authorization, OpenIddictConstants.Permissions.Endpoints.Token, - OpenIddictConstants.Permissions.GrantTypes.AuthorizationCode + OpenIddictConstants.Permissions.GrantTypes.AuthorizationCode, + OpenIddictConstants.Permissions.Scopes.Email, + OpenIddictConstants.Permissions.Scopes.Profile, + OpenIddictConstants.Permissions.Scopes.Roles } }; diff --git a/src/OpenIddict.Abstractions/Managers/IOpenIddictApplicationManager.cs b/src/OpenIddict.Abstractions/Managers/IOpenIddictApplicationManager.cs index 717fa176..ddab1219 100644 --- a/src/OpenIddict.Abstractions/Managers/IOpenIddictApplicationManager.cs +++ b/src/OpenIddict.Abstractions/Managers/IOpenIddictApplicationManager.cs @@ -395,17 +395,6 @@ namespace OpenIddict.Abstractions /// Task ValidateClientSecretAsync([NotNull] object application, string secret, CancellationToken cancellationToken = default); - /// - /// Validates the specified post_logout_redirect_uri. - /// - /// The address that should be compared to the post_logout_redirect_uri stored in the database. - /// The that can be used to abort the operation. - /// - /// A that can be used to monitor the asynchronous operation, whose result - /// returns a boolean indicating whether the post_logout_redirect_uri was valid. - /// - Task ValidatePostLogoutRedirectUriAsync([NotNull] string address, CancellationToken cancellationToken = default); - /// /// Validates the redirect_uri to ensure it's associated with an application. /// diff --git a/src/OpenIddict.Abstractions/OpenIddictConstants.cs b/src/OpenIddict.Abstractions/OpenIddictConstants.cs index c1dd31ba..0d7deddb 100644 --- a/src/OpenIddict.Abstractions/OpenIddictConstants.cs +++ b/src/OpenIddict.Abstractions/OpenIddictConstants.cs @@ -70,6 +70,17 @@ namespace OpenIddict.Abstractions public const string GrantType = "gt:"; public const string Scope = "scp:"; } + + public static class Scopes + { + public const string Address = "scp:address"; + public const string Email = "scp:email"; + public const string OfflineAccess = "scp:offline_access"; + public const string OpenId = "scp:openid"; + public const string Phone = "scp:phone"; + public const string Profile = "scp:profile"; + public const string Roles = "scp:roles"; + } } public static class Properties diff --git a/src/OpenIddict.Core/Managers/OpenIddictApplicationManager.cs b/src/OpenIddict.Core/Managers/OpenIddictApplicationManager.cs index 67e7238b..221ca27a 100644 --- a/src/OpenIddict.Core/Managers/OpenIddictApplicationManager.cs +++ b/src/OpenIddict.Core/Managers/OpenIddictApplicationManager.cs @@ -583,107 +583,7 @@ namespace OpenIddict.Core throw new ArgumentException("The permission name cannot be null or empty.", nameof(permission)); } - // Note: all the string-based comparisons used by this method are ordinal (and thus case-sensitive). - - var permissions = await Store.GetPermissionsAsync(application, cancellationToken); - - bool HasPermission(string name) - { - if (permissions.IsEmpty) - { - return false; - } - - return permissions.Contains(name); - } - - bool HasEndpointPermission(string name) - { - // If the requested permission is an "endpoint" permission, return true if it has been - // explicitly granted OR if no other endpoint permission has been explicitly registered. - - if (permissions.IsEmpty || HasPermission(name)) - { - return true; - } - - if (permissions.Any(element => element.StartsWith(OpenIddictConstants.Permissions.Prefixes.Endpoint))) - { - return false; - } - - return true; - } - - bool HasGrantTypePermission(string name) - { - // If the requested permission is a "grant_type" permission, return true if it has been - // explicitly granted OR if the application is allowed to use the corresponding endpoint - // AND no other grant type permission has been explicitly registered. - - if (permissions.IsEmpty || HasPermission(name)) - { - return true; - } - - if (permissions.Any(element => element.StartsWith(OpenIddictConstants.Permissions.Prefixes.GrantType))) - { - return false; - } - - switch (permission) - { - case OpenIddictConstants.Permissions.GrantTypes.AuthorizationCode: - return HasEndpointPermission(OpenIddictConstants.Permissions.Endpoints.Authorization) && - HasEndpointPermission(OpenIddictConstants.Permissions.Endpoints.Token); - - case OpenIddictConstants.Permissions.GrantTypes.Implicit: - return HasEndpointPermission(OpenIddictConstants.Permissions.Endpoints.Authorization); - - default: - case OpenIddictConstants.Permissions.GrantTypes.ClientCredentials: - case OpenIddictConstants.Permissions.GrantTypes.Password: - case OpenIddictConstants.Permissions.GrantTypes.RefreshToken: - return HasEndpointPermission(OpenIddictConstants.Permissions.Endpoints.Token); - } - } - - bool HasScopePermission(string name) - { - // If the requested permission is a "scope" permission, return true if it has been - // explicitly granted OR if the application is allowed to use the authorization or - // token endpoints AND no other scope permission has been explicitly registered. - - if (permissions.IsEmpty || HasPermission(name)) - { - return true; - } - - if (permissions.Any(element => element.StartsWith(OpenIddictConstants.Permissions.Prefixes.Scope))) - { - return false; - } - - return HasEndpointPermission(OpenIddictConstants.Permissions.Endpoints.Authorization) || - HasEndpointPermission(OpenIddictConstants.Permissions.Endpoints.Token); - } - - if (permission.StartsWith(OpenIddictConstants.Permissions.Prefixes.Endpoint)) - { - return HasEndpointPermission(permission); - } - - if (permission.StartsWith(OpenIddictConstants.Permissions.Prefixes.GrantType)) - { - return HasGrantTypePermission(permission); - } - - if (permission.StartsWith(OpenIddictConstants.Permissions.Prefixes.Scope)) - { - return HasScopePermission(permission); - } - - return HasPermission(permission); + return (await GetPermissionsAsync(application, cancellationToken)).Contains(permission); } /// @@ -1218,40 +1118,6 @@ namespace OpenIddict.Core return true; } - /// - /// Validates the specified post_logout_redirect_uri. - /// - /// The address that should be compared to the post_logout_redirect_uri stored in the database. - /// The that can be used to abort the operation. - /// - /// A that can be used to monitor the asynchronous operation, whose result - /// returns a boolean indicating whether the post_logout_redirect_uri was valid. - /// - public virtual async Task ValidatePostLogoutRedirectUriAsync( - [NotNull] string address, CancellationToken cancellationToken = default) - { - if (string.IsNullOrEmpty(address)) - { - throw new ArgumentException("The address cannot be null or empty.", nameof(address)); - } - - foreach (var application in await FindByPostLogoutRedirectUriAsync(address, cancellationToken)) - { - // If the application is not allowed to use the logout endpoint, ignore it and keep iterating. - if (!await HasPermissionAsync(application, OpenIddictConstants.Permissions.Endpoints.Logout, cancellationToken)) - { - continue; - } - - return true; - } - - Logger.LogWarning("Client validation failed because '{PostLogoutRedirectUri}' " + - "was not a valid post_logout_redirect_uri.", address); - - return false; - } - /// /// Validates the redirect_uri to ensure it's associated with an application. /// @@ -1450,9 +1316,6 @@ namespace OpenIddict.Core Task IOpenIddictApplicationManager.ValidateClientSecretAsync(object application, string secret, CancellationToken cancellationToken) => ValidateClientSecretAsync((TApplication) application, secret, cancellationToken); - Task IOpenIddictApplicationManager.ValidatePostLogoutRedirectUriAsync(string address, CancellationToken cancellationToken) - => ValidatePostLogoutRedirectUriAsync(address, cancellationToken); - Task IOpenIddictApplicationManager.ValidateRedirectUriAsync(object application, string address, CancellationToken cancellationToken) => ValidateRedirectUriAsync((TApplication) application, address, cancellationToken); } diff --git a/src/OpenIddict.Server/Internal/OpenIddictServerProvider.Authentication.cs b/src/OpenIddict.Server/Internal/OpenIddictServerProvider.Authentication.cs index a2e92059..e519ffc9 100644 --- a/src/OpenIddict.Server/Internal/OpenIddictServerProvider.Authentication.cs +++ b/src/OpenIddict.Server/Internal/OpenIddictServerProvider.Authentication.cs @@ -316,7 +316,8 @@ namespace OpenIddict.Server } // Reject the request if the application is not allowed to use the authorization endpoint. - if (!await _applicationManager.HasPermissionAsync(application, OpenIddictConstants.Permissions.Endpoints.Authorization)) + if (!options.IgnoreEndpointPermissions && + !await _applicationManager.HasPermissionAsync(application, OpenIddictConstants.Permissions.Endpoints.Authorization)) { _logger.LogError("The authorization request was rejected because the application '{ClientId}' " + "was not allowed to use the authorization endpoint.", context.ClientId); @@ -328,62 +329,65 @@ namespace OpenIddict.Server return; } - // Reject the request if the application is not allowed to use the authorization code flow. - if (context.Request.IsAuthorizationCodeFlow() && !await _applicationManager.HasPermissionAsync( - application, OpenIddictConstants.Permissions.GrantTypes.AuthorizationCode)) + if (!options.IgnoreGrantTypePermissions) { - _logger.LogError("The authorization request was rejected because the application '{ClientId}' " + - "was not allowed to use the authorization code flow.", context.ClientId); + // Reject the request if the application is not allowed to use the authorization code flow. + if (context.Request.IsAuthorizationCodeFlow() && !await _applicationManager.HasPermissionAsync( + application, OpenIddictConstants.Permissions.GrantTypes.AuthorizationCode)) + { + _logger.LogError("The authorization request was rejected because the application '{ClientId}' " + + "was not allowed to use the authorization code flow.", context.ClientId); - context.Reject( - error: OpenIdConnectConstants.Errors.UnauthorizedClient, - description: "The client application is not allowed to use the authorization code flow."); + context.Reject( + error: OpenIdConnectConstants.Errors.UnauthorizedClient, + description: "The client application is not allowed to use the authorization code flow."); - return; - } + return; + } - // Reject the request if the application is not allowed to use the implicit flow. - if (context.Request.IsImplicitFlow() && !await _applicationManager.HasPermissionAsync( - application, OpenIddictConstants.Permissions.GrantTypes.Implicit)) - { - _logger.LogError("The authorization request was rejected because the application '{ClientId}' " + - "was not allowed to use the implicit flow.", context.ClientId); + // Reject the request if the application is not allowed to use the implicit flow. + if (context.Request.IsImplicitFlow() && !await _applicationManager.HasPermissionAsync( + application, OpenIddictConstants.Permissions.GrantTypes.Implicit)) + { + _logger.LogError("The authorization request was rejected because the application '{ClientId}' " + + "was not allowed to use the implicit flow.", context.ClientId); - context.Reject( - error: OpenIdConnectConstants.Errors.UnauthorizedClient, - description: "The client application is not allowed to use the implicit flow."); + context.Reject( + error: OpenIdConnectConstants.Errors.UnauthorizedClient, + description: "The client application is not allowed to use the implicit flow."); - return; - } + return; + } - // Reject the request if the application is not allowed to use the authorization code/implicit flows. - if (context.Request.IsHybridFlow() && - (!await _applicationManager.HasPermissionAsync(application, OpenIddictConstants.Permissions.GrantTypes.AuthorizationCode) || - !await _applicationManager.HasPermissionAsync(application, OpenIddictConstants.Permissions.GrantTypes.Implicit))) - { - _logger.LogError("The authorization request was rejected because the application '{ClientId}' " + - "was not allowed to use the hybrid flow.", context.ClientId); + // Reject the request if the application is not allowed to use the authorization code/implicit flows. + if (context.Request.IsHybridFlow() && + (!await _applicationManager.HasPermissionAsync(application, OpenIddictConstants.Permissions.GrantTypes.AuthorizationCode) || + !await _applicationManager.HasPermissionAsync(application, OpenIddictConstants.Permissions.GrantTypes.Implicit))) + { + _logger.LogError("The authorization request was rejected because the application '{ClientId}' " + + "was not allowed to use the hybrid flow.", context.ClientId); - context.Reject( - error: OpenIdConnectConstants.Errors.UnauthorizedClient, - description: "The client application is not allowed to use the hybrid flow."); + context.Reject( + error: OpenIdConnectConstants.Errors.UnauthorizedClient, + description: "The client application is not allowed to use the hybrid flow."); - return; - } + return; + } - // Reject the request if the offline_access scope was request and if the - // application is not allowed to use the authorization code/implicit flows. - if (context.Request.HasScope(OpenIdConnectConstants.Scopes.OfflineAccess) && - !await _applicationManager.HasPermissionAsync(application, OpenIddictConstants.Permissions.GrantTypes.RefreshToken)) - { - _logger.LogError("The authorization request was rejected because the application '{ClientId}' " + - "was not allowed to request the 'offline_access' scope.", context.ClientId); + // Reject the request if the offline_access scope was request and if the + // application is not allowed to use the authorization code/implicit flows. + if (context.Request.HasScope(OpenIdConnectConstants.Scopes.OfflineAccess) && + !await _applicationManager.HasPermissionAsync(application, OpenIddictConstants.Permissions.GrantTypes.RefreshToken)) + { + _logger.LogError("The authorization request was rejected because the application '{ClientId}' " + + "was not allowed to request the 'offline_access' scope.", context.ClientId); - context.Reject( - error: OpenIdConnectConstants.Errors.InvalidRequest, - description: "The client application is not allowed to use the 'offline_access' scope."); + context.Reject( + error: OpenIdConnectConstants.Errors.InvalidRequest, + description: "The client application is not allowed to use the 'offline_access' scope."); - return; + return; + } } // Ensure that the specified redirect_uri is valid and is associated with the client application. @@ -399,26 +403,31 @@ namespace OpenIddict.Server return; } - foreach (var scope in context.Request.GetScopes()) + // Unless permission enforcement was explicitly disabled, ensure + // the client application is allowed to use the specified scopes. + if (!options.IgnoreScopePermissions) { - // Avoid validating the "openid" and "offline_access" scopes as they represent protocol scopes. - if (string.Equals(scope, OpenIdConnectConstants.Scopes.OfflineAccess, StringComparison.Ordinal) || - string.Equals(scope, OpenIdConnectConstants.Scopes.OpenId, StringComparison.Ordinal)) + foreach (var scope in context.Request.GetScopes()) { - continue; - } + // Avoid validating the "openid" and "offline_access" scopes as they represent protocol scopes. + if (string.Equals(scope, OpenIdConnectConstants.Scopes.OfflineAccess, StringComparison.Ordinal) || + string.Equals(scope, OpenIdConnectConstants.Scopes.OpenId, StringComparison.Ordinal)) + { + continue; + } - // Reject the request if the application is not allowed to use the iterated scope. - if (!await _applicationManager.HasPermissionAsync(application, OpenIddictConstants.Permissions.Prefixes.Scope + scope)) - { - _logger.LogError("The authorization request was rejected because the application '{ClientId}' " + - "was not allowed to use the scope {Scope}.", context.ClientId, scope); + // Reject the request if the application is not allowed to use the iterated scope. + if (!await _applicationManager.HasPermissionAsync(application, OpenIddictConstants.Permissions.Prefixes.Scope + scope)) + { + _logger.LogError("The authorization request was rejected because the application '{ClientId}' " + + "was not allowed to use the scope {Scope}.", context.ClientId, scope); - context.Reject( - error: OpenIdConnectConstants.Errors.InvalidRequest, - description: "This client application is not allowed to use the specified scope."); + context.Reject( + error: OpenIdConnectConstants.Errors.InvalidRequest, + description: "This client application is not allowed to use the specified scope."); - return; + return; + } } } diff --git a/src/OpenIddict.Server/Internal/OpenIddictServerProvider.Exchange.cs b/src/OpenIddict.Server/Internal/OpenIddictServerProvider.Exchange.cs index 458c3cb1..664fa0bb 100644 --- a/src/OpenIddict.Server/Internal/OpenIddictServerProvider.Exchange.cs +++ b/src/OpenIddict.Server/Internal/OpenIddictServerProvider.Exchange.cs @@ -166,7 +166,8 @@ namespace OpenIddict.Server context.Request.SetProperty($"{OpenIddictConstants.Properties.Application}:{context.ClientId}", application); // Reject the request if the application is not allowed to use the token endpoint. - if (!await _applicationManager.HasPermissionAsync(application, OpenIddictConstants.Permissions.Endpoints.Token)) + if (!options.IgnoreEndpointPermissions && + !await _applicationManager.HasPermissionAsync(application, OpenIddictConstants.Permissions.Endpoints.Token)) { _logger.LogError("The token request was rejected because the application '{ClientId}' " + "was not allowed to use the token endpoint.", context.ClientId); @@ -179,7 +180,8 @@ namespace OpenIddict.Server } // Reject the request if the application is not allowed to use the specified grant type. - if (!await _applicationManager.HasPermissionAsync(application, + if (!options.IgnoreGrantTypePermissions && + !await _applicationManager.HasPermissionAsync(application, OpenIddictConstants.Permissions.Prefixes.GrantType + context.Request.GrantType)) { _logger.LogError("The token request was rejected because the application '{ClientId}' was not allowed to " + @@ -256,27 +258,32 @@ namespace OpenIddict.Server return; } - foreach (var scope in context.Request.GetScopes()) + // Unless permission enforcement was explicitly disabled, ensure + // the client application is allowed to use the specified scopes. + if (!options.IgnoreScopePermissions) { - // Avoid validating the "openid" and "offline_access" scopes as they represent protocol scopes. - if (string.Equals(scope, OpenIdConnectConstants.Scopes.OfflineAccess, StringComparison.Ordinal) || - string.Equals(scope, OpenIdConnectConstants.Scopes.OpenId, StringComparison.Ordinal)) + foreach (var scope in context.Request.GetScopes()) { - continue; - } + // Avoid validating the "openid" and "offline_access" scopes as they represent protocol scopes. + if (string.Equals(scope, OpenIdConnectConstants.Scopes.OfflineAccess, StringComparison.Ordinal) || + string.Equals(scope, OpenIdConnectConstants.Scopes.OpenId, StringComparison.Ordinal)) + { + continue; + } - // Reject the request if the application is not allowed to use the iterated scope. - if (!await _applicationManager.HasPermissionAsync(application, - OpenIddictConstants.Permissions.Prefixes.Scope + scope)) - { - _logger.LogError("The token request was rejected because the application '{ClientId}' " + - "was not allowed to use the scope {Scope}.", context.ClientId, scope); + // Reject the request if the application is not allowed to use the iterated scope. + if (!await _applicationManager.HasPermissionAsync(application, + OpenIddictConstants.Permissions.Prefixes.Scope + scope)) + { + _logger.LogError("The token request was rejected because the application '{ClientId}' " + + "was not allowed to use the scope {Scope}.", context.ClientId, scope); - context.Reject( - error: OpenIdConnectConstants.Errors.InvalidRequest, - description: "This client application is not allowed to use the specified scope."); + context.Reject( + error: OpenIdConnectConstants.Errors.InvalidRequest, + description: "This client application is not allowed to use the specified scope."); - return; + return; + } } } diff --git a/src/OpenIddict.Server/Internal/OpenIddictServerProvider.Introspection.cs b/src/OpenIddict.Server/Internal/OpenIddictServerProvider.Introspection.cs index ae0c96fc..e33d9bf5 100644 --- a/src/OpenIddict.Server/Internal/OpenIddictServerProvider.Introspection.cs +++ b/src/OpenIddict.Server/Internal/OpenIddictServerProvider.Introspection.cs @@ -19,6 +19,8 @@ namespace OpenIddict.Server { public override async Task ValidateIntrospectionRequest([NotNull] ValidateIntrospectionRequestContext context) { + var options = (OpenIddictServerOptions) context.Options; + // Note: the OpenID Connect server middleware supports unauthenticated introspection requests // but OpenIddict uses a stricter policy preventing unauthenticated/public applications // from using the introspection endpoint, as required by the specifications. @@ -51,7 +53,8 @@ namespace OpenIddict.Server context.Request.SetProperty($"{OpenIddictConstants.Properties.Application}:{context.ClientId}", application); // Reject the request if the application is not allowed to use the introspection endpoint. - if (!await _applicationManager.HasPermissionAsync(application, OpenIddictConstants.Permissions.Endpoints.Introspection)) + if (!options.IgnoreEndpointPermissions && + !await _applicationManager.HasPermissionAsync(application, OpenIddictConstants.Permissions.Endpoints.Introspection)) { _logger.LogError("The introspection request was rejected because the application '{ClientId}' " + "was not allowed to use the introspection endpoint.", context.ClientId); diff --git a/src/OpenIddict.Server/Internal/OpenIddictServerProvider.Revocation.cs b/src/OpenIddict.Server/Internal/OpenIddictServerProvider.Revocation.cs index aceaacb9..1f69dcba 100644 --- a/src/OpenIddict.Server/Internal/OpenIddictServerProvider.Revocation.cs +++ b/src/OpenIddict.Server/Internal/OpenIddictServerProvider.Revocation.cs @@ -94,7 +94,8 @@ namespace OpenIddict.Server context.Request.SetProperty($"{OpenIddictConstants.Properties.Application}:{context.ClientId}", application); // Reject the request if the application is not allowed to use the revocation endpoint. - if (!await _applicationManager.HasPermissionAsync(application, OpenIddictConstants.Permissions.Endpoints.Revocation)) + if (!options.IgnoreEndpointPermissions && + !await _applicationManager.HasPermissionAsync(application, OpenIddictConstants.Permissions.Endpoints.Revocation)) { _logger.LogError("The revocation request was rejected because the application '{ClientId}' " + "was not allowed to use the revocation endpoint.", context.ClientId); diff --git a/src/OpenIddict.Server/Internal/OpenIddictServerProvider.Session.cs b/src/OpenIddict.Server/Internal/OpenIddictServerProvider.Session.cs index c3a34a2a..7feaf96a 100644 --- a/src/OpenIddict.Server/Internal/OpenIddictServerProvider.Session.cs +++ b/src/OpenIddict.Server/Internal/OpenIddictServerProvider.Session.cs @@ -82,6 +82,8 @@ namespace OpenIddict.Server public override async Task ValidateLogoutRequest([NotNull] ValidateLogoutRequestContext context) { + var options = (OpenIddictServerOptions) context.Options; + // If an optional post_logout_redirect_uri was provided, validate it. if (!string.IsNullOrEmpty(context.PostLogoutRedirectUri)) { @@ -109,7 +111,32 @@ namespace OpenIddict.Server return; } - if (!await _applicationManager.ValidatePostLogoutRedirectUriAsync(context.PostLogoutRedirectUri)) + async Task ValidatePostLogoutRedirectUriAsync(string address) + { + var applications = await _applicationManager.FindByPostLogoutRedirectUriAsync(address); + if (applications.IsDefaultOrEmpty) + { + return false; + } + + if (options.IgnoreEndpointPermissions) + { + return true; + } + + foreach (var application in applications) + { + if (await _applicationManager.HasPermissionAsync( + application, OpenIddictConstants.Permissions.Endpoints.Logout)) + { + return true; + } + } + + return false; + } + + if (!await ValidatePostLogoutRedirectUriAsync(context.PostLogoutRedirectUri)) { _logger.LogError("The logout request was rejected because the specified post_logout_redirect_uri " + "was unknown: {PostLogoutRedirectUri}.", context.PostLogoutRedirectUri); diff --git a/src/OpenIddict.Server/OpenIddictServerBuilder.cs b/src/OpenIddict.Server/OpenIddictServerBuilder.cs index c75dd76f..2ce9161f 100644 --- a/src/OpenIddict.Server/OpenIddictServerBuilder.cs +++ b/src/OpenIddict.Server/OpenIddictServerBuilder.cs @@ -507,6 +507,30 @@ namespace Microsoft.Extensions.DependencyInjection return Configure(options => options.UserinfoEndpointPath = path); } + /// + /// Disables endpoint permissions enforcement. Calling this method is NOT recommended, + /// unless all the clients are first-party applications you own, control and fully trust. + /// + /// The . + public OpenIddictServerBuilder IgnoreEndpointPermissions() + => Configure(options => options.IgnoreEndpointPermissions = true); + + /// + /// Disables grant type permissions enforcement. Calling this method is NOT recommended, + /// unless all the clients are first-party applications you own, control and fully trust. + /// + /// The . + public OpenIddictServerBuilder IgnoreGrantTypePermissions() + => Configure(options => options.IgnoreGrantTypePermissions = true); + + /// + /// Disables scope permissions enforcement. Calling this method is NOT recommended, + /// unless all the clients are first-party applications you own, control and fully trust. + /// + /// The . + public OpenIddictServerBuilder IgnoreScopePermissions() + => Configure(options => options.IgnoreScopePermissions = true); + /// /// Registers the specified claims as supported claims so /// they can be returned as part of the discovery document. diff --git a/src/OpenIddict.Server/OpenIddictServerOptions.cs b/src/OpenIddict.Server/OpenIddictServerOptions.cs index d9afb20a..bfa7c6a6 100644 --- a/src/OpenIddict.Server/OpenIddictServerOptions.cs +++ b/src/OpenIddict.Server/OpenIddictServerOptions.cs @@ -100,6 +100,27 @@ namespace OpenIddict.Server /// public ISet GrantTypes { get; } = new HashSet(StringComparer.Ordinal); + /// + /// Gets or sets a boolean indicating whether endpoint permissions should be ignored. + /// Setting this property to true is NOT recommended, unless all + /// the clients are first-party applications you own, control and fully trust. + /// + public bool IgnoreEndpointPermissions { get; set; } + + /// + /// Gets or sets a boolean indicating whether grant type permissions should be ignored. + /// Setting this property to true is NOT recommended, unless all + /// the clients are first-party applications you own, control and fully trust. + /// + public bool IgnoreGrantTypePermissions { get; set; } + + /// + /// Gets or sets a boolean indicating whether scope permissions should be ignored. + /// Setting this property to true is NOT recommended, unless all + /// the clients are first-party applications you own, control and fully trust. + /// + public bool IgnoreScopePermissions { get; set; } + /// /// Gets or sets the random number generator used to generate crypto-secure identifiers. /// diff --git a/test/OpenIddict.Server.Tests/Internal/OpenIddictServerProviderTests.Authentication.cs b/test/OpenIddict.Server.Tests/Internal/OpenIddictServerProviderTests.Authentication.cs index 1181ba82..bf929c4c 100644 --- a/test/OpenIddict.Server.Tests/Internal/OpenIddictServerProviderTests.Authentication.cs +++ b/test/OpenIddict.Server.Tests/Internal/OpenIddictServerProviderTests.Authentication.cs @@ -241,18 +241,6 @@ namespace OpenIddict.Server.Tests instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny())) .Returns(new ValueTask(OpenIddictConstants.ClientTypes.Public)); - - instance.Setup(mock => mock.HasPermissionAsync(application, - OpenIddictConstants.Permissions.Endpoints.Authorization, It.IsAny())) - .ReturnsAsync(true); - - instance.Setup(mock => mock.HasPermissionAsync(application, - OpenIddictConstants.Permissions.GrantTypes.Implicit, It.IsAny())) - .ReturnsAsync(true); - - instance.Setup(mock => mock.HasPermissionAsync(application, - OpenIddictConstants.Permissions.Prefixes.Scope + "registered_scope", It.IsAny())) - .ReturnsAsync(true); })); builder.RegisterScopes("registered_scope"); @@ -308,22 +296,6 @@ namespace OpenIddict.Server.Tests instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny())) .Returns(new ValueTask(OpenIddictConstants.ClientTypes.Public)); - - instance.Setup(mock => mock.HasPermissionAsync(application, - OpenIddictConstants.Permissions.Endpoints.Authorization, It.IsAny())) - .ReturnsAsync(true); - - instance.Setup(mock => mock.HasPermissionAsync(application, - OpenIddictConstants.Permissions.GrantTypes.Implicit, It.IsAny())) - .ReturnsAsync(true); - - instance.Setup(mock => mock.HasPermissionAsync(application, - OpenIddictConstants.Permissions.Prefixes.Scope + "scope_registered_in_database", It.IsAny())) - .ReturnsAsync(true); - - instance.Setup(mock => mock.HasPermissionAsync(application, - OpenIddictConstants.Permissions.Prefixes.Scope + "scope_registered_in_options", It.IsAny())) - .ReturnsAsync(true); })); builder.RegisterScopes("scope_registered_in_options"); @@ -586,6 +558,8 @@ namespace OpenIddict.Server.Tests var server = CreateAuthorizationServer(builder => { builder.Services.AddSingleton(manager); + + builder.Configure(options => options.IgnoreEndpointPermissions = false); }); var client = new OpenIdConnectClient(server.CreateClient()); @@ -647,10 +621,6 @@ namespace OpenIddict.Server.Tests instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny())) .ReturnsAsync(application); - instance.Setup(mock => mock.HasPermissionAsync(application, - OpenIddictConstants.Permissions.Endpoints.Authorization, It.IsAny())) - .ReturnsAsync(true); - foreach (var permission in permissions) { instance.Setup(mock => mock.HasPermissionAsync(application, permission, It.IsAny())) @@ -661,6 +631,8 @@ namespace OpenIddict.Server.Tests var server = CreateAuthorizationServer(builder => { builder.Services.AddSingleton(manager); + + builder.Configure(options => options.IgnoreGrantTypePermissions = false); }); var client = new OpenIdConnectClient(server.CreateClient()); @@ -680,8 +652,6 @@ namespace OpenIddict.Server.Tests Assert.Equal(description, response.ErrorDescription); Mock.Get(manager).Verify(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny()), Times.Once()); - Mock.Get(manager).Verify(mock => mock.HasPermissionAsync(application, - OpenIddictConstants.Permissions.Endpoints.Authorization, It.IsAny()), Times.Once()); Mock.Get(manager).Verify(mock => mock.HasPermissionAsync(application, permissions[0], It.IsAny()), Times.Once()); } @@ -696,14 +666,6 @@ namespace OpenIddict.Server.Tests instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny())) .ReturnsAsync(application); - instance.Setup(mock => mock.HasPermissionAsync(application, - OpenIddictConstants.Permissions.Endpoints.Authorization, It.IsAny())) - .ReturnsAsync(true); - - instance.Setup(mock => mock.HasPermissionAsync(application, - OpenIddictConstants.Permissions.GrantTypes.AuthorizationCode, It.IsAny())) - .ReturnsAsync(true); - instance.Setup(mock => mock.ValidateRedirectUriAsync(application, "http://www.fabrikam.com/path", It.IsAny())) .ReturnsAsync(false); }); @@ -728,10 +690,6 @@ namespace OpenIddict.Server.Tests Assert.Equal("The specified 'redirect_uri' parameter is not valid for this client application.", response.ErrorDescription); Mock.Get(manager).Verify(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny()), Times.Once()); - Mock.Get(manager).Verify(mock => mock.HasPermissionAsync(application, - OpenIddictConstants.Permissions.Endpoints.Authorization, It.IsAny()), Times.Once()); - Mock.Get(manager).Verify(mock => mock.HasPermissionAsync(application, - OpenIddictConstants.Permissions.GrantTypes.AuthorizationCode, It.IsAny()), Times.Once()); Mock.Get(manager).Verify(mock => mock.ValidateRedirectUriAsync(application, "http://www.fabrikam.com/path", It.IsAny()), Times.Once()); } @@ -746,18 +704,6 @@ namespace OpenIddict.Server.Tests instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny())) .ReturnsAsync(application); - instance.Setup(mock => mock.HasPermissionAsync(application, - OpenIddictConstants.Permissions.Endpoints.Authorization, It.IsAny())) - .ReturnsAsync(true); - - instance.Setup(mock => mock.HasPermissionAsync(application, - OpenIddictConstants.Permissions.GrantTypes.AuthorizationCode, It.IsAny())) - .ReturnsAsync(true); - - instance.Setup(mock => mock.HasPermissionAsync(application, - OpenIddictConstants.Permissions.GrantTypes.RefreshToken, It.IsAny())) - .ReturnsAsync(true); - instance.Setup(mock => mock.ValidateRedirectUriAsync(application, "http://www.fabrikam.com/path", It.IsAny())) .ReturnsAsync(true); @@ -776,6 +722,7 @@ namespace OpenIddict.Server.Tests { builder.Services.AddSingleton(manager); builder.RegisterScopes(OpenIdConnectConstants.Scopes.Email, OpenIdConnectConstants.Scopes.Profile); + builder.Configure(options => options.IgnoreScopePermissions = false); }); var client = new OpenIdConnectClient(server.CreateClient()); @@ -823,14 +770,6 @@ namespace OpenIddict.Server.Tests instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny())) .ReturnsAsync(application); - instance.Setup(mock => mock.HasPermissionAsync(application, - OpenIddictConstants.Permissions.Endpoints.Authorization, It.IsAny())) - .ReturnsAsync(true); - - instance.Setup(mock => mock.HasPermissionAsync(application, - OpenIddictConstants.Permissions.GrantTypes.Implicit, It.IsAny())) - .ReturnsAsync(true); - instance.Setup(mock => mock.ValidateRedirectUriAsync(application, "http://www.fabrikam.com/path", It.IsAny())) .ReturnsAsync(true); @@ -890,18 +829,6 @@ namespace OpenIddict.Server.Tests instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny())) .ReturnsAsync(application); - instance.Setup(mock => mock.HasPermissionAsync(application, - OpenIddictConstants.Permissions.Endpoints.Authorization, It.IsAny())) - .ReturnsAsync(true); - - instance.Setup(mock => mock.HasPermissionAsync(application, - OpenIddictConstants.Permissions.GrantTypes.AuthorizationCode, It.IsAny())) - .ReturnsAsync(true); - - instance.Setup(mock => mock.HasPermissionAsync(application, - OpenIddictConstants.Permissions.GrantTypes.Implicit, It.IsAny())) - .ReturnsAsync(true); - instance.Setup(mock => mock.ValidateRedirectUriAsync(application, "http://www.fabrikam.com/path", It.IsAny())) .ReturnsAsync(true); @@ -978,14 +905,6 @@ namespace OpenIddict.Server.Tests instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny())) .ReturnsAsync(application); - instance.Setup(mock => mock.HasPermissionAsync(application, - OpenIddictConstants.Permissions.Endpoints.Authorization, It.IsAny())) - .ReturnsAsync(true); - - instance.Setup(mock => mock.HasPermissionAsync(application, - OpenIddictConstants.Permissions.GrantTypes.Implicit, It.IsAny())) - .ReturnsAsync(true); - instance.Setup(mock => mock.ValidateRedirectUriAsync(application, "http://www.fabrikam.com/path", It.IsAny())) .ReturnsAsync(true); diff --git a/test/OpenIddict.Server.Tests/Internal/OpenIddictServerProviderTests.Exchange.cs b/test/OpenIddict.Server.Tests/Internal/OpenIddictServerProviderTests.Exchange.cs index 46447828..8e8ce206 100644 --- a/test/OpenIddict.Server.Tests/Internal/OpenIddictServerProviderTests.Exchange.cs +++ b/test/OpenIddict.Server.Tests/Internal/OpenIddictServerProviderTests.Exchange.cs @@ -320,6 +320,8 @@ namespace OpenIddict.Server.Tests var server = CreateAuthorizationServer(builder => { builder.Services.AddSingleton(manager); + + builder.Configure(options => options.IgnoreEndpointPermissions = false); }); var client = new OpenIdConnectClient(server.CreateClient()); @@ -353,10 +355,6 @@ namespace OpenIddict.Server.Tests instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny())) .ReturnsAsync(application); - instance.Setup(mock => mock.HasPermissionAsync(application, - OpenIddictConstants.Permissions.Endpoints.Token, It.IsAny())) - .ReturnsAsync(true); - instance.Setup(mock => mock.HasPermissionAsync(application, OpenIddictConstants.Permissions.GrantTypes.Password, It.IsAny())) .ReturnsAsync(false); @@ -365,6 +363,8 @@ namespace OpenIddict.Server.Tests var server = CreateAuthorizationServer(builder => { builder.Services.AddSingleton(manager); + + builder.Configure(options => options.IgnoreGrantTypePermissions = false); }); var client = new OpenIdConnectClient(server.CreateClient()); @@ -383,8 +383,6 @@ namespace OpenIddict.Server.Tests Assert.Equal("This client application is not allowed to use the specified grant type.", response.ErrorDescription); Mock.Get(manager).Verify(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny()), Times.Once()); - Mock.Get(manager).Verify(mock => mock.HasPermissionAsync(application, - OpenIddictConstants.Permissions.Endpoints.Token, It.IsAny()), Times.Once()); Mock.Get(manager).Verify(mock => mock.HasPermissionAsync(application, OpenIddictConstants.Permissions.GrantTypes.Password, It.IsAny()), Times.Once()); } @@ -400,14 +398,6 @@ namespace OpenIddict.Server.Tests instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny())) .ReturnsAsync(application); - instance.Setup(mock => mock.HasPermissionAsync(application, - OpenIddictConstants.Permissions.Endpoints.Token, It.IsAny())) - .ReturnsAsync(true); - - instance.Setup(mock => mock.HasPermissionAsync(application, - OpenIddictConstants.Permissions.GrantTypes.ClientCredentials, It.IsAny())) - .ReturnsAsync(true); - instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny())) .Returns(new ValueTask(OpenIddictConstants.ClientTypes.Public)); }); @@ -432,10 +422,6 @@ namespace OpenIddict.Server.Tests Assert.Equal("The specified 'grant_type' parameter is not valid for this client application.", response.ErrorDescription); Mock.Get(manager).Verify(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny()), Times.Once()); - Mock.Get(manager).Verify(mock => mock.HasPermissionAsync(application, - OpenIddictConstants.Permissions.Endpoints.Token, It.IsAny()), Times.Once()); - Mock.Get(manager).Verify(mock => mock.HasPermissionAsync(application, - OpenIddictConstants.Permissions.GrantTypes.ClientCredentials, It.IsAny()), Times.Once()); Mock.Get(manager).Verify(mock => mock.GetClientTypeAsync(application, It.IsAny()), Times.Once()); } @@ -450,14 +436,6 @@ namespace OpenIddict.Server.Tests instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny())) .ReturnsAsync(application); - instance.Setup(mock => mock.HasPermissionAsync(application, - OpenIddictConstants.Permissions.Endpoints.Token, It.IsAny())) - .ReturnsAsync(true); - - instance.Setup(mock => mock.HasPermissionAsync(application, - OpenIddictConstants.Permissions.GrantTypes.Password, It.IsAny())) - .ReturnsAsync(true); - instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny())) .Returns(new ValueTask(OpenIddictConstants.ClientTypes.Public)); }); @@ -484,10 +462,6 @@ namespace OpenIddict.Server.Tests Assert.Equal("The 'client_secret' parameter is not valid for this client application.", response.ErrorDescription); Mock.Get(manager).Verify(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny()), Times.Once()); - Mock.Get(manager).Verify(mock => mock.HasPermissionAsync(application, - OpenIddictConstants.Permissions.Endpoints.Token, It.IsAny()), Times.Once()); - Mock.Get(manager).Verify(mock => mock.HasPermissionAsync(application, - OpenIddictConstants.Permissions.GrantTypes.Password, It.IsAny()), Times.Once()); Mock.Get(manager).Verify(mock => mock.GetClientTypeAsync(application, It.IsAny()), Times.Once()); } @@ -502,14 +476,6 @@ namespace OpenIddict.Server.Tests instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny())) .ReturnsAsync(application); - instance.Setup(mock => mock.HasPermissionAsync(application, - OpenIddictConstants.Permissions.Endpoints.Token, It.IsAny())) - .ReturnsAsync(true); - - instance.Setup(mock => mock.HasPermissionAsync(application, - OpenIddictConstants.Permissions.GrantTypes.Password, It.IsAny())) - .ReturnsAsync(true); - instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny())) .Returns(new ValueTask(OpenIddictConstants.ClientTypes.Confidential)); }); @@ -536,10 +502,6 @@ namespace OpenIddict.Server.Tests Assert.Equal("The 'client_secret' parameter required for this client application is missing.", response.ErrorDescription); Mock.Get(manager).Verify(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny()), Times.Once()); - Mock.Get(manager).Verify(mock => mock.HasPermissionAsync(application, - OpenIddictConstants.Permissions.Endpoints.Token, It.IsAny()), Times.Once()); - Mock.Get(manager).Verify(mock => mock.HasPermissionAsync(application, - OpenIddictConstants.Permissions.GrantTypes.Password, It.IsAny()), Times.Once()); Mock.Get(manager).Verify(mock => mock.GetClientTypeAsync(application, It.IsAny()), Times.Once()); } @@ -554,14 +516,6 @@ namespace OpenIddict.Server.Tests instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny())) .ReturnsAsync(application); - instance.Setup(mock => mock.HasPermissionAsync(application, - OpenIddictConstants.Permissions.Endpoints.Token, It.IsAny())) - .ReturnsAsync(true); - - instance.Setup(mock => mock.HasPermissionAsync(application, - OpenIddictConstants.Permissions.GrantTypes.Password, It.IsAny())) - .ReturnsAsync(true); - instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny())) .Returns(new ValueTask(OpenIddictConstants.ClientTypes.Hybrid)); }); @@ -588,10 +542,6 @@ namespace OpenIddict.Server.Tests Assert.Equal("The 'client_secret' parameter required for this client application is missing.", response.ErrorDescription); Mock.Get(manager).Verify(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny()), Times.Once()); - Mock.Get(manager).Verify(mock => mock.HasPermissionAsync(application, - OpenIddictConstants.Permissions.Endpoints.Token, It.IsAny()), Times.Once()); - Mock.Get(manager).Verify(mock => mock.HasPermissionAsync(application, - OpenIddictConstants.Permissions.GrantTypes.Password, It.IsAny()), Times.Once()); Mock.Get(manager).Verify(mock => mock.GetClientTypeAsync(application, It.IsAny()), Times.Once()); } @@ -606,14 +556,6 @@ namespace OpenIddict.Server.Tests instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny())) .ReturnsAsync(application); - instance.Setup(mock => mock.HasPermissionAsync(application, - OpenIddictConstants.Permissions.Endpoints.Token, It.IsAny())) - .ReturnsAsync(true); - - instance.Setup(mock => mock.HasPermissionAsync(application, - OpenIddictConstants.Permissions.GrantTypes.Password, It.IsAny())) - .ReturnsAsync(true); - instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny())) .Returns(new ValueTask(OpenIddictConstants.ClientTypes.Confidential)); @@ -643,10 +585,6 @@ namespace OpenIddict.Server.Tests Assert.Equal("The specified client credentials are invalid.", response.ErrorDescription); Mock.Get(manager).Verify(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny()), Times.Once()); - Mock.Get(manager).Verify(mock => mock.HasPermissionAsync(application, - OpenIddictConstants.Permissions.Endpoints.Token, It.IsAny()), Times.Once()); - Mock.Get(manager).Verify(mock => mock.HasPermissionAsync(application, - OpenIddictConstants.Permissions.GrantTypes.Password, It.IsAny()), Times.Once()); Mock.Get(manager).Verify(mock => mock.GetClientTypeAsync(application, It.IsAny()), Times.Once()); Mock.Get(manager).Verify(mock => mock.ValidateClientSecretAsync(application, "7Fjfp0ZBr1KtDRbnfVdmIw", It.IsAny()), Times.Once()); } @@ -662,18 +600,6 @@ namespace OpenIddict.Server.Tests instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny())) .ReturnsAsync(application); - instance.Setup(mock => mock.HasPermissionAsync(application, - OpenIddictConstants.Permissions.Endpoints.Token, It.IsAny())) - .ReturnsAsync(true); - - instance.Setup(mock => mock.HasPermissionAsync(application, - OpenIddictConstants.Permissions.GrantTypes.Password, It.IsAny())) - .ReturnsAsync(true); - - instance.Setup(mock => mock.HasPermissionAsync(application, - OpenIddictConstants.Permissions.GrantTypes.RefreshToken, It.IsAny())) - .ReturnsAsync(true); - instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny())) .Returns(new ValueTask(OpenIddictConstants.ClientTypes.Confidential)); @@ -698,6 +624,7 @@ namespace OpenIddict.Server.Tests { builder.Services.AddSingleton(manager); builder.RegisterScopes(OpenIdConnectConstants.Scopes.Email, OpenIdConnectConstants.Scopes.Profile); + builder.Configure(options => options.IgnoreScopePermissions = false); }); var client = new OpenIdConnectClient(server.CreateClient()); @@ -758,14 +685,6 @@ namespace OpenIddict.Server.Tests instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny())) .ReturnsAsync(application); - instance.Setup(mock => mock.HasPermissionAsync(application, - OpenIddictConstants.Permissions.Endpoints.Token, It.IsAny())) - .ReturnsAsync(true); - - instance.Setup(mock => mock.HasPermissionAsync(application, - OpenIddictConstants.Permissions.GrantTypes.AuthorizationCode, It.IsAny())) - .ReturnsAsync(true); - instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny())) .Returns(new ValueTask(OpenIddictConstants.ClientTypes.Public)); })); @@ -818,14 +737,6 @@ namespace OpenIddict.Server.Tests instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny())) .ReturnsAsync(application); - instance.Setup(mock => mock.HasPermissionAsync(application, - OpenIddictConstants.Permissions.Endpoints.Token, It.IsAny())) - .ReturnsAsync(true); - - instance.Setup(mock => mock.HasPermissionAsync(application, - OpenIddictConstants.Permissions.GrantTypes.RefreshToken, It.IsAny())) - .ReturnsAsync(true); - instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny())) .Returns(new ValueTask(OpenIddictConstants.ClientTypes.Public)); })); @@ -883,14 +794,6 @@ namespace OpenIddict.Server.Tests instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny())) .ReturnsAsync(application); - instance.Setup(mock => mock.HasPermissionAsync(application, - OpenIddictConstants.Permissions.Endpoints.Token, It.IsAny())) - .ReturnsAsync(true); - - instance.Setup(mock => mock.HasPermissionAsync(application, - OpenIddictConstants.Permissions.GrantTypes.AuthorizationCode, It.IsAny())) - .ReturnsAsync(true); - instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny())) .Returns(new ValueTask(OpenIddictConstants.ClientTypes.Public)); })); @@ -950,14 +853,6 @@ namespace OpenIddict.Server.Tests instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny())) .ReturnsAsync(application); - instance.Setup(mock => mock.HasPermissionAsync(application, - OpenIddictConstants.Permissions.Endpoints.Token, It.IsAny())) - .ReturnsAsync(true); - - instance.Setup(mock => mock.HasPermissionAsync(application, - OpenIddictConstants.Permissions.GrantTypes.RefreshToken, It.IsAny())) - .ReturnsAsync(true); - instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny())) .Returns(new ValueTask(OpenIddictConstants.ClientTypes.Public)); })); @@ -1024,14 +919,6 @@ namespace OpenIddict.Server.Tests instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny())) .ReturnsAsync(application); - instance.Setup(mock => mock.HasPermissionAsync(application, - OpenIddictConstants.Permissions.Endpoints.Token, It.IsAny())) - .ReturnsAsync(true); - - instance.Setup(mock => mock.HasPermissionAsync(application, - OpenIddictConstants.Permissions.GrantTypes.AuthorizationCode, It.IsAny())) - .ReturnsAsync(true); - instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny())) .Returns(new ValueTask(OpenIddictConstants.ClientTypes.Public)); })); @@ -1100,14 +987,6 @@ namespace OpenIddict.Server.Tests instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny())) .ReturnsAsync(application); - instance.Setup(mock => mock.HasPermissionAsync(application, - OpenIddictConstants.Permissions.Endpoints.Token, It.IsAny())) - .ReturnsAsync(true); - - instance.Setup(mock => mock.HasPermissionAsync(application, - OpenIddictConstants.Permissions.GrantTypes.RefreshToken, It.IsAny())) - .ReturnsAsync(true); - instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny())) .Returns(new ValueTask(OpenIddictConstants.ClientTypes.Public)); })); @@ -1170,14 +1049,6 @@ namespace OpenIddict.Server.Tests instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny())) .ReturnsAsync(application); - instance.Setup(mock => mock.HasPermissionAsync(application, - OpenIddictConstants.Permissions.Endpoints.Token, It.IsAny())) - .ReturnsAsync(true); - - instance.Setup(mock => mock.HasPermissionAsync(application, - OpenIddictConstants.Permissions.GrantTypes.AuthorizationCode, It.IsAny())) - .ReturnsAsync(true); - instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny())) .Returns(new ValueTask(OpenIddictConstants.ClientTypes.Public)); })); @@ -1261,14 +1132,6 @@ namespace OpenIddict.Server.Tests instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny())) .ReturnsAsync(application); - instance.Setup(mock => mock.HasPermissionAsync(application, - OpenIddictConstants.Permissions.Endpoints.Token, It.IsAny())) - .ReturnsAsync(true); - - instance.Setup(mock => mock.HasPermissionAsync(application, - OpenIddictConstants.Permissions.GrantTypes.RefreshToken, It.IsAny())) - .ReturnsAsync(true); - instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny())) .Returns(new ValueTask(OpenIddictConstants.ClientTypes.Public)); })); @@ -1372,14 +1235,6 @@ namespace OpenIddict.Server.Tests instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny())) .ReturnsAsync(application); - instance.Setup(mock => mock.HasPermissionAsync(application, - OpenIddictConstants.Permissions.Endpoints.Token, It.IsAny())) - .ReturnsAsync(true); - - instance.Setup(mock => mock.HasPermissionAsync(application, - OpenIddictConstants.Permissions.GrantTypes.AuthorizationCode, It.IsAny())) - .ReturnsAsync(true); - instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny())) .Returns(new ValueTask(OpenIddictConstants.ClientTypes.Public)); })); @@ -1475,14 +1330,6 @@ namespace OpenIddict.Server.Tests instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny())) .ReturnsAsync(application); - instance.Setup(mock => mock.HasPermissionAsync(application, - OpenIddictConstants.Permissions.Endpoints.Token, It.IsAny())) - .ReturnsAsync(true); - - instance.Setup(mock => mock.HasPermissionAsync(application, - OpenIddictConstants.Permissions.GrantTypes.RefreshToken, It.IsAny())) - .ReturnsAsync(true); - instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny())) .Returns(new ValueTask(OpenIddictConstants.ClientTypes.Public)); })); @@ -1564,14 +1411,6 @@ namespace OpenIddict.Server.Tests instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny())) .ReturnsAsync(application); - instance.Setup(mock => mock.HasPermissionAsync(application, - OpenIddictConstants.Permissions.Endpoints.Token, It.IsAny())) - .ReturnsAsync(true); - - instance.Setup(mock => mock.HasPermissionAsync(application, - OpenIddictConstants.Permissions.GrantTypes.AuthorizationCode, It.IsAny())) - .ReturnsAsync(true); - instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny())) .Returns(new ValueTask(OpenIddictConstants.ClientTypes.Public)); })); @@ -1644,14 +1483,6 @@ namespace OpenIddict.Server.Tests instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny())) .ReturnsAsync(application); - instance.Setup(mock => mock.HasPermissionAsync(application, - OpenIddictConstants.Permissions.Endpoints.Token, It.IsAny())) - .ReturnsAsync(true); - - instance.Setup(mock => mock.HasPermissionAsync(application, - OpenIddictConstants.Permissions.GrantTypes.RefreshToken, It.IsAny())) - .ReturnsAsync(true); - instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny())) .Returns(new ValueTask(OpenIddictConstants.ClientTypes.Public)); })); @@ -1711,14 +1542,6 @@ namespace OpenIddict.Server.Tests instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny())) .ReturnsAsync(application); - instance.Setup(mock => mock.HasPermissionAsync(application, - OpenIddictConstants.Permissions.Endpoints.Token, It.IsAny())) - .ReturnsAsync(true); - - instance.Setup(mock => mock.HasPermissionAsync(application, - OpenIddictConstants.Permissions.GrantTypes.AuthorizationCode, It.IsAny())) - .ReturnsAsync(true); - instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny())) .Returns(new ValueTask(OpenIddictConstants.ClientTypes.Public)); })); @@ -1802,14 +1625,6 @@ namespace OpenIddict.Server.Tests instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny())) .ReturnsAsync(application); - instance.Setup(mock => mock.HasPermissionAsync(application, - OpenIddictConstants.Permissions.Endpoints.Token, It.IsAny())) - .ReturnsAsync(true); - - instance.Setup(mock => mock.HasPermissionAsync(application, - OpenIddictConstants.Permissions.GrantTypes.AuthorizationCode, It.IsAny())) - .ReturnsAsync(true); - instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny())) .Returns(new ValueTask(OpenIddictConstants.ClientTypes.Public)); })); @@ -1891,14 +1706,6 @@ namespace OpenIddict.Server.Tests instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny())) .ReturnsAsync(application); - instance.Setup(mock => mock.HasPermissionAsync(application, - OpenIddictConstants.Permissions.Endpoints.Token, It.IsAny())) - .ReturnsAsync(true); - - instance.Setup(mock => mock.HasPermissionAsync(application, - OpenIddictConstants.Permissions.GrantTypes.AuthorizationCode, It.IsAny())) - .ReturnsAsync(true); - instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny())) .Returns(new ValueTask(OpenIddictConstants.ClientTypes.Public)); })); @@ -1984,14 +1791,6 @@ namespace OpenIddict.Server.Tests instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny())) .ReturnsAsync(application); - instance.Setup(mock => mock.HasPermissionAsync(application, - OpenIddictConstants.Permissions.Endpoints.Token, It.IsAny())) - .ReturnsAsync(true); - - instance.Setup(mock => mock.HasPermissionAsync(application, - OpenIddictConstants.Permissions.GrantTypes.AuthorizationCode, It.IsAny())) - .ReturnsAsync(true); - instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny())) .Returns(new ValueTask(OpenIddictConstants.ClientTypes.Public)); })); @@ -2073,14 +1872,6 @@ namespace OpenIddict.Server.Tests instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny())) .ReturnsAsync(application); - instance.Setup(mock => mock.HasPermissionAsync(application, - OpenIddictConstants.Permissions.Endpoints.Token, It.IsAny())) - .ReturnsAsync(true); - - instance.Setup(mock => mock.HasPermissionAsync(application, - OpenIddictConstants.Permissions.GrantTypes.RefreshToken, It.IsAny())) - .ReturnsAsync(true); - instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny())) .Returns(new ValueTask(OpenIddictConstants.ClientTypes.Public)); })); @@ -2164,14 +1955,6 @@ namespace OpenIddict.Server.Tests instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny())) .ReturnsAsync(application); - instance.Setup(mock => mock.HasPermissionAsync(application, - OpenIddictConstants.Permissions.Endpoints.Token, It.IsAny())) - .ReturnsAsync(true); - - instance.Setup(mock => mock.HasPermissionAsync(application, - OpenIddictConstants.Permissions.GrantTypes.RefreshToken, It.IsAny())) - .ReturnsAsync(true); - instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny())) .Returns(new ValueTask(OpenIddictConstants.ClientTypes.Public)); })); @@ -2280,30 +2063,6 @@ namespace OpenIddict.Server.Tests instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny())) .ReturnsAsync(application); - instance.Setup(mock => mock.HasPermissionAsync(application, - OpenIddictConstants.Permissions.Endpoints.Token, It.IsAny())) - .ReturnsAsync(true); - - instance.Setup(mock => mock.HasPermissionAsync(application, - OpenIddictConstants.Permissions.GrantTypes.AuthorizationCode, It.IsAny())) - .ReturnsAsync(true); - - instance.Setup(mock => mock.HasPermissionAsync(application, - OpenIddictConstants.Permissions.GrantTypes.ClientCredentials, It.IsAny())) - .ReturnsAsync(true); - - instance.Setup(mock => mock.HasPermissionAsync(application, - OpenIddictConstants.Permissions.GrantTypes.Password, It.IsAny())) - .ReturnsAsync(true); - - instance.Setup(mock => mock.HasPermissionAsync(application, - OpenIddictConstants.Permissions.GrantTypes.RefreshToken, It.IsAny())) - .ReturnsAsync(true); - - instance.Setup(mock => mock.HasPermissionAsync(application, - "gt:urn:ietf:params:oauth:grant-type:custom_grant", It.IsAny())) - .ReturnsAsync(true); - instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny())) .Returns(new ValueTask(OpenIddictConstants.ClientTypes.Confidential)); diff --git a/test/OpenIddict.Server.Tests/Internal/OpenIddictServerProviderTests.Introspection.cs b/test/OpenIddict.Server.Tests/Internal/OpenIddictServerProviderTests.Introspection.cs index 52b6663e..177928aa 100644 --- a/test/OpenIddict.Server.Tests/Internal/OpenIddictServerProviderTests.Introspection.cs +++ b/test/OpenIddict.Server.Tests/Internal/OpenIddictServerProviderTests.Introspection.cs @@ -94,6 +94,8 @@ namespace OpenIddict.Server.Tests var server = CreateAuthorizationServer(builder => { builder.Services.AddSingleton(manager); + + builder.Configure(options => options.IgnoreEndpointPermissions = false); }); var client = new OpenIdConnectClient(server.CreateClient()); @@ -126,10 +128,6 @@ namespace OpenIddict.Server.Tests instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny())) .ReturnsAsync(application); - instance.Setup(mock => mock.HasPermissionAsync(application, - OpenIddictConstants.Permissions.Endpoints.Introspection, It.IsAny())) - .ReturnsAsync(true); - instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny())) .Returns(new ValueTask(OpenIddictConstants.ClientTypes.Public)); }); @@ -154,8 +152,6 @@ namespace OpenIddict.Server.Tests Assert.Equal("This client application is not allowed to use the introspection endpoint.", response.ErrorDescription); Mock.Get(manager).Verify(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny()), Times.Once()); - Mock.Get(manager).Verify(mock => mock.HasPermissionAsync(application, - OpenIddictConstants.Permissions.Endpoints.Introspection, It.IsAny()), Times.Once()); Mock.Get(manager).Verify(mock => mock.GetClientTypeAsync(application, It.IsAny()), Times.Once()); } @@ -170,10 +166,6 @@ namespace OpenIddict.Server.Tests instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny())) .ReturnsAsync(application); - instance.Setup(mock => mock.HasPermissionAsync(application, - OpenIddictConstants.Permissions.Endpoints.Introspection, It.IsAny())) - .ReturnsAsync(true); - instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny())) .Returns(new ValueTask(OpenIddictConstants.ClientTypes.Confidential)); @@ -201,8 +193,6 @@ namespace OpenIddict.Server.Tests Assert.Equal("The specified client credentials are invalid.", response.ErrorDescription); Mock.Get(manager).Verify(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny()), Times.Once()); - Mock.Get(manager).Verify(mock => mock.HasPermissionAsync(application, - OpenIddictConstants.Permissions.Endpoints.Introspection, It.IsAny()), Times.Once()); Mock.Get(manager).Verify(mock => mock.GetClientTypeAsync(application, It.IsAny()), Times.Once()); Mock.Get(manager).Verify(mock => mock.ValidateClientSecretAsync(application, "7Fjfp0ZBr1KtDRbnfVdmIw", It.IsAny()), Times.Once()); } @@ -239,10 +229,6 @@ namespace OpenIddict.Server.Tests instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny())) .ReturnsAsync(application); - instance.Setup(mock => mock.HasPermissionAsync(application, - OpenIddictConstants.Permissions.Endpoints.Introspection, It.IsAny())) - .ReturnsAsync(true); - instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny())) .Returns(new ValueTask(OpenIddictConstants.ClientTypes.Confidential)); @@ -297,10 +283,6 @@ namespace OpenIddict.Server.Tests instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny())) .ReturnsAsync(application); - instance.Setup(mock => mock.HasPermissionAsync(application, - OpenIddictConstants.Permissions.Endpoints.Introspection, It.IsAny())) - .ReturnsAsync(true); - instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny())) .Returns(new ValueTask(OpenIddictConstants.ClientTypes.Confidential)); @@ -356,10 +338,6 @@ namespace OpenIddict.Server.Tests instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny())) .ReturnsAsync(application); - instance.Setup(mock => mock.HasPermissionAsync(application, - OpenIddictConstants.Permissions.Endpoints.Introspection, It.IsAny())) - .ReturnsAsync(true); - instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny())) .Returns(new ValueTask(OpenIddictConstants.ClientTypes.Confidential)); @@ -407,10 +385,6 @@ namespace OpenIddict.Server.Tests instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny())) .ReturnsAsync(application); - instance.Setup(mock => mock.HasPermissionAsync(application, - OpenIddictConstants.Permissions.Endpoints.Introspection, It.IsAny())) - .ReturnsAsync(true); - instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny())) .Returns(new ValueTask(OpenIddictConstants.ClientTypes.Confidential)); @@ -477,10 +451,6 @@ namespace OpenIddict.Server.Tests instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny())) .ReturnsAsync(application); - instance.Setup(mock => mock.HasPermissionAsync(application, - OpenIddictConstants.Permissions.Endpoints.Introspection, It.IsAny())) - .ReturnsAsync(true); - instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny())) .Returns(new ValueTask(OpenIddictConstants.ClientTypes.Confidential)); @@ -572,10 +542,6 @@ namespace OpenIddict.Server.Tests instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny())) .ReturnsAsync(application); - instance.Setup(mock => mock.HasPermissionAsync(application, - OpenIddictConstants.Permissions.Endpoints.Introspection, It.IsAny())) - .ReturnsAsync(true); - instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny())) .Returns(new ValueTask(OpenIddictConstants.ClientTypes.Confidential)); @@ -671,10 +637,6 @@ namespace OpenIddict.Server.Tests instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny())) .ReturnsAsync(application); - instance.Setup(mock => mock.HasPermissionAsync(application, - OpenIddictConstants.Permissions.Endpoints.Introspection, It.IsAny())) - .ReturnsAsync(true); - instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny())) .Returns(new ValueTask(OpenIddictConstants.ClientTypes.Confidential)); @@ -780,10 +742,6 @@ namespace OpenIddict.Server.Tests instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny())) .ReturnsAsync(application); - instance.Setup(mock => mock.HasPermissionAsync(application, - OpenIddictConstants.Permissions.Endpoints.Introspection, It.IsAny())) - .ReturnsAsync(true); - instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny())) .Returns(new ValueTask(OpenIddictConstants.ClientTypes.Confidential)); diff --git a/test/OpenIddict.Server.Tests/Internal/OpenIddictServerProviderTests.Revocation.cs b/test/OpenIddict.Server.Tests/Internal/OpenIddictServerProviderTests.Revocation.cs index 6ea51325..74c35fb7 100644 --- a/test/OpenIddict.Server.Tests/Internal/OpenIddictServerProviderTests.Revocation.cs +++ b/test/OpenIddict.Server.Tests/Internal/OpenIddictServerProviderTests.Revocation.cs @@ -119,6 +119,8 @@ namespace OpenIddict.Server.Tests var server = CreateAuthorizationServer(builder => { builder.Services.AddSingleton(manager); + + builder.Configure(options => options.IgnoreEndpointPermissions = false); }); var client = new OpenIdConnectClient(server.CreateClient()); @@ -152,10 +154,6 @@ namespace OpenIddict.Server.Tests instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny())) .ReturnsAsync(application); - instance.Setup(mock => mock.HasPermissionAsync(application, - OpenIddictConstants.Permissions.Endpoints.Revocation, It.IsAny())) - .ReturnsAsync(true); - instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny())) .Returns(new ValueTask(OpenIddictConstants.ClientTypes.Public)); }); @@ -181,8 +179,6 @@ namespace OpenIddict.Server.Tests Assert.Equal("The 'client_secret' parameter is not valid for this client application.", response.ErrorDescription); Mock.Get(manager).Verify(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny()), Times.Once()); - Mock.Get(manager).Verify(mock => mock.HasPermissionAsync(application, - OpenIddictConstants.Permissions.Endpoints.Revocation, It.IsAny()), Times.Once()); Mock.Get(manager).Verify(mock => mock.GetClientTypeAsync(application, It.IsAny()), Times.Once()); } @@ -197,10 +193,6 @@ namespace OpenIddict.Server.Tests instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny())) .ReturnsAsync(application); - instance.Setup(mock => mock.HasPermissionAsync(application, - OpenIddictConstants.Permissions.Endpoints.Revocation, It.IsAny())) - .ReturnsAsync(true); - instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny())) .Returns(new ValueTask(OpenIddictConstants.ClientTypes.Confidential)); }); @@ -226,8 +218,6 @@ namespace OpenIddict.Server.Tests Assert.Equal("The 'client_secret' parameter required for this client application is missing.", response.ErrorDescription); Mock.Get(manager).Verify(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny()), Times.Once()); - Mock.Get(manager).Verify(mock => mock.HasPermissionAsync(application, - OpenIddictConstants.Permissions.Endpoints.Revocation, It.IsAny()), Times.Once()); Mock.Get(manager).Verify(mock => mock.GetClientTypeAsync(application, It.IsAny()), Times.Once()); } @@ -242,10 +232,6 @@ namespace OpenIddict.Server.Tests instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny())) .ReturnsAsync(application); - instance.Setup(mock => mock.HasPermissionAsync(application, - OpenIddictConstants.Permissions.Endpoints.Revocation, It.IsAny())) - .ReturnsAsync(true); - instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny())) .Returns(new ValueTask(OpenIddictConstants.ClientTypes.Hybrid)); }); @@ -271,8 +257,6 @@ namespace OpenIddict.Server.Tests Assert.Equal("The 'client_secret' parameter required for this client application is missing.", response.ErrorDescription); Mock.Get(manager).Verify(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny()), Times.Once()); - Mock.Get(manager).Verify(mock => mock.HasPermissionAsync(application, - OpenIddictConstants.Permissions.Endpoints.Revocation, It.IsAny()), Times.Once()); Mock.Get(manager).Verify(mock => mock.GetClientTypeAsync(application, It.IsAny()), Times.Once()); } @@ -287,10 +271,6 @@ namespace OpenIddict.Server.Tests instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny())) .ReturnsAsync(application); - instance.Setup(mock => mock.HasPermissionAsync(application, - OpenIddictConstants.Permissions.Endpoints.Revocation, It.IsAny())) - .ReturnsAsync(true); - instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny())) .Returns(new ValueTask(OpenIddictConstants.ClientTypes.Confidential)); diff --git a/test/OpenIddict.Server.Tests/Internal/OpenIddictServerProviderTests.Serialization.cs b/test/OpenIddict.Server.Tests/Internal/OpenIddictServerProviderTests.Serialization.cs index 223bfa94..42350622 100644 --- a/test/OpenIddict.Server.Tests/Internal/OpenIddictServerProviderTests.Serialization.cs +++ b/test/OpenIddict.Server.Tests/Internal/OpenIddictServerProviderTests.Serialization.cs @@ -38,10 +38,6 @@ namespace OpenIddict.Server.Tests instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny())) .ReturnsAsync(application); - instance.Setup(mock => mock.HasPermissionAsync(application, - OpenIddictConstants.Permissions.Endpoints.Introspection, It.IsAny())) - .ReturnsAsync(true); - instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny())) .Returns(new ValueTask(OpenIddictConstants.ClientTypes.Confidential)); @@ -116,10 +112,6 @@ namespace OpenIddict.Server.Tests instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny())) .ReturnsAsync(application); - instance.Setup(mock => mock.HasPermissionAsync(application, - OpenIddictConstants.Permissions.Endpoints.Introspection, It.IsAny())) - .ReturnsAsync(true); - instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny())) .Returns(new ValueTask(OpenIddictConstants.ClientTypes.Confidential)); @@ -174,10 +166,6 @@ namespace OpenIddict.Server.Tests instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny())) .ReturnsAsync(application); - instance.Setup(mock => mock.HasPermissionAsync(application, - OpenIddictConstants.Permissions.Endpoints.Introspection, It.IsAny())) - .ReturnsAsync(true); - instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny())) .Returns(new ValueTask(OpenIddictConstants.ClientTypes.Confidential)); @@ -236,10 +224,6 @@ namespace OpenIddict.Server.Tests instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny())) .ReturnsAsync(application); - instance.Setup(mock => mock.HasPermissionAsync(application, - OpenIddictConstants.Permissions.Endpoints.Introspection, It.IsAny())) - .ReturnsAsync(true); - instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny())) .Returns(new ValueTask(OpenIddictConstants.ClientTypes.Confidential)); @@ -303,10 +287,6 @@ namespace OpenIddict.Server.Tests instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny())) .ReturnsAsync(application); - instance.Setup(mock => mock.HasPermissionAsync(application, - OpenIddictConstants.Permissions.Endpoints.Introspection, It.IsAny())) - .ReturnsAsync(true); - instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny())) .Returns(new ValueTask(OpenIddictConstants.ClientTypes.Confidential)); @@ -396,10 +376,6 @@ namespace OpenIddict.Server.Tests instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny())) .ReturnsAsync(application); - instance.Setup(mock => mock.HasPermissionAsync(application, - OpenIddictConstants.Permissions.Endpoints.Introspection, It.IsAny())) - .ReturnsAsync(true); - instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny())) .Returns(new ValueTask(OpenIddictConstants.ClientTypes.Confidential)); @@ -458,14 +434,6 @@ namespace OpenIddict.Server.Tests instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny())) .ReturnsAsync(application); - instance.Setup(mock => mock.HasPermissionAsync(application, - OpenIddictConstants.Permissions.Endpoints.Token, It.IsAny())) - .ReturnsAsync(true); - - instance.Setup(mock => mock.HasPermissionAsync(application, - OpenIddictConstants.Permissions.GrantTypes.AuthorizationCode, It.IsAny())) - .ReturnsAsync(true); - instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny())) .Returns(new ValueTask(OpenIddictConstants.ClientTypes.Confidential)); @@ -543,14 +511,6 @@ namespace OpenIddict.Server.Tests instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny())) .ReturnsAsync(application); - instance.Setup(mock => mock.HasPermissionAsync(application, - OpenIddictConstants.Permissions.Endpoints.Token, It.IsAny())) - .ReturnsAsync(true); - - instance.Setup(mock => mock.HasPermissionAsync(application, - OpenIddictConstants.Permissions.GrantTypes.AuthorizationCode, It.IsAny())) - .ReturnsAsync(true); - instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny())) .Returns(new ValueTask(OpenIddictConstants.ClientTypes.Confidential)); @@ -606,14 +566,6 @@ namespace OpenIddict.Server.Tests instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny())) .ReturnsAsync(application); - instance.Setup(mock => mock.HasPermissionAsync(application, - OpenIddictConstants.Permissions.Endpoints.Token, It.IsAny())) - .ReturnsAsync(true); - - instance.Setup(mock => mock.HasPermissionAsync(application, - OpenIddictConstants.Permissions.GrantTypes.AuthorizationCode, It.IsAny())) - .ReturnsAsync(true); - instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny())) .Returns(new ValueTask(OpenIddictConstants.ClientTypes.Confidential)); @@ -673,14 +625,6 @@ namespace OpenIddict.Server.Tests instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny())) .ReturnsAsync(application); - instance.Setup(mock => mock.HasPermissionAsync(application, - OpenIddictConstants.Permissions.Endpoints.Token, It.IsAny())) - .ReturnsAsync(true); - - instance.Setup(mock => mock.HasPermissionAsync(application, - OpenIddictConstants.Permissions.GrantTypes.AuthorizationCode, It.IsAny())) - .ReturnsAsync(true); - instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny())) .Returns(new ValueTask(OpenIddictConstants.ClientTypes.Confidential)); @@ -745,14 +689,6 @@ namespace OpenIddict.Server.Tests instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny())) .ReturnsAsync(application); - instance.Setup(mock => mock.HasPermissionAsync(application, - OpenIddictConstants.Permissions.Endpoints.Token, It.IsAny())) - .ReturnsAsync(true); - - instance.Setup(mock => mock.HasPermissionAsync(application, - OpenIddictConstants.Permissions.GrantTypes.AuthorizationCode, It.IsAny())) - .ReturnsAsync(true); - instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny())) .Returns(new ValueTask(OpenIddictConstants.ClientTypes.Confidential)); @@ -842,14 +778,6 @@ namespace OpenIddict.Server.Tests instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny())) .ReturnsAsync(application); - instance.Setup(mock => mock.HasPermissionAsync(application, - OpenIddictConstants.Permissions.Endpoints.Token, It.IsAny())) - .ReturnsAsync(true); - - instance.Setup(mock => mock.HasPermissionAsync(application, - OpenIddictConstants.Permissions.GrantTypes.AuthorizationCode, It.IsAny())) - .ReturnsAsync(true); - instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny())) .Returns(new ValueTask(OpenIddictConstants.ClientTypes.Confidential)); @@ -916,14 +844,6 @@ namespace OpenIddict.Server.Tests instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny())) .ReturnsAsync(application); - instance.Setup(mock => mock.HasPermissionAsync(application, - OpenIddictConstants.Permissions.Endpoints.Token, It.IsAny())) - .ReturnsAsync(true); - - instance.Setup(mock => mock.HasPermissionAsync(application, - OpenIddictConstants.Permissions.GrantTypes.AuthorizationCode, It.IsAny())) - .ReturnsAsync(true); - instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny())) .Returns(new ValueTask(OpenIddictConstants.ClientTypes.Confidential)); @@ -969,14 +889,6 @@ namespace OpenIddict.Server.Tests instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny())) .ReturnsAsync(application); - instance.Setup(mock => mock.HasPermissionAsync(application, - OpenIddictConstants.Permissions.Endpoints.Token, It.IsAny())) - .ReturnsAsync(true); - - instance.Setup(mock => mock.HasPermissionAsync(application, - OpenIddictConstants.Permissions.GrantTypes.AuthorizationCode, It.IsAny())) - .ReturnsAsync(true); - instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny())) .Returns(new ValueTask(OpenIddictConstants.ClientTypes.Confidential)); @@ -1055,14 +967,6 @@ namespace OpenIddict.Server.Tests instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny())) .ReturnsAsync(application); - instance.Setup(mock => mock.HasPermissionAsync(application, - OpenIddictConstants.Permissions.Endpoints.Token, It.IsAny())) - .ReturnsAsync(true); - - instance.Setup(mock => mock.HasPermissionAsync(application, - OpenIddictConstants.Permissions.GrantTypes.AuthorizationCode, It.IsAny())) - .ReturnsAsync(true); - instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny())) .Returns(new ValueTask(OpenIddictConstants.ClientTypes.Confidential)); @@ -1116,10 +1020,6 @@ namespace OpenIddict.Server.Tests instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny())) .ReturnsAsync(application); - instance.Setup(mock => mock.HasPermissionAsync(application, - OpenIddictConstants.Permissions.Endpoints.Introspection, It.IsAny())) - .ReturnsAsync(true); - instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny())) .Returns(new ValueTask(OpenIddictConstants.ClientTypes.Confidential)); @@ -1663,14 +1563,6 @@ namespace OpenIddict.Server.Tests instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny())) .ReturnsAsync(application); - instance.Setup(mock => mock.HasPermissionAsync(application, - OpenIddictConstants.Permissions.Endpoints.Token, It.IsAny())) - .ReturnsAsync(true); - - instance.Setup(mock => mock.HasPermissionAsync(application, - OpenIddictConstants.Permissions.GrantTypes.Password, It.IsAny())) - .ReturnsAsync(true); - instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny())) .Returns(new ValueTask(OpenIddictConstants.ClientTypes.Public)); @@ -1772,14 +1664,6 @@ namespace OpenIddict.Server.Tests instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny())) .ReturnsAsync(application); - instance.Setup(mock => mock.HasPermissionAsync(application, - OpenIddictConstants.Permissions.Endpoints.Authorization, It.IsAny())) - .ReturnsAsync(true); - - instance.Setup(mock => mock.HasPermissionAsync(application, - OpenIddictConstants.Permissions.GrantTypes.AuthorizationCode, It.IsAny())) - .ReturnsAsync(true); - instance.Setup(mock => mock.ValidateRedirectUriAsync(application, "http://www.fabrikam.com/path", It.IsAny())) .ReturnsAsync(true); @@ -1837,14 +1721,6 @@ namespace OpenIddict.Server.Tests instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny())) .ReturnsAsync(application); - instance.Setup(mock => mock.HasPermissionAsync(application, - OpenIddictConstants.Permissions.Endpoints.Authorization, It.IsAny())) - .ReturnsAsync(true); - - instance.Setup(mock => mock.HasPermissionAsync(application, - OpenIddictConstants.Permissions.GrantTypes.AuthorizationCode, It.IsAny())) - .ReturnsAsync(true); - instance.Setup(mock => mock.ValidateRedirectUriAsync(application, "http://www.fabrikam.com/path", It.IsAny())) .ReturnsAsync(true); @@ -1916,14 +1792,6 @@ namespace OpenIddict.Server.Tests instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny())) .ReturnsAsync(application); - instance.Setup(mock => mock.HasPermissionAsync(application, - OpenIddictConstants.Permissions.Endpoints.Authorization, It.IsAny())) - .ReturnsAsync(true); - - instance.Setup(mock => mock.HasPermissionAsync(application, - OpenIddictConstants.Permissions.GrantTypes.AuthorizationCode, It.IsAny())) - .ReturnsAsync(true); - instance.Setup(mock => mock.ValidateRedirectUriAsync(application, "http://www.fabrikam.com/path", It.IsAny())) .ReturnsAsync(true); @@ -1997,14 +1865,6 @@ namespace OpenIddict.Server.Tests instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny())) .ReturnsAsync(application); - instance.Setup(mock => mock.HasPermissionAsync(application, - OpenIddictConstants.Permissions.Endpoints.Authorization, It.IsAny())) - .ReturnsAsync(true); - - instance.Setup(mock => mock.HasPermissionAsync(application, - OpenIddictConstants.Permissions.GrantTypes.AuthorizationCode, It.IsAny())) - .ReturnsAsync(true); - instance.Setup(mock => mock.ValidateRedirectUriAsync(application, "http://www.fabrikam.com/path", It.IsAny())) .ReturnsAsync(true); @@ -2063,14 +1923,6 @@ namespace OpenIddict.Server.Tests instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny())) .ReturnsAsync(application); - instance.Setup(mock => mock.HasPermissionAsync(application, - OpenIddictConstants.Permissions.Endpoints.Authorization, It.IsAny())) - .ReturnsAsync(true); - - instance.Setup(mock => mock.HasPermissionAsync(application, - OpenIddictConstants.Permissions.GrantTypes.AuthorizationCode, It.IsAny())) - .ReturnsAsync(true); - instance.Setup(mock => mock.ValidateRedirectUriAsync(application, "http://www.fabrikam.com/path", It.IsAny())) .ReturnsAsync(true); @@ -2354,14 +2206,6 @@ namespace OpenIddict.Server.Tests instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny())) .ReturnsAsync(application); - instance.Setup(mock => mock.HasPermissionAsync(application, - OpenIddictConstants.Permissions.Endpoints.Token, It.IsAny())) - .ReturnsAsync(true); - - instance.Setup(mock => mock.HasPermissionAsync(application, - OpenIddictConstants.Permissions.GrantTypes.Password, It.IsAny())) - .ReturnsAsync(true); - instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny())) .Returns(new ValueTask(OpenIddictConstants.ClientTypes.Public)); diff --git a/test/OpenIddict.Server.Tests/Internal/OpenIddictServerProviderTests.Session.cs b/test/OpenIddict.Server.Tests/Internal/OpenIddictServerProviderTests.Session.cs index 9e72de31..340aaab7 100644 --- a/test/OpenIddict.Server.Tests/Internal/OpenIddictServerProviderTests.Session.cs +++ b/test/OpenIddict.Server.Tests/Internal/OpenIddictServerProviderTests.Session.cs @@ -4,6 +4,7 @@ * the license and the contributors participating to this project. */ +using System.Collections.Immutable; using System.Security.Cryptography; using System.Threading; using System.Threading.Tasks; @@ -91,8 +92,8 @@ namespace OpenIddict.Server.Tests // Arrange var manager = CreateApplicationManager(instance => { - instance.Setup(mock => mock.ValidatePostLogoutRedirectUriAsync("http://www.fabrikam.com/path", It.IsAny())) - .ReturnsAsync(false); + instance.Setup(mock => mock.FindByPostLogoutRedirectUriAsync("http://www.fabrikam.com/path", It.IsAny())) + .ReturnsAsync(ImmutableArray.Create()); }); var server = CreateAuthorizationServer(builder => @@ -112,7 +113,7 @@ namespace OpenIddict.Server.Tests Assert.Equal(OpenIdConnectConstants.Errors.InvalidRequest, response.Error); Assert.Equal("The specified 'post_logout_redirect_uri' parameter is not valid.", response.ErrorDescription); - Mock.Get(manager).Verify(mock => mock.ValidatePostLogoutRedirectUriAsync("http://www.fabrikam.com/path", It.IsAny()), Times.Once()); + Mock.Get(manager).Verify(mock => mock.FindByPostLogoutRedirectUriAsync("http://www.fabrikam.com/path", It.IsAny()), Times.Once()); } [Fact] @@ -126,8 +127,8 @@ namespace OpenIddict.Server.Tests { builder.Services.AddSingleton(CreateApplicationManager(instance => { - instance.Setup(mock => mock.ValidatePostLogoutRedirectUriAsync("http://www.fabrikam.com/path", It.IsAny())) - .ReturnsAsync(true); + instance.Setup(mock => mock.FindByPostLogoutRedirectUriAsync("http://www.fabrikam.com/path", It.IsAny())) + .ReturnsAsync(ImmutableArray.Create(new OpenIddictApplication())); })); builder.Services.AddSingleton(cache.Object); @@ -168,8 +169,8 @@ namespace OpenIddict.Server.Tests { builder.Services.AddSingleton(CreateApplicationManager(instance => { - instance.Setup(mock => mock.ValidatePostLogoutRedirectUriAsync("http://www.fabrikam.com/path", It.IsAny())) - .ReturnsAsync(true); + instance.Setup(mock => mock.FindByPostLogoutRedirectUriAsync("http://www.fabrikam.com/path", It.IsAny())) + .ReturnsAsync(ImmutableArray.Create(new OpenIddictApplication())); })); }); @@ -194,8 +195,8 @@ namespace OpenIddict.Server.Tests { builder.Services.AddSingleton(CreateApplicationManager(instance => { - instance.Setup(mock => mock.ValidatePostLogoutRedirectUriAsync("http://www.fabrikam.com/path", It.IsAny())) - .ReturnsAsync(false); + instance.Setup(mock => mock.FindByPostLogoutRedirectUriAsync("http://www.fabrikam.com/path", It.IsAny())) + .ReturnsAsync(ImmutableArray.Create(new OpenIddictApplication())); })); builder.EnableAuthorizationEndpoint("/logout-status-code-middleware"); diff --git a/test/OpenIddict.Server.Tests/Internal/OpenIddictServerProviderTests.cs b/test/OpenIddict.Server.Tests/Internal/OpenIddictServerProviderTests.cs index 07ed1970..4f734af8 100644 --- a/test/OpenIddict.Server.Tests/Internal/OpenIddictServerProviderTests.cs +++ b/test/OpenIddict.Server.Tests/Internal/OpenIddictServerProviderTests.cs @@ -57,14 +57,6 @@ namespace OpenIddict.Server.Tests instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny())) .ReturnsAsync(application); - instance.Setup(mock => mock.HasPermissionAsync(application, - OpenIddictConstants.Permissions.Endpoints.Authorization, It.IsAny())) - .ReturnsAsync(true); - - instance.Setup(mock => mock.HasPermissionAsync(application, - OpenIddictConstants.Permissions.GrantTypes.AuthorizationCode, It.IsAny())) - .ReturnsAsync(true); - instance.Setup(mock => mock.ValidateRedirectUriAsync(application, "http://www.fabrikam.com/path", It.IsAny())) .ReturnsAsync(true); @@ -241,14 +233,6 @@ namespace OpenIddict.Server.Tests instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny())) .ReturnsAsync(application); - instance.Setup(mock => mock.HasPermissionAsync(application, - OpenIddictConstants.Permissions.Endpoints.Token, It.IsAny())) - .ReturnsAsync(true); - - instance.Setup(mock => mock.HasPermissionAsync(application, - OpenIddictConstants.Permissions.GrantTypes.AuthorizationCode, It.IsAny())) - .ReturnsAsync(true); - instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny())) .Returns(new ValueTask(OpenIddictConstants.ClientTypes.Public)); })); @@ -440,14 +424,6 @@ namespace OpenIddict.Server.Tests instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny())) .ReturnsAsync(application); - instance.Setup(mock => mock.HasPermissionAsync(application, - OpenIddictConstants.Permissions.Endpoints.Token, It.IsAny())) - .ReturnsAsync(true); - - instance.Setup(mock => mock.HasPermissionAsync(application, - OpenIddictConstants.Permissions.GrantTypes.AuthorizationCode, It.IsAny())) - .ReturnsAsync(true); - instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny())) .Returns(new ValueTask(OpenIddictConstants.ClientTypes.Public)); })); @@ -520,14 +496,6 @@ namespace OpenIddict.Server.Tests instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny())) .ReturnsAsync(application); - instance.Setup(mock => mock.HasPermissionAsync(application, - OpenIddictConstants.Permissions.Endpoints.Token, It.IsAny())) - .ReturnsAsync(true); - - instance.Setup(mock => mock.HasPermissionAsync(application, - OpenIddictConstants.Permissions.GrantTypes.AuthorizationCode, It.IsAny())) - .ReturnsAsync(true); - instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny())) .Returns(new ValueTask(OpenIddictConstants.ClientTypes.Public)); })); @@ -1159,14 +1127,6 @@ namespace OpenIddict.Server.Tests instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny())) .ReturnsAsync(application); - instance.Setup(mock => mock.HasPermissionAsync(application, - OpenIddictConstants.Permissions.Endpoints.Authorization, It.IsAny())) - .ReturnsAsync(true); - - instance.Setup(mock => mock.HasPermissionAsync(application, - OpenIddictConstants.Permissions.GrantTypes.AuthorizationCode, It.IsAny())) - .ReturnsAsync(true); - instance.Setup(mock => mock.ValidateRedirectUriAsync(application, "http://www.fabrikam.com/path", It.IsAny())) .ReturnsAsync(true); @@ -1231,14 +1191,6 @@ namespace OpenIddict.Server.Tests instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny())) .ReturnsAsync(application); - instance.Setup(mock => mock.HasPermissionAsync(application, - OpenIddictConstants.Permissions.Endpoints.Authorization, It.IsAny())) - .ReturnsAsync(true); - - instance.Setup(mock => mock.HasPermissionAsync(application, - OpenIddictConstants.Permissions.GrantTypes.AuthorizationCode, It.IsAny())) - .ReturnsAsync(true); - instance.Setup(mock => mock.ValidateRedirectUriAsync(application, "http://www.fabrikam.com/path", It.IsAny())) .ReturnsAsync(true); @@ -1292,14 +1244,6 @@ namespace OpenIddict.Server.Tests instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny())) .ReturnsAsync(application); - instance.Setup(mock => mock.HasPermissionAsync(application, - OpenIddictConstants.Permissions.Endpoints.Authorization, It.IsAny())) - .ReturnsAsync(true); - - instance.Setup(mock => mock.HasPermissionAsync(application, - OpenIddictConstants.Permissions.GrantTypes.AuthorizationCode, It.IsAny())) - .ReturnsAsync(true); - instance.Setup(mock => mock.ValidateRedirectUriAsync(application, "http://www.fabrikam.com/path", It.IsAny())) .ReturnsAsync(true); @@ -1398,8 +1342,8 @@ namespace OpenIddict.Server.Tests { builder.Services.AddSingleton(CreateApplicationManager(instance => { - instance.Setup(mock => mock.ValidatePostLogoutRedirectUriAsync("http://www.fabrikam.com/path", It.IsAny())) - .ReturnsAsync(true); + instance.Setup(mock => mock.FindByPostLogoutRedirectUriAsync("http://www.fabrikam.com/path", It.IsAny())) + .ReturnsAsync(ImmutableArray.Create(new OpenIddictApplication())); })); }); @@ -1453,6 +1397,11 @@ namespace OpenIddict.Server.Tests // Accept anonymous clients by default. options.AcceptAnonymousClients(); + // Disable permission enforcement by default. + options.IgnoreEndpointPermissions() + .IgnoreGrantTypePermissions() + .IgnoreScopePermissions(); + // Disable the transport security requirement during testing. options.DisableHttpsRequirement();