Browse Source

Update the logout endpoint logic to not trigger a sign-out response by default and reword some of the exception messages

pull/1009/head
Kévin Chalet 6 years ago
parent
commit
e0909c87a8
  1. 6
      src/OpenIddict.Server/OpenIddictServerEvents.Authentication.cs
  2. 6
      src/OpenIddict.Server/OpenIddictServerEvents.Exchange.cs
  3. 12
      src/OpenIddict.Server/OpenIddictServerEvents.Session.cs
  4. 10
      src/OpenIddict.Server/OpenIddictServerHandlers.Authentication.cs
  5. 33
      src/OpenIddict.Server/OpenIddictServerHandlers.Device.cs
  6. 10
      src/OpenIddict.Server/OpenIddictServerHandlers.Exchange.cs
  7. 55
      src/OpenIddict.Server/OpenIddictServerHandlers.Session.cs
  8. 16
      test/OpenIddict.Server.AspNetCore.IntegrationTests/OpenIddictServerAspNetCoreIntegrationTests.cs
  9. 64
      test/OpenIddict.Server.IntegrationTests/OpenIddictServerIntegrationTests.Session.cs
  10. 16
      test/OpenIddict.Server.IntegrationTests/OpenIddictServerIntegrationTests.cs
  11. 16
      test/OpenIddict.Server.Owin.IntegrationTests/OpenIddictServerOwinIntegrationTests.cs

6
src/OpenIddict.Server/OpenIddictServerEvents.Authentication.cs

@ -91,6 +91,12 @@ namespace OpenIddict.Server
: base(transaction)
{
}
/// <summary>
/// Allows OpenIddict to return a sign-in response using the specified principal.
/// </summary>
/// <param name="principal">The claims principal.</param>
public void SignIn(ClaimsPrincipal principal) => Principal = principal;
}
/// <summary>

6
src/OpenIddict.Server/OpenIddictServerEvents.Exchange.cs

@ -60,6 +60,12 @@ namespace OpenIddict.Server
: base(transaction)
{
}
/// <summary>
/// Allows OpenIddict to return a sign-in response using the specified principal.
/// </summary>
/// <param name="principal">The claims principal.</param>
public void SignIn(ClaimsPrincipal principal) => Principal = principal;
}
/// <summary>

12
src/OpenIddict.Server/OpenIddictServerEvents.Session.cs

@ -5,7 +5,6 @@
*/
using System;
using System.Security.Claims;
using JetBrains.Annotations;
namespace OpenIddict.Server
@ -86,11 +85,14 @@ namespace OpenIddict.Server
}
/// <summary>
/// Gets or sets the security principal extracted from the id_token_hint, if available.
/// Note: the principal may not represent the user currently logged in,
/// so additional validation is strongly encouraged when using this property.
/// Gets a boolean indicating whether a sign-out should be triggered.
/// </summary>
public ClaimsPrincipal IdentityTokenHintPrincipal { get; set; }
public bool IsSignOutTriggered { get; private set; }
/// <summary>
/// Allows OpenIddict to return a sign-out response.
/// </summary>
public void SignOut() => IsSignOutTriggered = true;
}
/// <summary>

10
src/OpenIddict.Server/OpenIddictServerHandlers.Authentication.cs

@ -300,10 +300,12 @@ namespace OpenIddict.Server
}
throw new InvalidOperationException(new StringBuilder()
.Append("The authorization request was not handled. To handle authorization requests, ")
.Append("create a class implementing 'IOpenIddictServerHandler<HandleAuthorizationRequestContext>' ")
.AppendLine("and register it using 'services.AddOpenIddict().AddServer().AddEventHandler()'.")
.Append("Alternatively, enable the pass-through mode to handle them at a later stage.")
.Append("The authorization request was not handled. To handle authorization requests in a controller, ")
.Append("create a custom controller action with the same route as the authorization endpoint ")
.Append("and enable the pass-through mode in the server ASP.NET Core or OWIN options using ")
.AppendLine("'services.AddOpenIddict().AddServer().UseAspNetCore().EnableAuthorizationEndpointPassthrough()'.")
.Append("Alternatively, create a class implementing 'IOpenIddictServerHandler<HandleAuthorizationRequestContext>' ")
.Append("and register it using 'services.AddOpenIddict().AddServer().AddEventHandler()'.")
.ToString());
}
}

