Browse Source

Backport application provider support to OpenIddict 1.x

pull/670/head
Kévin Chalet 8 years ago
parent
commit
88e5b7a5e5
  1. 10
      src/OpenIddict.Server/Internal/OpenIddictServerProvider.Authentication.cs
  2. 2
      src/OpenIddict.Server/Internal/OpenIddictServerProvider.Discovery.cs
  3. 6
      src/OpenIddict.Server/Internal/OpenIddictServerProvider.Exchange.cs
  4. 21
      src/OpenIddict.Server/Internal/OpenIddictServerProvider.Introspection.cs
  5. 4
      src/OpenIddict.Server/Internal/OpenIddictServerProvider.Revocation.cs
  6. 12
      src/OpenIddict.Server/Internal/OpenIddictServerProvider.Serialization.cs
  7. 10
      src/OpenIddict.Server/Internal/OpenIddictServerProvider.Session.cs
  8. 2
      src/OpenIddict.Server/Internal/OpenIddictServerProvider.Userinfo.cs
  9. 62
      src/OpenIddict.Server/Internal/OpenIddictServerProvider.cs
  10. 19
      src/OpenIddict.Server/OpenIddictServerBuilder.cs
  11. 12
      src/OpenIddict.Server/OpenIddictServerExtensions.cs
  12. 6
      src/OpenIddict.Server/OpenIddictServerOptions.cs
  13. 2
      src/OpenIddict.Stores/OpenIddict.Stores.csproj
  14. 1
      test/OpenIddict.Server.Tests/Internal/OpenIddictServerProviderTests.Authentication.cs
  15. 2
      test/OpenIddict.Server.Tests/Internal/OpenIddictServerProviderTests.Exchange.cs
  16. 23
      test/OpenIddict.Server.Tests/Internal/OpenIddictServerProviderTests.Introspection.cs
  17. 2
      test/OpenIddict.Server.Tests/Internal/OpenIddictServerProviderTests.Revocation.cs
  18. 2
      test/OpenIddict.Server.Tests/Internal/OpenIddictServerProviderTests.Serialization.cs
  19. 1
      test/OpenIddict.Server.Tests/Internal/OpenIddictServerProviderTests.Session.cs
  20. 1
      test/OpenIddict.Server.Tests/Internal/OpenIddictServerProviderTests.cs

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

@ -107,6 +107,8 @@ namespace OpenIddict.Server
}
}
}
await base.ExtractAuthorizationRequest(context);
}
public override async Task ValidateAuthorizationRequest([NotNull] ValidateAuthorizationRequestContext context)
@ -416,6 +418,8 @@ namespace OpenIddict.Server
}
context.Validate();
await base.ValidateAuthorizationRequest(context);
}
public override async Task HandleAuthorizationRequest([NotNull] HandleAuthorizationRequestContext context)
@ -467,7 +471,7 @@ namespace OpenIddict.Server
return;
}
context.SkipToNextMiddleware();
await base.HandleAuthorizationRequest(context);
}
public override async Task ApplyAuthorizationResponse([NotNull] ApplyAuthorizationResponseContext context)
@ -503,8 +507,12 @@ namespace OpenIddict.Server
// from displaying the default error page and to allow the status code pages middleware
// to rewrite the response using the logic defined by the developer when registering it.
context.HandleResponse();
return;
}
}
await base.ApplyAuthorizationResponse(context);
}
}
}

2
src/OpenIddict.Server/Internal/OpenIddictServerProvider.Discovery.cs

@ -52,7 +52,7 @@ namespace OpenIddict.Server
where !string.IsNullOrEmpty(provider.DisplayName)
select provider.AuthenticationScheme);
return Task.FromResult(0);
return base.HandleConfigurationRequest(context);
}
}
}

6
src/OpenIddict.Server/Internal/OpenIddictServerProvider.Exchange.cs

@ -273,6 +273,8 @@ namespace OpenIddict.Server
}
context.Validate();
await base.ValidateTokenRequest(context);
}
public override async Task HandleTokenRequest([NotNull] HandleTokenRequestContext context)
@ -295,6 +297,8 @@ namespace OpenIddict.Server
// the user code to handle the token request.
context.SkipToNextMiddleware();
await base.HandleTokenRequest(context);
return;
}
@ -350,6 +354,8 @@ namespace OpenIddict.Server
// Invoke the rest of the pipeline to allow
// the user code to handle the token request.
context.SkipToNextMiddleware();
await base.HandleTokenRequest(context);
}
}
}

