Permalink
Browse files

Prevent the deserialization methods from being called twice when rece…

…iving an introspection or revocation request with a token_type_hint
  • Loading branch information...
PinpointTownes committed Oct 9, 2017
1 parent d95810b commit c561a3418daefda64f7bd27ae5d9b2f0dce03e27
@@ -219,10 +219,42 @@ private async Task<bool> InvokeIntrospectionEndpointAsync()
// See https://tools.ietf.org/html/rfc7662#section-2.1
if (ticket == null)
{
ticket = await DeserializeAccessTokenAsync(request.Token, request) ??
await DeserializeAuthorizationCodeAsync(request.Token, request) ??
await DeserializeIdentityTokenAsync(request.Token, request) ??
await DeserializeRefreshTokenAsync(request.Token, request);
// To avoid calling the same deserialization methods twice,
// an additional check is made to exclude the corresponding
// method when an explicit token_type_hint was specified.
switch (request.TokenTypeHint)
{
case OpenIdConnectConstants.TokenTypeHints.AccessToken:
ticket = await DeserializeAuthorizationCodeAsync(request.Token, request) ??
await DeserializeIdentityTokenAsync(request.Token, request) ??
await DeserializeRefreshTokenAsync(request.Token, request);
break;
case OpenIdConnectConstants.TokenTypeHints.AuthorizationCode:
ticket = await DeserializeAccessTokenAsync(request.Token, request) ??
await DeserializeIdentityTokenAsync(request.Token, request) ??
await DeserializeRefreshTokenAsync(request.Token, request);
break;
case OpenIdConnectConstants.TokenTypeHints.IdToken:
ticket = await DeserializeAccessTokenAsync(request.Token, request) ??
await DeserializeAuthorizationCodeAsync(request.Token, request) ??
await DeserializeRefreshTokenAsync(request.Token, request);
break;
case OpenIdConnectConstants.TokenTypeHints.RefreshToken:
ticket = await DeserializeAccessTokenAsync(request.Token, request) ??
await DeserializeAuthorizationCodeAsync(request.Token, request) ??
await DeserializeIdentityTokenAsync(request.Token, request);
break;
default:
ticket = await DeserializeAccessTokenAsync(request.Token, request) ??
await DeserializeAuthorizationCodeAsync(request.Token, request) ??
await DeserializeIdentityTokenAsync(request.Token, request) ??
await DeserializeRefreshTokenAsync(request.Token, request);
break;
}
}
if (ticket == null)
@@ -204,10 +204,42 @@ private async Task<bool> InvokeRevocationEndpointAsync()
// See https://tools.ietf.org/html/rfc7009#section-2.1
if (ticket == null)
{
ticket = await DeserializeAccessTokenAsync(request.Token, request) ??
await DeserializeAuthorizationCodeAsync(request.Token, request) ??
await DeserializeIdentityTokenAsync(request.Token, request) ??
await DeserializeRefreshTokenAsync(request.Token, request);
// To avoid calling the same deserialization methods twice,
// an additional check is made to exclude the corresponding
// method when an explicit token_type_hint was specified.
switch (request.TokenTypeHint)
{
case OpenIdConnectConstants.TokenTypeHints.AccessToken:
ticket = await DeserializeAuthorizationCodeAsync(request.Token, request) ??
await DeserializeIdentityTokenAsync(request.Token, request) ??
await DeserializeRefreshTokenAsync(request.Token, request);
break;
case OpenIdConnectConstants.TokenTypeHints.AuthorizationCode:
ticket = await DeserializeAccessTokenAsync(request.Token, request) ??
await DeserializeIdentityTokenAsync(request.Token, request) ??
await DeserializeRefreshTokenAsync(request.Token, request);
break;
case OpenIdConnectConstants.TokenTypeHints.IdToken:
ticket = await DeserializeAccessTokenAsync(request.Token, request) ??
await DeserializeAuthorizationCodeAsync(request.Token, request) ??
await DeserializeRefreshTokenAsync(request.Token, request);
break;
case OpenIdConnectConstants.TokenTypeHints.RefreshToken:
ticket = await DeserializeAccessTokenAsync(request.Token, request) ??
await DeserializeAuthorizationCodeAsync(request.Token, request) ??
await DeserializeIdentityTokenAsync(request.Token, request);
break;
default:
ticket = await DeserializeAccessTokenAsync(request.Token, request) ??
await DeserializeAuthorizationCodeAsync(request.Token, request) ??
await DeserializeIdentityTokenAsync(request.Token, request) ??
await DeserializeRefreshTokenAsync(request.Token, request);
break;
}
}
if (ticket == null)
@@ -219,10 +219,42 @@ private async Task<bool> InvokeIntrospectionEndpointAsync()
// See https://tools.ietf.org/html/rfc7662#section-2.1
if (ticket == null)
{
ticket = await DeserializeAccessTokenAsync(request.Token, request) ??
await DeserializeAuthorizationCodeAsync(request.Token, request) ??
await DeserializeIdentityTokenAsync(request.Token, request) ??
await DeserializeRefreshTokenAsync(request.Token, request);
// To avoid calling the same deserialization methods twice,
// an additional check is made to exclude the corresponding
// method when an explicit token_type_hint was specified.
switch (request.TokenTypeHint)
{
case OpenIdConnectConstants.TokenTypeHints.AccessToken:
ticket = await DeserializeAuthorizationCodeAsync(request.Token, request) ??
await DeserializeIdentityTokenAsync(request.Token, request) ??
await DeserializeRefreshTokenAsync(request.Token, request);
break;
case OpenIdConnectConstants.TokenTypeHints.AuthorizationCode:
ticket = await DeserializeAccessTokenAsync(request.Token, request) ??
await DeserializeIdentityTokenAsync(request.Token, request) ??
await DeserializeRefreshTokenAsync(request.Token, request);
break;
case OpenIdConnectConstants.TokenTypeHints.IdToken:
ticket = await DeserializeAccessTokenAsync(request.Token, request) ??
await DeserializeAuthorizationCodeAsync(request.Token, request) ??
await DeserializeRefreshTokenAsync(request.Token, request);
break;
case OpenIdConnectConstants.TokenTypeHints.RefreshToken:
ticket = await DeserializeAccessTokenAsync(request.Token, request) ??
await DeserializeAuthorizationCodeAsync(request.Token, request) ??
await DeserializeIdentityTokenAsync(request.Token, request);
break;
default:
ticket = await DeserializeAccessTokenAsync(request.Token, request) ??
await DeserializeAuthorizationCodeAsync(request.Token, request) ??
await DeserializeIdentityTokenAsync(request.Token, request) ??
await DeserializeRefreshTokenAsync(request.Token, request);
break;
}
}
if (ticket == null)
@@ -204,10 +204,42 @@ private async Task<bool> InvokeRevocationEndpointAsync()
// See https://tools.ietf.org/html/rfc7009#section-2.1
if (ticket == null)
{
ticket = await DeserializeAccessTokenAsync(request.Token, request) ??
await DeserializeAuthorizationCodeAsync(request.Token, request) ??
await DeserializeIdentityTokenAsync(request.Token, request) ??
await DeserializeRefreshTokenAsync(request.Token, request);
// To avoid calling the same deserialization methods twice,
// an additional check is made to exclude the corresponding
// method when an explicit token_type_hint was specified.
switch (request.TokenTypeHint)
{
case OpenIdConnectConstants.TokenTypeHints.AccessToken:
ticket = await DeserializeAuthorizationCodeAsync(request.Token, request) ??
await DeserializeIdentityTokenAsync(request.Token, request) ??
await DeserializeRefreshTokenAsync(request.Token, request);
break;
case OpenIdConnectConstants.TokenTypeHints.AuthorizationCode:
ticket = await DeserializeAccessTokenAsync(request.Token, request) ??
await DeserializeIdentityTokenAsync(request.Token, request) ??
await DeserializeRefreshTokenAsync(request.Token, request);
break;
case OpenIdConnectConstants.TokenTypeHints.IdToken:
ticket = await DeserializeAccessTokenAsync(request.Token, request) ??
await DeserializeAuthorizationCodeAsync(request.Token, request) ??
await DeserializeRefreshTokenAsync(request.Token, request);
break;
case OpenIdConnectConstants.TokenTypeHints.RefreshToken:
ticket = await DeserializeAccessTokenAsync(request.Token, request) ??
await DeserializeAuthorizationCodeAsync(request.Token, request) ??
await DeserializeIdentityTokenAsync(request.Token, request);
break;
default:
ticket = await DeserializeAccessTokenAsync(request.Token, request) ??
await DeserializeAuthorizationCodeAsync(request.Token, request) ??
await DeserializeIdentityTokenAsync(request.Token, request) ??
await DeserializeRefreshTokenAsync(request.Token, request);
break;
}
}
if (ticket == null)
@@ -356,6 +356,69 @@ public async Task InvokeIntrospectionEndpointAsync_InvalidTokenCausesAnError()
Assert.False((bool) response[OpenIdConnectConstants.Parameters.Active]);
}
[Theory]
[InlineData(OpenIdConnectConstants.TokenTypeHints.AccessToken)]
[InlineData(OpenIdConnectConstants.TokenTypeHints.AuthorizationCode)]
[InlineData(OpenIdConnectConstants.TokenTypeHints.IdToken)]
[InlineData(OpenIdConnectConstants.TokenTypeHints.RefreshToken)]
public async Task InvokeIntrospectionEndpointAsync_TokenIsNotDeserializedTwice(string hint)
{
// Arrange
var server = CreateAuthorizationServer(options =>
{
options.Provider.OnDeserializeAccessToken = context =>
{
Assert.False(context.Request.HasProperty(nameof(options.Provider.OnDeserializeAccessToken)));
context.Request.AddProperty(nameof(options.Provider.OnDeserializeAccessToken), new object());
return Task.FromResult(0);
};
options.Provider.OnDeserializeAuthorizationCode = context =>
{
Assert.False(context.Request.HasProperty(nameof(options.Provider.OnDeserializeAuthorizationCode)));
context.Request.AddProperty(nameof(options.Provider.OnDeserializeAuthorizationCode), new object());
return Task.FromResult(0);
};
options.Provider.OnDeserializeIdentityToken = context =>
{
Assert.False(context.Request.HasProperty(nameof(options.Provider.OnDeserializeIdentityToken)));
context.Request.AddProperty(nameof(options.Provider.OnDeserializeIdentityToken), new object());
return Task.FromResult(0);
};
options.Provider.OnDeserializeRefreshToken = context =>
{
Assert.False(context.Request.HasProperty(nameof(options.Provider.OnDeserializeRefreshToken)));
context.Request.AddProperty(nameof(options.Provider.OnDeserializeRefreshToken), new object());
return Task.FromResult(0);
};
options.Provider.OnValidateIntrospectionRequest = context =>
{
context.Skip();
return Task.FromResult(0);
};
});
var client = new OpenIdConnectClient(server.CreateClient());
// Act
var response = await client.PostAsync(IntrospectionEndpoint, new OpenIdConnectRequest
{
Token = "SlAV32hkKG",
TokenTypeHint = hint
});
// Assert
Assert.False((bool) response[OpenIdConnectConstants.Parameters.Active]);
}
[Fact]
public async Task InvokeIntrospectionEndpointAsync_ConfidentialTokenCausesAnErrorWhenValidationIsSkipped()
{
Oops, something went wrong.

0 comments on commit c561a34

Please sign in to comment.