diff --git a/samples/Mvc.Server/Startup.cs b/samples/Mvc.Server/Startup.cs index 4e28596e..8dff7db7 100644 --- a/samples/Mvc.Server/Startup.cs +++ b/samples/Mvc.Server/Startup.cs @@ -88,9 +88,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). @@ -98,10 +95,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(); @@ -110,6 +103,23 @@ 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(); + + // 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 services. @@ -217,7 +227,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 } }; @@ -244,7 +257,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 b2bb0639..ae3c77ca 100644 --- a/src/OpenIddict.Core/Managers/OpenIddictApplicationManager.cs +++ b/src/OpenIddict.Core/Managers/OpenIddictApplicationManager.cs @@ -594,107 +594,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); } /// @@ -1229,40 +1129,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. /// @@ -1461,9 +1327,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 564dc761..fe0597f5 100644 --- a/src/OpenIddict.Server/Internal/OpenIddictServerProvider.Authentication.cs +++ b/src/OpenIddict.Server/Internal/OpenIddictServerProvider.Authentication.cs @@ -187,7 +187,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); @@ -323,7 +323,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); @@ -335,62 +336,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; + } } @@ -407,26 +411,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 be35f09c..b1884b9d 100644 --- a/src/OpenIddict.Server/Internal/OpenIddictServerProvider.Exchange.cs +++ b/src/OpenIddict.Server/Internal/OpenIddictServerProvider.Exchange.cs @@ -83,7 +83,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); @@ -132,7 +132,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."); @@ -171,7 +171,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); @@ -184,7 +185,7 @@ 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 " + @@ -261,27 +262,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 9710540d..b5494654 100644 --- a/src/OpenIddict.Server/Internal/OpenIddictServerProvider.Introspection.cs +++ b/src/OpenIddict.Server/Internal/OpenIddictServerProvider.Introspection.cs @@ -20,6 +20,8 @@ namespace OpenIddict.Server { public override async Task ValidateIntrospectionRequest([NotNull] ValidateIntrospectionRequestContext context) { + var options = (OpenIddictServerOptions) context.Options; + var logger = GetLogger(context.HttpContext.RequestServices); var applicationManager = GetApplicationManager(context.HttpContext.RequestServices); @@ -55,7 +57,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 c90c4336..67d3d221 100644 --- a/src/OpenIddict.Server/Internal/OpenIddictServerProvider.Revocation.cs +++ b/src/OpenIddict.Server/Internal/OpenIddictServerProvider.Revocation.cs @@ -59,7 +59,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."); @@ -98,7 +98,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 ee428af1..21abdf41 100644 --- a/src/OpenIddict.Server/Internal/OpenIddictServerProvider.Session.cs +++ b/src/OpenIddict.Server/Internal/OpenIddictServerProvider.Session.cs @@ -86,6 +86,8 @@ namespace OpenIddict.Server public override async Task ValidateLogoutRequest([NotNull] ValidateLogoutRequestContext context) { + var options = (OpenIddictServerOptions) context.Options; + var logger = GetLogger(context.HttpContext.RequestServices); var applicationManager = GetApplicationManager(context.HttpContext.RequestServices); @@ -116,7 +118,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 3209c9fc..973f720f 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 a new ephemeral key used to sign the JWT tokens issued by OpenIddict: the key /// is discarded when the application shuts down and tokens signed using this key are @@ -423,12 +431,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. @@ -460,6 +468,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. @@ -520,16 +552,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 ab5f5127..dc596aa4 100644 --- a/src/OpenIddict.Server/OpenIddictServerOptions.cs +++ b/src/OpenIddict.Server/OpenIddictServerOptions.cs @@ -26,6 +26,13 @@ namespace OpenIddict.Server Provider = new 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. @@ -75,9 +82,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. @@ -85,16 +92,30 @@ namespace OpenIddict.Server public ISet GrantTypes { get; } = new HashSet(StringComparer.Ordinal); /// - /// Gets or sets the random number generator used to generate crypto-secure identifiers. + /// 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 RandomNumberGenerator RandomNumberGenerator { get; set; } = RandomNumberGenerator.Create(); + public bool IgnoreEndpointPermissions { get; set; } /// - /// 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. + /// 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 RequireClientIdentification { get; set; } + 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. + /// + public RandomNumberGenerator RandomNumberGenerator { get; set; } = RandomNumberGenerator.Create(); /// /// 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 25725861..962111e9 100644 --- a/test/OpenIddict.Server.Tests/Internal/OpenIddictServerProviderTests.Authentication.cs +++ b/test/OpenIddict.Server.Tests/Internal/OpenIddictServerProviderTests.Authentication.cs @@ -206,8 +206,6 @@ namespace OpenIddict.Server.Tests It.IsAny())) .ReturnsAsync(ImmutableArray.Create()); })); - - builder.EnableScopeValidation(); }); var client = new OpenIdConnectClient(server.CreateClient()); @@ -244,21 +242,8 @@ 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.EnableScopeValidation(); builder.RegisterScopes("registered_scope"); }); @@ -312,27 +297,10 @@ 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"); - builder.EnableScopeValidation(); builder.Services.AddSingleton(manager); }); @@ -591,6 +559,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()); @@ -652,10 +622,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())) @@ -666,6 +632,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()); @@ -685,8 +653,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()); } @@ -701,14 +667,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); }); @@ -733,10 +691,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()); } @@ -751,18 +705,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); @@ -781,6 +723,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()); @@ -828,14 +771,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); @@ -894,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); @@ -981,14 +904,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 be93e915..6b9b2418 100644 --- a/test/OpenIddict.Server.Tests/Internal/OpenIddictServerProviderTests.Exchange.cs +++ b/test/OpenIddict.Server.Tests/Internal/OpenIddictServerProviderTests.Exchange.cs @@ -83,10 +83,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()); @@ -117,8 +114,6 @@ namespace OpenIddict.Server.Tests It.IsAny())) .ReturnsAsync(ImmutableArray.Create()); })); - - builder.EnableScopeValidation(); }); var client = new OpenIdConnectClient(server.CreateClient()); @@ -143,7 +138,6 @@ namespace OpenIddict.Server.Tests // Arrange var server = CreateAuthorizationServer(builder => { - builder.EnableScopeValidation(); builder.RegisterScopes("registered_scope"); }); @@ -184,7 +178,6 @@ namespace OpenIddict.Server.Tests var server = CreateAuthorizationServer(builder => { - builder.EnableScopeValidation(); builder.RegisterScopes("scope_registered_in_options"); builder.Services.AddSingleton(manager); @@ -256,7 +249,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()); @@ -326,6 +322,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()); @@ -359,10 +357,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); @@ -371,6 +365,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()); @@ -389,8 +385,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()); } @@ -406,14 +400,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)); }); @@ -438,10 +424,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()); } @@ -456,14 +438,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)); }); @@ -490,10 +464,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()); } @@ -508,14 +478,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)); }); @@ -542,10 +504,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()); } @@ -560,14 +518,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)); }); @@ -594,10 +544,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()); } @@ -612,14 +558,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)); @@ -649,10 +587,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()); } @@ -668,18 +602,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)); @@ -704,6 +626,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()); @@ -764,14 +687,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)); })); @@ -824,14 +739,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)); })); @@ -889,14 +796,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)); })); @@ -956,14 +855,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)); })); @@ -1030,14 +921,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)); })); @@ -1106,14 +989,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)); })); @@ -1176,14 +1051,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)); })); @@ -1267,14 +1134,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)); })); @@ -1378,14 +1237,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)); })); @@ -1481,14 +1332,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)); })); @@ -1570,14 +1413,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)); })); @@ -1650,14 +1485,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)); })); @@ -1717,14 +1544,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)); })); @@ -1808,14 +1627,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)); })); @@ -1897,14 +1708,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)); })); @@ -1990,14 +1793,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)); })); @@ -2079,14 +1874,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)); })); @@ -2170,14 +1957,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)); })); @@ -2286,30 +2065,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 38e1408d..dc9ca02a 100644 --- a/test/OpenIddict.Server.Tests/Internal/OpenIddictServerProviderTests.Introspection.cs +++ b/test/OpenIddict.Server.Tests/Internal/OpenIddictServerProviderTests.Introspection.cs @@ -95,6 +95,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()); @@ -127,10 +129,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)); }); @@ -155,8 +153,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()); } @@ -171,10 +167,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)); @@ -202,8 +194,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()); } @@ -240,10 +230,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)); @@ -298,10 +284,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)); @@ -357,10 +339,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)); @@ -408,10 +386,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)); @@ -478,10 +452,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)); @@ -573,10 +543,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)); @@ -672,10 +638,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)); @@ -781,10 +743,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 680e4ee9..522ea37d 100644 --- a/test/OpenIddict.Server.Tests/Internal/OpenIddictServerProviderTests.Revocation.cs +++ b/test/OpenIddict.Server.Tests/Internal/OpenIddictServerProviderTests.Revocation.cs @@ -51,7 +51,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()); @@ -118,6 +121,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()); @@ -151,10 +156,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)); }); @@ -180,8 +181,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()); } @@ -196,10 +195,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)); }); @@ -225,8 +220,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()); } @@ -241,10 +234,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)); }); @@ -270,8 +259,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()); } @@ -286,10 +273,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 96ec8490..81111232 100644 --- a/test/OpenIddict.Server.Tests/Internal/OpenIddictServerProviderTests.Serialization.cs +++ b/test/OpenIddict.Server.Tests/Internal/OpenIddictServerProviderTests.Serialization.cs @@ -40,10 +40,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)); @@ -118,10 +114,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)); @@ -176,10 +168,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)); @@ -238,10 +226,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)); @@ -305,10 +289,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)); @@ -398,10 +378,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)); @@ -460,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.AuthorizationCode, It.IsAny())) - .ReturnsAsync(true); - instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny())) .Returns(new ValueTask(OpenIddictConstants.ClientTypes.Confidential)); @@ -545,14 +513,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)); @@ -608,14 +568,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)); @@ -675,14 +627,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)); @@ -747,14 +691,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)); @@ -844,14 +780,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)); @@ -918,14 +846,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)); @@ -971,14 +891,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)); @@ -1057,14 +969,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)); @@ -1118,10 +1022,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)); @@ -1665,14 +1565,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)); @@ -1774,14 +1666,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); @@ -1839,14 +1723,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); @@ -1918,14 +1794,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); @@ -1999,14 +1867,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); @@ -2065,14 +1925,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); @@ -2356,14 +2208,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 f5fe7920..d506cf46 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; @@ -92,8 +93,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 => @@ -113,7 +114,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] @@ -127,8 +128,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 88bef8a0..b4f1b12c 100644 --- a/test/OpenIddict.Server.Tests/Internal/OpenIddictServerProviderTests.cs +++ b/test/OpenIddict.Server.Tests/Internal/OpenIddictServerProviderTests.cs @@ -58,14 +58,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); @@ -242,14 +234,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)); })); @@ -441,14 +425,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)); })); @@ -521,14 +497,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)); })); @@ -1160,14 +1128,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); @@ -1232,14 +1192,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); @@ -1293,14 +1245,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); @@ -1399,8 +1343,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())); })); }); @@ -1451,6 +1395,14 @@ namespace OpenIddict.Server.Tests .AddServer(options => { + // 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(); diff --git a/test/OpenIddict.Server.Tests/OpenIddictServerBuilderTests.cs b/test/OpenIddict.Server.Tests/OpenIddictServerBuilderTests.cs index a82c2e14..9b30edf4 100644 --- a/test/OpenIddict.Server.Tests/OpenIddictServerBuilderTests.cs +++ b/test/OpenIddict.Server.Tests/OpenIddictServerBuilderTests.cs @@ -422,7 +422,7 @@ namespace OpenIddict.Server.Tests } [Fact] - public void EnableScopeValidation_ScopeValidationIsDisabled() + public void DisableScopeValidation_ScopeValidationIsDisabled() { // Arrange var services = new ServiceCollection(); @@ -431,12 +431,12 @@ namespace OpenIddict.Server.Tests var builder = CreateBuilder(services); // Act - builder.EnableScopeValidation(); + builder.DisableScopeValidation(); var options = GetOptions(services); // Assert - Assert.True(options.EnableScopeValidation); + Assert.True(options.DisableScopeValidation); } [Fact] @@ -476,7 +476,7 @@ namespace OpenIddict.Server.Tests } [Fact] - public void RequireClientIdentification_ClientIdentificationIsEnforced() + public void AcceptAnonymousClients_ClientIdentificationIsOptional() { // Arrange var services = new ServiceCollection(); @@ -485,12 +485,12 @@ namespace OpenIddict.Server.Tests var builder = CreateBuilder(services); // Act - builder.RequireClientIdentification(); + builder.AcceptAnonymousClients(); var options = GetOptions(services); // Assert - Assert.True(options.RequireClientIdentification); + Assert.True(options.AcceptAnonymousClients); } [Fact]