21
src/OpenIddict.Server/Internal/OpenIddictServerProvider.Introspection.cs

@ -4,7 +4,6 @@
* the license and the contributors participating to this project.
*/
using System;
using System.Diagnostics;
using System.Threading.Tasks;
using AspNet.Security.OpenIdConnect.Extensions;
@ -19,22 +18,6 @@ namespace OpenIddict.Server
{
public partial class OpenIddictServerProvider : OpenIdConnectServerProvider
{
public override Task ExtractIntrospectionRequest([NotNull] ExtractIntrospectionRequestContext context)
{
// Note: the OpenID Connect server middleware supports both GET and POST
// introspection requests but OpenIddict only accepts POST requests.
if (!string.Equals(context.HttpContext.Request.Method, "POST", StringComparison.OrdinalIgnoreCase))
{
context.Reject(
error: OpenIdConnectConstants.Errors.InvalidRequest,
description: "The specified HTTP method is not valid.");
return Task.FromResult(0);
}
return Task.FromResult(0);
}
public override async Task ValidateIntrospectionRequest([NotNull] ValidateIntrospectionRequestContext context)
{
var logger = context.HttpContext.RequestServices.GetRequiredService<ILogger<OpenIddictServerProvider>>();
@ -111,6 +94,8 @@ namespace OpenIddict.Server
}
context.Validate();
await base.ValidateIntrospectionRequest(context);
}
public override async Task HandleIntrospectionRequest([NotNull] HandleIntrospectionRequestContext context)
@ -179,6 +164,8 @@ namespace OpenIddict.Server
return;
}
await base.HandleIntrospectionRequest(context);
}
}
}

4
src/OpenIddict.Server/Internal/OpenIddictServerProvider.Revocation.cs

@ -162,6 +162,8 @@ namespace OpenIddict.Server
}
context.Validate();
await base.ValidateRevocationRequest(context);
}
public override async Task HandleRevocationRequest([NotNull] HandleRevocationRequestContext context)
@ -235,6 +237,8 @@ namespace OpenIddict.Server
logger.LogInformation("The token '{Identifier}' was successfully revoked.", identifier);
context.Revoked = true;
await base.HandleRevocationRequest(context);
}
}
}

12
src/OpenIddict.Server/Internal/OpenIddictServerProvider.Serialization.cs

@ -33,6 +33,8 @@ namespace OpenIddict.Server
{
context.HandleResponse();
}
await base.DeserializeAccessToken(context);
}
public override async Task DeserializeAuthorizationCode([NotNull] DeserializeAuthorizationCodeContext context)
@ -50,6 +52,8 @@ namespace OpenIddict.Server
// Prevent the OpenID Connect server middleware from using its default logic.
context.HandleResponse();
await base.DeserializeAuthorizationCode(context);
}
public override async Task DeserializeRefreshToken([NotNull] DeserializeRefreshTokenContext context)
@ -67,6 +71,8 @@ namespace OpenIddict.Server
// Prevent the OpenID Connect server middleware from using its default logic.
context.HandleResponse();
await base.DeserializeRefreshToken(context);
}
public override async Task SerializeAccessToken([NotNull] SerializeAccessTokenContext context)
@ -92,6 +98,8 @@ namespace OpenIddict.Server
// Otherwise, let the OpenID Connect server middleware
// serialize the token using its default internal logic.
await base.SerializeAccessToken(context);
}
public override async Task SerializeAuthorizationCode([NotNull] SerializeAuthorizationCodeContext context)
@ -119,6 +127,8 @@ namespace OpenIddict.Server
// Otherwise, let the OpenID Connect server middleware
// serialize the token using its default internal logic.
await base.SerializeAuthorizationCode(context);
}
public override async Task SerializeRefreshToken([NotNull] SerializeRefreshTokenContext context)
@ -146,6 +156,8 @@ namespace OpenIddict.Server
// Otherwise, let the OpenID Connect server middleware
// serialize the token using its default internal logic.
await base.SerializeRefreshToken(context);
}
}
}

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

