Browse Source

Throw an InvalidOperationException when SignIn() is called with an unauthenticated ClaimsIdentity

pull/627/head
Kévin Chalet 8 years ago
parent
commit
e9c796ca37
  1. 16
      src/OpenIddict.Server/Internal/OpenIddictServerProvider.cs
  2. 33
      test/OpenIddict.Server.Tests/Internal/OpenIddictServerProviderTests.cs

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

@ -4,9 +4,11 @@
* the license and the contributors participating to this project.
*/
using System;
using System.ComponentModel;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using AspNet.Security.OpenIdConnect.Extensions;
using AspNet.Security.OpenIdConnect.Primitives;
@ -75,6 +77,20 @@ namespace OpenIddict.Server
context.Request.IsTokenRequest(),
"The request should be an authorization or token request.");
// While null/unauthenticated identities can be validly represented and are allowed by
// the OpenID Connect server handler, this most likely indicates that the developer
// has not correctly set the authentication type associated with the claims identity,
// which may later cause issues when validating opaque access tokens, as the resulting
// principal would be considered unauthenticated by the ASP.NET Core authorization stack.
if (context.Ticket.Principal.Identity == null || !context.Ticket.Principal.Identity.IsAuthenticated)
{
throw new InvalidOperationException(new StringBuilder()
.AppendLine("The specified principal doesn't contain a valid or authenticated identity.")
.Append("Make sure that both 'ClaimsPrincipal.Identity' and 'ClaimsPrincipal.Identity.AuthenticationType' ")
.Append("are not null and that 'ClaimsPrincipal.Identity.IsAuthenticated' returns 'true'.")
.ToString());
}
if (context.Request.IsTokenRequest() && (context.Request.IsAuthorizationCodeGrantType() ||
context.Request.IsRefreshTokenGrantType()))
{

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

@ -9,6 +9,7 @@ using System.Collections.Immutable;
using System.Linq;
using System.Reflection;
using System.Security.Claims;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using AspNet.Security.OpenIdConnect.Client;
@ -114,6 +115,33 @@ namespace OpenIddict.Server.Tests
Assert.Equal("value", (string) response["custom_string_parameter"]);
}
[Fact]
public async Task ProcessSigninResponse_ThrowsAnExceptionForInvalidIdentity()
{
// Arrange
var server = CreateAuthorizationServer();
var client = new OpenIdConnectClient(server.CreateClient());
// Act and assert
var exception = await Assert.ThrowsAsync<InvalidOperationException>(delegate
{
return client.PostAsync(TokenEndpoint, new OpenIdConnectRequest
{
GrantType = OpenIdConnectConstants.GrantTypes.Password,
Username = "johndoe",
Password = "A3ddj3w",
["use-null-authentication-type"] = true
});
});
Assert.Equal(new StringBuilder()
.AppendLine("The specified principal doesn't contain a valid or authenticated identity.")
.Append("Make sure that both 'ClaimsPrincipal.Identity' and 'ClaimsPrincipal.Identity.AuthenticationType' ")
.Append("are not null and that 'ClaimsPrincipal.Identity.IsAuthenticated' returns 'true'.")
.ToString(), exception.Message);
}
[Fact]
public async Task ProcessSigninResponse_AuthenticationPropertiesAreAutomaticallyRestored()
{
@ -1471,7 +1499,10 @@ namespace OpenIddict.Server.Tests
return Task.CompletedTask;
}
var identity = new ClaimsIdentity(OpenIddictServerDefaults.AuthenticationScheme);
var identity = !request.HasParameter("use-null-authentication-type") ?
new ClaimsIdentity(OpenIddictServerDefaults.AuthenticationScheme) :
new ClaimsIdentity();
identity.AddClaim(OpenIdConnectConstants.Claims.Subject, "Bob le Magnifique");
var ticket = new AuthenticationTicket(

Loading…
Cancel
Save