33
src/OpenIddict.Server/OpenIddictServerHandlers.Device.cs

@ -256,21 +256,21 @@ namespace OpenIddict.Server
return;
}
var @event = new ProcessSignInContext(context.Transaction)
{
Principal = notification.Principal,
Response = new OpenIddictResponse()
};
if (@event.Principal == null)
if (notification.Principal == null)
{
// Note: no authentication type is deliberately specified to represent an unauthenticated identity.
var principal = new ClaimsPrincipal(new ClaimsIdentity());
principal.SetScopes(context.Request.GetScopes());
@event.Principal = principal;
notification.Principal = principal;
}
var @event = new ProcessSignInContext(context.Transaction)
{
Principal = notification.Principal,
Response = new OpenIddictResponse()
};
await _dispatcher.DispatchAsync(@event);
if (@event.IsRequestHandled)
@ -293,13 +293,6 @@ namespace OpenIddict.Server
uri: @event.ErrorUri);
return;
}
throw new InvalidOperationException(new StringBuilder()
.Append("The device request was not handled. To handle device requests, ")
.Append("create a class implementing 'IOpenIddictServerHandler<HandleDeviceRequestContext>' ")
.AppendLine("and register it using 'services.AddOpenIddict().AddServer().AddEventHandler()'.")
.Append("Alternatively, enable the pass-through mode to handle them at a later stage.")
.ToString());
}
}
@ -1066,10 +1059,12 @@ namespace OpenIddict.Server
}
throw new InvalidOperationException(new StringBuilder()
.Append("The verification request was not handled. To handle verification requests, ")
.Append("create a class implementing 'IOpenIddictServerHandler<HandleVerificationRequestContext>' ")
.AppendLine("and register it using 'services.AddOpenIddict().AddServer().AddEventHandler()'.")
.Append("Alternatively, enable the pass-through mode to handle them at a later stage.")
.Append("The verification request was not handled. To handle verification requests in a controller, ")
.Append("create a custom controller action with the same route as the verification endpoint ")
.Append("and enable the pass-through mode in the server ASP.NET Core or OWIN options using ")
.AppendLine("'services.AddOpenIddict().AddServer().UseAspNetCore().EnableVerificationEndpointPassthrough()'.")
.Append("Alternatively, create a class implementing 'IOpenIddictServerHandler<HandleVerificationRequestContext>' ")
.Append("and register it using 'services.AddOpenIddict().AddServer().AddEventHandler()'.")
.ToString());
}
}

10
src/OpenIddict.Server/OpenIddictServerHandlers.Exchange.cs

@ -300,10 +300,12 @@ namespace OpenIddict.Server
}
throw new InvalidOperationException(new StringBuilder()
.Append("The token request was not handled. To handle token requests, ")
.Append("create a class implementing 'IOpenIddictServerHandler<HandleTokenRequestContext>' ")
.AppendLine("and register it using 'services.AddOpenIddict().AddServer().AddEventHandler()'.")
.Append("Alternatively, enable the pass-through mode to handle them at a later stage.")
.Append("The token request was not handled. To handle token requests in a controller, ")
.Append("create a custom controller action with the same route as the token endpoint ")
.Append("and enable the pass-through mode in the server ASP.NET Core or OWIN options using ")
.AppendLine("'services.AddOpenIddict().AddServer().UseAspNetCore().EnableTokenEndpointPassthrough()'.")
.Append("Alternatively, create a class implementing 'IOpenIddictServerHandler<HandleTokenRequestContext>' ")
.Append("and register it using 'services.AddOpenIddict().AddServer().AddEventHandler()'.")
.ToString());
}
}

55
src/OpenIddict.Server/OpenIddictServerHandlers.Session.cs