@ -80,6 +80,8 @@ namespace OpenIddict.Server
}
}
}
await base.ExtractLogoutRequest(context);
}
public override async Task ValidateLogoutRequest([NotNull] ValidateLogoutRequestContext context)
@ -128,6 +130,8 @@ namespace OpenIddict.Server
}
context.Validate();
await base.ValidateLogoutRequest(context);
}
public override async Task HandleLogoutRequest([NotNull] HandleLogoutRequestContext context)
@ -178,6 +182,8 @@ namespace OpenIddict.Server
return;
}
await base.HandleLogoutRequest(context);
}
public override async Task ApplyLogoutResponse([NotNull] ApplyLogoutResponseContext context)
@ -213,8 +219,12 @@ namespace OpenIddict.Server
// from displaying the default error page and to allow the status code pages middleware
// to rewrite the response using the logic defined by the developer when registering it.
context.HandleResponse();
return;
}
}
await base.ApplyLogoutResponse(context);
}
}
}

2
src/OpenIddict.Server/Internal/OpenIddictServerProvider.Userinfo.cs

@ -24,7 +24,7 @@ namespace OpenIddict.Server
// the user code to handle the userinfo request.
context.SkipToNextMiddleware();
return Task.FromResult(0);
return base.ExtractUserinfoRequest(context);
}
}
}

62
src/OpenIddict.Server/Internal/OpenIddictServerProvider.cs

@ -34,7 +34,7 @@ namespace OpenIddict.Server
context.Response.AddParameter(parameter.Item2, parameter.Item3);
}
return Task.FromResult(0);
return base.ProcessChallengeResponse(context);
}
public override async Task ProcessSigninResponse([NotNull] ProcessSigninResponseContext context)
@ -97,6 +97,8 @@ namespace OpenIddict.Server
// none of the following security routines apply.
if (options.DisableTokenRevocation)
{
await base.ProcessSigninResponse(context);
return;
}
@ -165,6 +167,8 @@ namespace OpenIddict.Server
context.Response.AddParameter(parameter.Item2, parameter.Item3);
context.Ticket.RemoveProperty(parameter.Item1);
}
await base.ProcessSigninResponse(context);
}
public override Task ProcessSignoutResponse([NotNull] ProcessSignoutResponseContext context)
@ -178,7 +182,61 @@ namespace OpenIddict.Server
context.Response.AddParameter(parameter.Item2, parameter.Item3);
}
return Task.FromResult(0);
return base.ProcessSignoutResponse(context);
}
public void Import([NotNull] OpenIdConnectServerProvider provider)
{
OnMatchEndpoint = provider.MatchEndpoint;
OnExtractAuthorizationRequest = provider.ExtractAuthorizationRequest;
OnExtractConfigurationRequest = provider.ExtractConfigurationRequest;
OnExtractCryptographyRequest = provider.ExtractCryptographyRequest;
OnExtractIntrospectionRequest = provider.ExtractIntrospectionRequest;
OnExtractLogoutRequest = provider.ExtractLogoutRequest;
OnExtractRevocationRequest = provider.ExtractRevocationRequest;
OnExtractTokenRequest = provider.ExtractTokenRequest;
OnExtractUserinfoRequest = provider.ExtractUserinfoRequest;
OnValidateAuthorizationRequest = provider.ValidateAuthorizationRequest;
OnValidateConfigurationRequest = provider.ValidateConfigurationRequest;
OnValidateCryptographyRequest = provider.ValidateCryptographyRequest;
OnValidateIntrospectionRequest = provider.ValidateIntrospectionRequest;
OnValidateLogoutRequest = provider.ValidateLogoutRequest;
OnValidateRevocationRequest = provider.ValidateRevocationRequest;
OnValidateTokenRequest = provider.ValidateTokenRequest;
OnValidateUserinfoRequest = provider.ValidateUserinfoRequest;
OnHandleAuthorizationRequest = provider.HandleAuthorizationRequest;
OnHandleConfigurationRequest = provider.HandleConfigurationRequest;
OnHandleCryptographyRequest = provider.HandleCryptographyRequest;
OnHandleIntrospectionRequest = provider.HandleIntrospectionRequest;
OnHandleLogoutRequest = provider.HandleLogoutRequest;
OnHandleRevocationRequest = provider.HandleRevocationRequest;
OnHandleTokenRequest = provider.HandleTokenRequest;
OnHandleUserinfoRequest = provider.HandleUserinfoRequest;
OnApplyAuthorizationResponse = provider.ApplyAuthorizationResponse;
OnApplyConfigurationResponse = provider.ApplyConfigurationResponse;
OnApplyCryptographyResponse = provider.ApplyCryptographyResponse;
OnApplyIntrospectionResponse = provider.ApplyIntrospectionResponse;
OnApplyLogoutResponse = provider.ApplyLogoutResponse;
OnApplyRevocationResponse = provider.ApplyRevocationResponse;
OnApplyTokenResponse = provider.ApplyTokenResponse;
OnApplyUserinfoResponse = provider.ApplyUserinfoResponse;
OnProcessChallengeResponse = provider.ProcessChallengeResponse;
OnProcessSigninResponse = provider.ProcessSigninResponse;
OnProcessSignoutResponse = provider.ProcessSignoutResponse;
OnDeserializeAccessToken = provider.DeserializeAccessToken;
OnDeserializeAuthorizationCode = provider.DeserializeAuthorizationCode;
OnDeserializeIdentityToken = provider.DeserializeIdentityToken;
OnDeserializeRefreshToken = provider.DeserializeRefreshToken;
OnSerializeAccessToken = provider.SerializeAccessToken;
OnSerializeAuthorizationCode = provider.SerializeAuthorizationCode;
OnSerializeIdentityToken = provider.SerializeIdentityToken;
OnSerializeRefreshToken = provider.SerializeRefreshToken;
}
}
}

