|
|
|
@ -2353,184 +2353,6 @@ namespace OpenIddict.Server.IntegrationTests |
|
|
|
Mock.Get(manager).Verify(manager => manager.HasStatusAsync(token, Statuses.Redeemed, It.IsAny<CancellationToken>()), Times.Once()); |
|
|
|
} |
|
|
|
|
|
|
|
[Fact] |
|
|
|
public async Task HandleTokenRequest_RevokesAuthorizationWhenAuthorizationCodeIsAlreadyRedeemed() |
|
|
|
{ |
|
|
|
// Arrange
|
|
|
|
var authorization = new OpenIddictAuthorization(); |
|
|
|
|
|
|
|
var manager = CreateAuthorizationManager(mock => |
|
|
|
{ |
|
|
|
mock.Setup(manager => manager.FindByIdAsync("18D15F73-BE2B-6867-DC01-B3C1E8AFDED0", It.IsAny<CancellationToken>())) |
|
|
|
.ReturnsAsync(authorization); |
|
|
|
}); |
|
|
|
|
|
|
|
await using var server = await CreateServerAsync(options => |
|
|
|
{ |
|
|
|
options.AddEventHandler<ProcessAuthenticationContext>(builder => |
|
|
|
{ |
|
|
|
builder.UseInlineHandler(context => |
|
|
|
{ |
|
|
|
Assert.Equal("SplxlOBeZQQYbYS6WxSbIA", context.Token); |
|
|
|
Assert.Equal(TokenTypeHints.AuthorizationCode, context.TokenType); |
|
|
|
|
|
|
|
context.Principal = new ClaimsPrincipal(new ClaimsIdentity("Bearer")) |
|
|
|
.SetTokenType(TokenTypeHints.AuthorizationCode) |
|
|
|
.SetPresenters("Fabrikam") |
|
|
|
.SetTokenId("3E228451-1555-46F7-A471-951EFBA23A56") |
|
|
|
.SetAuthorizationId("18D15F73-BE2B-6867-DC01-B3C1E8AFDED0") |
|
|
|
.SetClaim(Claims.Subject, "Bob le Bricoleur"); |
|
|
|
|
|
|
|
return default; |
|
|
|
}); |
|
|
|
|
|
|
|
builder.SetOrder(ValidateIdentityModelToken.Descriptor.Order - 500); |
|
|
|
}); |
|
|
|
|
|
|
|
options.AddEventHandler<HandleTokenRequestContext>(builder => |
|
|
|
builder.UseInlineHandler(context => |
|
|
|
{ |
|
|
|
context.Principal = new ClaimsPrincipal(new ClaimsIdentity("Bearer")) |
|
|
|
.SetClaim(Claims.Subject, "Bob le Magnifique"); |
|
|
|
|
|
|
|
return default; |
|
|
|
})); |
|
|
|
|
|
|
|
options.Services.AddSingleton(CreateApplicationManager(mock => |
|
|
|
{ |
|
|
|
var application = new OpenIddictApplication(); |
|
|
|
|
|
|
|
mock.Setup(manager => manager.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>())) |
|
|
|
.ReturnsAsync(application); |
|
|
|
|
|
|
|
mock.Setup(manager => manager.HasClientTypeAsync(application, ClientTypes.Public, It.IsAny<CancellationToken>())) |
|
|
|
.ReturnsAsync(true); |
|
|
|
})); |
|
|
|
|
|
|
|
options.Services.AddSingleton(CreateTokenManager(mock => |
|
|
|
{ |
|
|
|
var token = new OpenIddictToken(); |
|
|
|
|
|
|
|
mock.Setup(manager => manager.FindByIdAsync("3E228451-1555-46F7-A471-951EFBA23A56", It.IsAny<CancellationToken>())) |
|
|
|
.ReturnsAsync(token); |
|
|
|
|
|
|
|
mock.Setup(manager => manager.GetIdAsync(token, It.IsAny<CancellationToken>())) |
|
|
|
.ReturnsAsync("3E228451-1555-46F7-A471-951EFBA23A56"); |
|
|
|
|
|
|
|
mock.Setup(manager => manager.GetAuthorizationIdAsync(token, It.IsAny<CancellationToken>())) |
|
|
|
.ReturnsAsync("18D15F73-BE2B-6867-DC01-B3C1E8AFDED0"); |
|
|
|
|
|
|
|
mock.Setup(manager => manager.HasStatusAsync(token, Statuses.Redeemed, It.IsAny<CancellationToken>())) |
|
|
|
.ReturnsAsync(true); |
|
|
|
|
|
|
|
mock.Setup(manager => manager.FindByAuthorizationIdAsync("18D15F73-BE2B-6867-DC01-B3C1E8AFDED0", It.IsAny<CancellationToken>())) |
|
|
|
.Returns(AsyncEnumerable.Empty<OpenIddictToken>()); |
|
|
|
})); |
|
|
|
|
|
|
|
options.Services.AddSingleton(manager); |
|
|
|
}); |
|
|
|
|
|
|
|
await using var client = await server.CreateClientAsync(); |
|
|
|
|
|
|
|
// Act
|
|
|
|
var response = await client.PostAsync("/connect/token", new OpenIddictRequest |
|
|
|
{ |
|
|
|
ClientId = "Fabrikam", |
|
|
|
Code = "SplxlOBeZQQYbYS6WxSbIA", |
|
|
|
GrantType = GrantTypes.AuthorizationCode, |
|
|
|
RedirectUri = "http://www.fabrikam.com/path" |
|
|
|
}); |
|
|
|
|
|
|
|
// Assert
|
|
|
|
Assert.Equal(Errors.InvalidGrant, response.Error); |
|
|
|
Assert.Equal(SR.GetResourceString(SR.ID3010), response.ErrorDescription); |
|
|
|
|
|
|
|
Mock.Get(manager).Verify(manager => manager.FindByIdAsync("18D15F73-BE2B-6867-DC01-B3C1E8AFDED0", It.IsAny<CancellationToken>()), Times.Once()); |
|
|
|
Mock.Get(manager).Verify(manager => manager.TryRevokeAsync(authorization, It.IsAny<CancellationToken>()), Times.Once()); |
|
|
|
} |
|
|
|
|
|
|
|
[Fact] |
|
|
|
public async Task HandleTokenRequest_RevokesAuthorizationWhenRefreshTokenIsAlreadyRedeemed() |
|
|
|
{ |
|
|
|
// Arrange
|
|
|
|
var authorization = new OpenIddictAuthorization(); |
|
|
|
|
|
|
|
var manager = CreateAuthorizationManager(mock => |
|
|
|
{ |
|
|
|
mock.Setup(manager => manager.FindByIdAsync("18D15F73-BE2B-6867-DC01-B3C1E8AFDED0", It.IsAny<CancellationToken>())) |
|
|
|
.ReturnsAsync(authorization); |
|
|
|
}); |
|
|
|
|
|
|
|
await using var server = await CreateServerAsync(options => |
|
|
|
{ |
|
|
|
options.AddEventHandler<ProcessAuthenticationContext>(builder => |
|
|
|
{ |
|
|
|
builder.UseInlineHandler(context => |
|
|
|
{ |
|
|
|
Assert.Equal("8xLOxBtZp8", context.Token); |
|
|
|
Assert.Equal(TokenTypeHints.RefreshToken, context.TokenType); |
|
|
|
|
|
|
|
context.Principal = new ClaimsPrincipal(new ClaimsIdentity("Bearer")) |
|
|
|
.SetTokenType(TokenTypeHints.RefreshToken) |
|
|
|
.SetTokenId("60FFF7EA-F98E-437B-937E-5073CC313103") |
|
|
|
.SetAuthorizationId("18D15F73-BE2B-6867-DC01-B3C1E8AFDED0") |
|
|
|
.SetClaim(Claims.Subject, "Bob le Bricoleur"); |
|
|
|
|
|
|
|
return default; |
|
|
|
}); |
|
|
|
|
|
|
|
builder.SetOrder(ValidateIdentityModelToken.Descriptor.Order - 500); |
|
|
|
}); |
|
|
|
|
|
|
|
options.AddEventHandler<HandleTokenRequestContext>(builder => |
|
|
|
builder.UseInlineHandler(context => |
|
|
|
{ |
|
|
|
context.Principal = new ClaimsPrincipal(new ClaimsIdentity("Bearer")) |
|
|
|
.SetClaim(Claims.Subject, "Bob le Magnifique"); |
|
|
|
|
|
|
|
return default; |
|
|
|
})); |
|
|
|
|
|
|
|
options.Services.AddSingleton(CreateTokenManager(mock => |
|
|
|
{ |
|
|
|
var token = new OpenIddictToken(); |
|
|
|
|
|
|
|
mock.Setup(manager => manager.FindByIdAsync("60FFF7EA-F98E-437B-937E-5073CC313103", It.IsAny<CancellationToken>())) |
|
|
|
.ReturnsAsync(token); |
|
|
|
|
|
|
|
mock.Setup(manager => manager.GetIdAsync(token, It.IsAny<CancellationToken>())) |
|
|
|
.ReturnsAsync("60FFF7EA-F98E-437B-937E-5073CC313103"); |
|
|
|
|
|
|
|
mock.Setup(manager => manager.GetAuthorizationIdAsync(token, It.IsAny<CancellationToken>())) |
|
|
|
.ReturnsAsync("18D15F73-BE2B-6867-DC01-B3C1E8AFDED0"); |
|
|
|
|
|
|
|
mock.Setup(manager => manager.HasStatusAsync(token, Statuses.Redeemed, It.IsAny<CancellationToken>())) |
|
|
|
.ReturnsAsync(true); |
|
|
|
|
|
|
|
mock.Setup(manager => manager.FindByAuthorizationIdAsync("18D15F73-BE2B-6867-DC01-B3C1E8AFDED0", It.IsAny<CancellationToken>())) |
|
|
|
.Returns(AsyncEnumerable.Empty<OpenIddictToken>()); |
|
|
|
})); |
|
|
|
|
|
|
|
options.Services.AddSingleton(manager); |
|
|
|
}); |
|
|
|
|
|
|
|
await using var client = await server.CreateClientAsync(); |
|
|
|
|
|
|
|
// Act
|
|
|
|
var response = await client.PostAsync("/connect/token", new OpenIddictRequest |
|
|
|
{ |
|
|
|
GrantType = GrantTypes.RefreshToken, |
|
|
|
RefreshToken = "8xLOxBtZp8" |
|
|
|
}); |
|
|
|
|
|
|
|
// Assert
|
|
|
|
Assert.Equal(Errors.InvalidGrant, response.Error); |
|
|
|
Assert.Equal(SR.GetResourceString(SR.ID3012), response.ErrorDescription); |
|
|
|
|
|
|
|
Mock.Get(manager).Verify(manager => manager.FindByIdAsync("18D15F73-BE2B-6867-DC01-B3C1E8AFDED0", It.IsAny<CancellationToken>()), Times.Once()); |
|
|
|
Mock.Get(manager).Verify(manager => manager.TryRevokeAsync(authorization, It.IsAny<CancellationToken>()), Times.Once()); |
|
|
|
} |
|
|
|
|
|
|
|
[Fact] |
|
|
|
public async Task HandleTokenRequest_RevokesTokensWhenAuthorizationCodeIsAlreadyRedeemed() |
|
|
|
{ |
|
|
|
|