@ -242,39 +242,44 @@ namespace OpenIddict.Server
return;
}
var @event = new ProcessSignOutContext(context.Transaction)
if (notification.IsSignOutTriggered)
{
Response = new OpenIddictResponse()
};
var @event = new ProcessSignOutContext(context.Transaction)
{
Response = new OpenIddictResponse()
};
await _dispatcher.DispatchAsync(@event);
await _dispatcher.DispatchAsync(@event);
if (@event.IsRequestHandled)
{
context.HandleRequest();
return;
}
if (@event.IsRequestHandled)
{
context.HandleRequest();
return;
}
else if (@event.IsRequestSkipped)
{
context.SkipRequest();
return;
}
else if (@event.IsRequestSkipped)
{
context.SkipRequest();
return;
}
else if (@event.IsRejected)
{
context.Reject(
error: @event.Error ?? Errors.InvalidRequest,
description: @event.ErrorDescription,
uri: @event.ErrorUri);
return;
else if (@event.IsRejected)
{
context.Reject(
error: @event.Error ?? Errors.InvalidRequest,
description: @event.ErrorDescription,
uri: @event.ErrorUri);
return;
}
}
throw new InvalidOperationException(new StringBuilder()
.Append("The logout request was not handled. To handle logout requests, ")
.Append("create a class implementing 'IOpenIddictServerHandler<HandleLogoutRequestContext>' ")
.AppendLine("and register it using 'services.AddOpenIddict().AddServer().AddEventHandler()'.")
.Append("Alternatively, enable the pass-through mode to handle them at a later stage.")
.Append("The logout request was not handled. To handle logout requests in a controller, ")
.Append("create a custom controller action with the same route as the logout endpoint ")
.Append("and enable the pass-through mode in the server ASP.NET Core or OWIN options using ")
.AppendLine("'services.AddOpenIddict().AddServer().UseAspNetCore().EnableLogoutEndpointPassthrough()'.")
.Append("Alternatively, create a class implementing 'IOpenIddictServerHandler<HandleLogoutRequestContext>' ")
.Append("and register it using 'services.AddOpenIddict().AddServer().AddEventHandler()'.")
.ToString());
}
}

16
test/OpenIddict.Server.AspNetCore.IntegrationTests/OpenIddictServerAspNetCoreIntegrationTests.cs