19
src/OpenIddict.Server/OpenIddictServerBuilder.cs

@ -13,6 +13,7 @@ using System.Linq;
using System.Reflection;
using System.Security.Cryptography.X509Certificates;
using AspNet.Security.OpenIdConnect.Primitives;
using AspNet.Security.OpenIdConnect.Server;
using JetBrains.Annotations;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.DataProtection;
@ -537,6 +538,24 @@ namespace Microsoft.Extensions.DependencyInjection
return Configure(options => options.Claims.UnionWith(claims));
}
/// <summary>
/// Registers an application-specific OpenID Connect server provider whose events
/// are automatically invoked for each request handled by the OpenIddict server handler.
/// Using this method is NOT recommended if you're not familiar with the OIDC events model.
/// </summary>
/// <param name="provider">The custom <see cref="OpenIdConnectServerProvider"/> service.</param>
/// <returns>The <see cref="OpenIddictServerBuilder"/>.</returns>
[EditorBrowsable(EditorBrowsableState.Advanced)]
public OpenIddictServerBuilder RegisterProvider([NotNull] OpenIdConnectServerProvider provider)
{
if (provider == null)
{
throw new ArgumentNullException(nameof(provider));
}
return Configure(options => options.ApplicationProvider = provider);
}
/// <summary>
/// Registers the specified scopes as supported scopes so
/// they can be returned as part of the discovery document.

12
src/OpenIddict.Server/OpenIddictServerExtensions.cs

@ -198,6 +198,18 @@ namespace Microsoft.Extensions.DependencyInjection
options.Scopes.Add(OpenIdConnectConstants.Scopes.OfflineAccess);
}
// If an application provider was registered, import the events into the main provider.
if (options.ApplicationProvider != null)
{
var provider = options.Provider as OpenIddictServerProvider;
if (provider == null)
{
throw new InvalidOperationException("The specified OpenID Connect server provider is not compatible.");
}
provider.Import(options.ApplicationProvider);
}
return app.UseOpenIdConnectServer(options);
}
}

6
src/OpenIddict.Server/OpenIddictServerOptions.cs

@ -26,6 +26,12 @@ namespace OpenIddict.Server
Provider = new OpenIddictServerProvider();
}
/// <summary>
/// Gets or sets the user-provided <see cref="OpenIdConnectServerProvider"/> that the OpenIddict server
/// invokes to enable developer control over the entire authentication/authorization process.
/// </summary>
public OpenIdConnectServerProvider ApplicationProvider { get; set; }
/// <summary>
/// Gets or sets the distributed cache used by OpenIddict. If no cache is explicitly
/// provided, the cache registered in the dependency injection container is used.

2
src/OpenIddict.Stores/OpenIddict.Stores.csproj

@ -19,7 +19,7 @@
<ItemGroup>
<PackageReference Include="JetBrains.Annotations" Version="$(JetBrainsVersion)" PrivateAssets="All" />
<PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="$(AspNetCoreVersion)" />
<PackageReference Include="Microsoft.Extensions.Caching.Abstractions" Version="$(AspNetCoreVersion)" />
</ItemGroup>
<ItemGroup Condition=" '$(TargetFramework)' == 'netstandard1.3' ">

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

@ -17,7 +17,6 @@ using Moq;
using Newtonsoft.Json;
using Newtonsoft.Json.Bson;
using OpenIddict.Abstractions;
using OpenIddict.Core;
using OpenIddict.Models;
using Xunit;

2
test/OpenIddict.Server.Tests/Internal/OpenIddictServerProviderTests.Exchange.cs

@ -11,7 +11,6 @@ using System.Threading.Tasks;
using AspNet.Security.OpenIdConnect.Client;
using AspNet.Security.OpenIdConnect.Extensions;
using AspNet.Security.OpenIdConnect.Primitives;
using AspNet.Security.OpenIdConnect.Server;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
@ -19,7 +18,6 @@ using Microsoft.AspNetCore.Http.Authentication;
using Microsoft.Extensions.DependencyInjection;
using Moq;
using OpenIddict.Abstractions;
using OpenIddict.Core;
using OpenIddict.Models;
using Xunit;

23
test/OpenIddict.Server.Tests/Internal/OpenIddictServerProviderTests.Introspection.cs

@ -10,15 +10,11 @@ using System.Threading.Tasks;
using AspNet.Security.OpenIdConnect.Client;
using AspNet.Security.OpenIdConnect.Extensions;
using AspNet.Security.OpenIdConnect.Primitives;
using AspNet.Security.OpenIdConnect.Server;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Http.Authentication;
using Microsoft.Extensions.DependencyInjection;
using Moq;
using OpenIddict.Abstractions;
using OpenIddict.Core;
using OpenIddict.Models;
using Xunit;
@ -26,25 +22,6 @@ namespace OpenIddict.Server.Tests
{
public partial class OpenIddictServerProviderTests
{
[Fact]
public async Task ExtractIntrospectionRequest_GetRequestsAreRejected()
{
// Arrange
var server = CreateAuthorizationServer();
var client = new OpenIdConnectClient(server.CreateClient());
// Act
var response = await client.GetAsync(IntrospectionEndpoint, new OpenIdConnectRequest
{
Token = "2YotnFZFEjr1zCsicMWpAA"
});
// Assert
Assert.Equal(OpenIdConnectConstants.Errors.InvalidRequest, response.Error);
Assert.Equal("The specified HTTP method is not valid.", response.ErrorDescription);
}
[Theory]
[InlineData("client_id", "")]
[InlineData("", "client_secret")]

2
test/OpenIddict.Server.Tests/Internal/OpenIddictServerProviderTests.Revocation.cs

@ -12,7 +12,6 @@ using System.Threading.Tasks;
using AspNet.Security.OpenIdConnect.Client;
using AspNet.Security.OpenIdConnect.Extensions;
using AspNet.Security.OpenIdConnect.Primitives;
using AspNet.Security.OpenIdConnect.Server;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http.Authentication;
@ -20,7 +19,6 @@ using Microsoft.Extensions.DependencyInjection;
using Microsoft.IdentityModel.Tokens;
using Moq;
using OpenIddict.Abstractions;
using OpenIddict.Core;
using OpenIddict.Models;
using Xunit;

2
test/OpenIddict.Server.Tests/Internal/OpenIddictServerProviderTests.Serialization.cs

@ -11,7 +11,6 @@ using System.Threading.Tasks;
using AspNet.Security.OpenIdConnect.Client;
using AspNet.Security.OpenIdConnect.Extensions;
using AspNet.Security.OpenIdConnect.Primitives;
using AspNet.Security.OpenIdConnect.Server;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
@ -19,7 +18,6 @@ using Microsoft.AspNetCore.Http.Authentication;
using Microsoft.Extensions.DependencyInjection;
using Moq;
using OpenIddict.Abstractions;
using OpenIddict.Core;
using OpenIddict.Models;
using Xunit;

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

@ -14,7 +14,6 @@ using Microsoft.Extensions.Caching.Distributed;
using Microsoft.Extensions.DependencyInjection;
using Moq;
using OpenIddict.Abstractions;
using OpenIddict.Core;
using Xunit;
namespace OpenIddict.Server.Tests

1
test/OpenIddict.Server.Tests/Internal/OpenIddictServerProviderTests.cs

@ -14,7 +14,6 @@ using System.Threading.Tasks;
using AspNet.Security.OpenIdConnect.Client;
using AspNet.Security.OpenIdConnect.Extensions;
using AspNet.Security.OpenIdConnect.Primitives;
using AspNet.Security.OpenIdConnect.Server;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Builder;

Loading…
Cancel
Save