@ -188,6 +188,14 @@ namespace OpenIddict.Server.AspNetCore.FunctionalTests
{
options.EnableDegradedMode();
options.AddEventHandler<HandleLogoutRequestContext>(builder =>
builder.UseInlineHandler(context =>
{
context.SignOut();
return default;
}));
options.AddEventHandler<ProcessRequestContext>(builder =>
builder.UseInlineHandler(context =>
{
@ -221,6 +229,14 @@ namespace OpenIddict.Server.AspNetCore.FunctionalTests
{
options.EnableDegradedMode();
options.AddEventHandler<HandleLogoutRequestContext>(builder =>
builder.UseInlineHandler(context =>
{
context.SignOut();
return default;
}));
options.AddEventHandler<ProcessRequestContext>(builder =>
{
builder.UseInlineHandler(context =>

64
test/OpenIddict.Server.IntegrationTests/OpenIddictServerIntegrationTests.Session.cs

@ -261,6 +261,14 @@ namespace OpenIddict.Server.FunctionalTests
options.SetLogoutEndpointUris("/signout");
options.Configure(options => options.IgnoreEndpointPermissions = false);
options.AddEventHandler<HandleLogoutRequestContext>(builder =>
builder.UseInlineHandler(context =>
{
context.SignOut();
return default;
}));
});
await using var client = await server.CreateClientAsync();
@ -473,6 +481,14 @@ namespace OpenIddict.Server.FunctionalTests
{
options.EnableDegradedMode();
options.AddEventHandler<HandleLogoutRequestContext>(builder =>
builder.UseInlineHandler(context =>
{
context.SignOut();
return default;
}));
options.AddEventHandler<ApplyLogoutResponseContext>(builder =>
builder.UseInlineHandler(context =>
{
@ -504,6 +520,14 @@ namespace OpenIddict.Server.FunctionalTests
{
options.EnableDegradedMode();
options.AddEventHandler<HandleLogoutRequestContext>(builder =>
builder.UseInlineHandler(context =>
{
context.SignOut();
return default;
}));
options.AddEventHandler<ApplyLogoutResponseContext>(builder =>
builder.UseInlineHandler(context =>
{
@ -539,6 +563,14 @@ namespace OpenIddict.Server.FunctionalTests
{
options.EnableDegradedMode();
options.AddEventHandler<HandleLogoutRequestContext>(builder =>
builder.UseInlineHandler(context =>
{
context.SignOut();
return default;
}));
options.AddEventHandler<ApplyLogoutResponseContext>(builder =>
builder.UseInlineHandler(context =>
{
@ -568,6 +600,14 @@ namespace OpenIddict.Server.FunctionalTests
{
options.EnableDegradedMode();
options.AddEventHandler<HandleLogoutRequestContext>(builder =>
builder.UseInlineHandler(context =>
{
context.SignOut();
return default;
}));
options.AddEventHandler<ApplyLogoutResponseContext>(builder =>
builder.UseInlineHandler(context =>
{
@ -594,6 +634,14 @@ namespace OpenIddict.Server.FunctionalTests
{
options.EnableDegradedMode();
options.SetLogoutEndpointUris("/signout");
options.AddEventHandler<HandleLogoutRequestContext>(builder =>
builder.UseInlineHandler(context =>
{
context.SignOut();
return default;
}));
});
await using var client = await server.CreateClientAsync();
@ -616,6 +664,14 @@ namespace OpenIddict.Server.FunctionalTests
{
options.EnableDegradedMode();
options.SetLogoutEndpointUris("/signout");
options.AddEventHandler<HandleLogoutRequestContext>(builder =>
builder.UseInlineHandler(context =>
{
context.SignOut();
return default;
}));
});
await using var client = await server.CreateClientAsync();
@ -640,6 +696,14 @@ namespace OpenIddict.Server.FunctionalTests
options.EnableDegradedMode();
options.SetLogoutEndpointUris("/signout");
options.AddEventHandler<HandleLogoutRequestContext>(builder =>
builder.UseInlineHandler(context =>
{
context.SignOut();
return default;
}));
options.AddEventHandler<ApplyLogoutResponseContext>(builder =>
builder.UseInlineHandler(context =>
{

16
test/OpenIddict.Server.IntegrationTests/OpenIddictServerIntegrationTests.cs

@ -4147,6 +4147,14 @@ namespace OpenIddict.Server.FunctionalTests
{
options.EnableDegradedMode();
options.AddEventHandler<HandleLogoutRequestContext>(builder =>
builder.UseInlineHandler(context =>
{
context.SignOut();
return default;
}));
options.AddEventHandler<ProcessSignOutContext>(builder =>
builder.UseInlineHandler(context =>
{
@ -4175,6 +4183,14 @@ namespace OpenIddict.Server.FunctionalTests
{
options.EnableDegradedMode();
options.AddEventHandler<HandleLogoutRequestContext>(builder =>
builder.UseInlineHandler(context =>
{
context.SignOut();
return default;
}));
options.AddEventHandler<ProcessSignOutContext>(builder =>
builder.UseInlineHandler(context =>
{

16
test/OpenIddict.Server.Owin.IntegrationTests/OpenIddictServerOwinIntegrationTests.cs

@ -144,6 +144,14 @@ namespace OpenIddict.Server.Owin.FunctionalTests
{
options.EnableDegradedMode();
options.AddEventHandler<HandleLogoutRequestContext>(builder =>
builder.UseInlineHandler(context =>
{
context.SignOut();
return default;
}));
options.AddEventHandler<ProcessRequestContext>(builder =>
builder.UseInlineHandler(context =>
{
@ -177,6 +185,14 @@ namespace OpenIddict.Server.Owin.FunctionalTests
{
options.EnableDegradedMode();
options.AddEventHandler<HandleLogoutRequestContext>(builder =>
builder.UseInlineHandler(context =>
{
context.SignOut();
return default;
}));
options.AddEventHandler<ProcessRequestContext>(builder =>
{
builder.UseInlineHandler(context =>

Loading…
Cancel
Save