|
|
|
@ -3095,6 +3095,130 @@ public abstract partial class OpenIddictServerIntegrationTests |
|
|
|
Assert.Equal(SR.FormatID8000(SR.ID2029), response.ErrorUri); |
|
|
|
} |
|
|
|
|
|
|
|
[Fact] |
|
|
|
public async Task ValidatePushedAuthorizationRequest_ClientSecretCannotBeUsedByPublicClients() |
|
|
|
{ |
|
|
|
// Arrange
|
|
|
|
var application = new OpenIddictApplication(); |
|
|
|
|
|
|
|
var manager = CreateApplicationManager(mock => |
|
|
|
{ |
|
|
|
mock.Setup(manager => manager.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>())) |
|
|
|
.ReturnsAsync(application); |
|
|
|
|
|
|
|
mock.Setup(manager => manager.HasClientTypeAsync(application, ClientTypes.Public, It.IsAny<CancellationToken>())) |
|
|
|
.ReturnsAsync(true); |
|
|
|
}); |
|
|
|
|
|
|
|
await using var server = await CreateServerAsync(options => |
|
|
|
{ |
|
|
|
options.Services.AddSingleton(manager); |
|
|
|
}); |
|
|
|
|
|
|
|
await using var client = await server.CreateClientAsync(); |
|
|
|
|
|
|
|
// Act
|
|
|
|
var response = await client.PostAsync("/connect/par", new OpenIddictRequest |
|
|
|
{ |
|
|
|
ClientId = "Fabrikam", |
|
|
|
ClientSecret = "7Fjfp0ZBr1KtDRbnfVdmIw", |
|
|
|
RedirectUri = "http://www.fabrikam.com/path", |
|
|
|
ResponseType = ResponseTypes.Code |
|
|
|
}); |
|
|
|
|
|
|
|
// Assert
|
|
|
|
Assert.Equal(Errors.InvalidClient, response.Error); |
|
|
|
Assert.Equal(SR.FormatID2053(Parameters.ClientSecret), response.ErrorDescription); |
|
|
|
Assert.Equal(SR.FormatID8000(SR.ID2053), response.ErrorUri); |
|
|
|
|
|
|
|
Mock.Get(manager).Verify(manager => manager.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>()), Times.AtLeastOnce()); |
|
|
|
Mock.Get(manager).Verify(manager => manager.HasClientTypeAsync(application, ClientTypes.Public, It.IsAny<CancellationToken>()), Times.Once()); |
|
|
|
} |
|
|
|
|
|
|
|
[Fact] |
|
|
|
public async Task ValidatePushedAuthorizationRequest_ClientSecretIsRequiredForNonPublicClients() |
|
|
|
{ |
|
|
|
// Arrange
|
|
|
|
var application = new OpenIddictApplication(); |
|
|
|
|
|
|
|
var manager = CreateApplicationManager(mock => |
|
|
|
{ |
|
|
|
mock.Setup(manager => manager.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>())) |
|
|
|
.ReturnsAsync(application); |
|
|
|
|
|
|
|
mock.Setup(manager => manager.HasClientTypeAsync(application, ClientTypes.Public, It.IsAny<CancellationToken>())) |
|
|
|
.ReturnsAsync(false); |
|
|
|
}); |
|
|
|
|
|
|
|
await using var server = await CreateServerAsync(options => |
|
|
|
{ |
|
|
|
options.Services.AddSingleton(manager); |
|
|
|
}); |
|
|
|
|
|
|
|
await using var client = await server.CreateClientAsync(); |
|
|
|
|
|
|
|
// Act
|
|
|
|
var response = await client.PostAsync("/connect/par", new OpenIddictRequest |
|
|
|
{ |
|
|
|
ClientId = "Fabrikam", |
|
|
|
ClientSecret = null, |
|
|
|
RedirectUri = "http://www.fabrikam.com/path", |
|
|
|
ResponseType = ResponseTypes.Code |
|
|
|
}); |
|
|
|
|
|
|
|
// Assert
|
|
|
|
Assert.Equal(Errors.InvalidClient, response.Error); |
|
|
|
Assert.Equal(SR.FormatID2054(Parameters.ClientSecret), response.ErrorDescription); |
|
|
|
Assert.Equal(SR.FormatID8000(SR.ID2054), response.ErrorUri); |
|
|
|
|
|
|
|
Mock.Get(manager).Verify(manager => manager.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>()), Times.AtLeastOnce()); |
|
|
|
Mock.Get(manager).Verify(manager => manager.HasClientTypeAsync(application, ClientTypes.Public, It.IsAny<CancellationToken>()), Times.Once()); |
|
|
|
} |
|
|
|
|
|
|
|
[Fact] |
|
|
|
public async Task ValidatePushedAuthorizationRequest_RequestIsRejectedWhenClientCredentialsAreInvalid() |
|
|
|
{ |
|
|
|
// Arrange
|
|
|
|
var application = new OpenIddictApplication(); |
|
|
|
|
|
|
|
var manager = CreateApplicationManager(mock => |
|
|
|
{ |
|
|
|
mock.Setup(manager => manager.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>())) |
|
|
|
.ReturnsAsync(application); |
|
|
|
|
|
|
|
mock.Setup(manager => manager.HasClientTypeAsync(application, ClientTypes.Public, It.IsAny<CancellationToken>())) |
|
|
|
.ReturnsAsync(false); |
|
|
|
|
|
|
|
mock.Setup(manager => manager.ValidateClientSecretAsync(application, "7Fjfp0ZBr1KtDRbnfVdmIw", It.IsAny<CancellationToken>())) |
|
|
|
.ReturnsAsync(false); |
|
|
|
}); |
|
|
|
|
|
|
|
await using var server = await CreateServerAsync(options => |
|
|
|
{ |
|
|
|
options.Services.AddSingleton(manager); |
|
|
|
}); |
|
|
|
|
|
|
|
await using var client = await server.CreateClientAsync(); |
|
|
|
|
|
|
|
// Act
|
|
|
|
var response = await client.PostAsync("/connect/par", new OpenIddictRequest |
|
|
|
{ |
|
|
|
ClientId = "Fabrikam", |
|
|
|
ClientSecret = "7Fjfp0ZBr1KtDRbnfVdmIw", |
|
|
|
RedirectUri = "http://www.fabrikam.com/path", |
|
|
|
ResponseType = ResponseTypes.Code |
|
|
|
}); |
|
|
|
|
|
|
|
// Assert
|
|
|
|
Assert.Equal(Errors.InvalidClient, response.Error); |
|
|
|
Assert.Equal(SR.GetResourceString(SR.ID2055), response.ErrorDescription); |
|
|
|
Assert.Equal(SR.FormatID8000(SR.ID2055), response.ErrorUri); |
|
|
|
|
|
|
|
Mock.Get(manager).Verify(manager => manager.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>()), Times.AtLeastOnce()); |
|
|
|
Mock.Get(manager).Verify(manager => manager.HasClientTypeAsync(application, ClientTypes.Public, It.IsAny<CancellationToken>()), Times.AtLeastOnce()); |
|
|
|
Mock.Get(manager).Verify(manager => manager.ValidateClientSecretAsync(application, "7Fjfp0ZBr1KtDRbnfVdmIw", It.IsAny<CancellationToken>()), Times.Once()); |
|
|
|
} |
|
|
|
|
|
|
|
[Fact] |
|
|
|
public async Task ValidatePushedAuthorizationRequest_MissingRedirectUriCausesAnErrorForOpenIdRequests() |
|
|
|
{ |
|
|
|
@ -4000,7 +4124,7 @@ public abstract partial class OpenIddictServerIntegrationTests |
|
|
|
}); |
|
|
|
|
|
|
|
// Assert
|
|
|
|
Assert.Equal(Errors.InvalidRequest, response.Error); |
|
|
|
Assert.Equal(Errors.InvalidClient, response.Error); |
|
|
|
Assert.Equal(SR.FormatID2052(Parameters.ClientId), response.ErrorDescription); |
|
|
|
Assert.Equal(SR.FormatID8000(SR.ID2052), response.ErrorUri); |
|
|
|
|
|
|
|
@ -4047,6 +4171,9 @@ public abstract partial class OpenIddictServerIntegrationTests |
|
|
|
mock.Setup(manager => manager.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>())) |
|
|
|
.ReturnsAsync(application); |
|
|
|
|
|
|
|
mock.Setup(manager => manager.HasClientTypeAsync(application, ClientTypes.Public, It.IsAny<CancellationToken>())) |
|
|
|
.ReturnsAsync(true); |
|
|
|
|
|
|
|
mock.Setup(manager => manager.ValidateRedirectUriAsync(application, "http://www.fabrikam.com/path", It.IsAny<CancellationToken>())) |
|
|
|
.ReturnsAsync(true); |
|
|
|
|
|
|
|
@ -4088,6 +4215,9 @@ public abstract partial class OpenIddictServerIntegrationTests |
|
|
|
mock.Setup(manager => manager.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>())) |
|
|
|
.ReturnsAsync(application); |
|
|
|
|
|
|
|
mock.Setup(manager => manager.HasClientTypeAsync(application, ClientTypes.Public, It.IsAny<CancellationToken>())) |
|
|
|
.ReturnsAsync(true); |
|
|
|
|
|
|
|
mock.Setup(manager => manager.GetPermissionsAsync(application, It.IsAny<CancellationToken>())) |
|
|
|
.ReturnsAsync(ImmutableArray.Create("rst:" + type)); |
|
|
|
|
|
|
|
@ -4151,6 +4281,9 @@ public abstract partial class OpenIddictServerIntegrationTests |
|
|
|
mock.Setup(manager => manager.HasClientTypeAsync(application, ClientTypes.Confidential, It.IsAny<CancellationToken>())) |
|
|
|
.ReturnsAsync(true); |
|
|
|
|
|
|
|
mock.Setup(manager => manager.ValidateClientSecretAsync(application, "7Fjfp0ZBr1KtDRbnfVdmIw", It.IsAny<CancellationToken>())) |
|
|
|
.ReturnsAsync(true); |
|
|
|
|
|
|
|
mock.Setup(manager => manager.GetPermissionsAsync(application, It.IsAny<CancellationToken>())) |
|
|
|
.ReturnsAsync(ImmutableArray<string>.Empty); |
|
|
|
}); |
|
|
|
@ -4166,6 +4299,7 @@ public abstract partial class OpenIddictServerIntegrationTests |
|
|
|
var response = await client.PostAsync("/connect/par", new OpenIddictRequest |
|
|
|
{ |
|
|
|
ClientId = "Fabrikam", |
|
|
|
ClientSecret = "7Fjfp0ZBr1KtDRbnfVdmIw", |
|
|
|
Nonce = "n-0S6_WzA2Mj", |
|
|
|
RedirectUri = "http://www.fabrikam.com/path", |
|
|
|
ResponseType = type, |
|
|
|
@ -4192,6 +4326,9 @@ public abstract partial class OpenIddictServerIntegrationTests |
|
|
|
mock.Setup(manager => manager.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>())) |
|
|
|
.ReturnsAsync(application); |
|
|
|
|
|
|
|
mock.Setup(manager => manager.HasClientTypeAsync(application, ClientTypes.Public, It.IsAny<CancellationToken>())) |
|
|
|
.ReturnsAsync(true); |
|
|
|
|
|
|
|
mock.Setup(manager => manager.ValidateRedirectUriAsync(application, "http://www.fabrikam.com/path", It.IsAny<CancellationToken>())) |
|
|
|
.ReturnsAsync(true); |
|
|
|
|
|
|
|
@ -4267,6 +4404,9 @@ public abstract partial class OpenIddictServerIntegrationTests |
|
|
|
mock.Setup(manager => manager.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>())) |
|
|
|
.ReturnsAsync(application); |
|
|
|
|
|
|
|
mock.Setup(manager => manager.HasClientTypeAsync(application, ClientTypes.Public, It.IsAny<CancellationToken>())) |
|
|
|
.ReturnsAsync(true); |
|
|
|
|
|
|
|
mock.Setup(manager => manager.ValidateRedirectUriAsync(application, "http://www.fabrikam.com/path", It.IsAny<CancellationToken>())) |
|
|
|
.ReturnsAsync(true); |
|
|
|
|
|
|
|
@ -4324,6 +4464,9 @@ public abstract partial class OpenIddictServerIntegrationTests |
|
|
|
mock.Setup(manager => manager.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>())) |
|
|
|
.ReturnsAsync(application); |
|
|
|
|
|
|
|
mock.Setup(manager => manager.HasClientTypeAsync(application, ClientTypes.Public, It.IsAny<CancellationToken>())) |
|
|
|
.ReturnsAsync(true); |
|
|
|
|
|
|
|
mock.Setup(manager => manager.ValidateRedirectUriAsync(application, "http://www.fabrikam.com/path", It.IsAny<CancellationToken>())) |
|
|
|
.ReturnsAsync(true); |
|
|
|
|
|
|
|
@ -4374,6 +4517,9 @@ public abstract partial class OpenIddictServerIntegrationTests |
|
|
|
mock.Setup(manager => manager.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>())) |
|
|
|
.ReturnsAsync(application); |
|
|
|
|
|
|
|
mock.Setup(manager => manager.HasClientTypeAsync(application, ClientTypes.Public, It.IsAny<CancellationToken>())) |
|
|
|
.ReturnsAsync(true); |
|
|
|
|
|
|
|
mock.Setup(manager => manager.GetPermissionsAsync(application, It.IsAny<CancellationToken>())) |
|
|
|
.ReturnsAsync(ImmutableArray.Create("rst:" + type)); |
|
|
|
|
|
|
|
@ -4431,6 +4577,9 @@ public abstract partial class OpenIddictServerIntegrationTests |
|
|
|
mock.Setup(manager => manager.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>())) |
|
|
|
.ReturnsAsync(application); |
|
|
|
|
|
|
|
mock.Setup(manager => manager.HasClientTypeAsync(application, ClientTypes.Public, It.IsAny<CancellationToken>())) |
|
|
|
.ReturnsAsync(true); |
|
|
|
|
|
|
|
mock.Setup(manager => manager.ValidateRedirectUriAsync(application, "http://www.fabrikam.com/path", It.IsAny<CancellationToken>())) |
|
|
|
.ReturnsAsync(true); |
|
|
|
|
|
|
|
@ -4481,6 +4630,9 @@ public abstract partial class OpenIddictServerIntegrationTests |
|
|
|
mock.Setup(manager => manager.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>())) |
|
|
|
.ReturnsAsync(application); |
|
|
|
|
|
|
|
mock.Setup(manager => manager.HasClientTypeAsync(application, ClientTypes.Public, It.IsAny<CancellationToken>())) |
|
|
|
.ReturnsAsync(true); |
|
|
|
|
|
|
|
mock.Setup(manager => manager.ValidateRedirectUriAsync(application, "http://www.fabrikam.com/path", It.IsAny<CancellationToken>())) |
|
|
|
.ReturnsAsync(false); |
|
|
|
}); |
|
|
|
@ -4520,6 +4672,9 @@ public abstract partial class OpenIddictServerIntegrationTests |
|
|
|
mock.Setup(manager => manager.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>())) |
|
|
|
.ReturnsAsync(application); |
|
|
|
|
|
|
|
mock.Setup(manager => manager.HasClientTypeAsync(application, ClientTypes.Public, It.IsAny<CancellationToken>())) |
|
|
|
.ReturnsAsync(true); |
|
|
|
|
|
|
|
mock.Setup(manager => manager.ValidateRedirectUriAsync(application, "http://www.fabrikam.com/path", It.IsAny<CancellationToken>())) |
|
|
|
.ReturnsAsync(true); |
|
|
|
|
|
|
|
@ -4576,6 +4731,9 @@ public abstract partial class OpenIddictServerIntegrationTests |
|
|
|
mock.Setup(manager => manager.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>())) |
|
|
|
.ReturnsAsync(application); |
|
|
|
|
|
|
|
mock.Setup(manager => manager.HasClientTypeAsync(application, ClientTypes.Public, It.IsAny<CancellationToken>())) |
|
|
|
.ReturnsAsync(true); |
|
|
|
|
|
|
|
mock.Setup(manager => manager.ValidateRedirectUriAsync(application, "http://www.fabrikam.com/path", It.IsAny<CancellationToken>())) |
|
|
|
.ReturnsAsync(true); |
|
|
|
|
|
|
|
@ -4622,6 +4780,9 @@ public abstract partial class OpenIddictServerIntegrationTests |
|
|
|
mock.Setup(manager => manager.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>())) |
|
|
|
.ReturnsAsync(application); |
|
|
|
|
|
|
|
mock.Setup(manager => manager.HasClientTypeAsync(application, ClientTypes.Public, It.IsAny<CancellationToken>())) |
|
|
|
.ReturnsAsync(true); |
|
|
|
|
|
|
|
mock.Setup(manager => manager.ValidateRedirectUriAsync(application, "http://www.fabrikam.com/path", It.IsAny<CancellationToken>())) |
|
|
|
.ReturnsAsync(true); |
|
|
|
|
|
|
|
@ -4676,6 +4837,9 @@ public abstract partial class OpenIddictServerIntegrationTests |
|
|
|
mock.Setup(manager => manager.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>())) |
|
|
|
.ReturnsAsync(application); |
|
|
|
|
|
|
|
mock.Setup(manager => manager.HasClientTypeAsync(application, ClientTypes.Public, It.IsAny<CancellationToken>())) |
|
|
|
.ReturnsAsync(true); |
|
|
|
|
|
|
|
mock.Setup(manager => manager.ValidateRedirectUriAsync(application, "http://www.fabrikam.com/path", It.IsAny<CancellationToken>())) |
|
|
|
.ReturnsAsync(true); |
|
|
|
|
|
|
|
@ -4730,6 +4894,9 @@ public abstract partial class OpenIddictServerIntegrationTests |
|
|
|
mock.Setup(manager => manager.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>())) |
|
|
|
.ReturnsAsync(application); |
|
|
|
|
|
|
|
mock.Setup(manager => manager.HasClientTypeAsync(application, ClientTypes.Public, It.IsAny<CancellationToken>())) |
|
|
|
.ReturnsAsync(true); |
|
|
|
|
|
|
|
mock.Setup(manager => manager.ValidateRedirectUriAsync(application, "http://www.fabrikam.com/path", It.IsAny<CancellationToken>())) |
|
|
|
.ReturnsAsync(true); |
|
|
|
|
|
|
|
@ -4899,6 +5066,9 @@ public abstract partial class OpenIddictServerIntegrationTests |
|
|
|
mock.Setup(manager => manager.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>())) |
|
|
|
.ReturnsAsync(application); |
|
|
|
|
|
|
|
mock.Setup(manager => manager.HasClientTypeAsync(application, ClientTypes.Public, It.IsAny<CancellationToken>())) |
|
|
|
.ReturnsAsync(true); |
|
|
|
|
|
|
|
mock.Setup(manager => manager.ValidateRedirectUriAsync(application, "http://www.fabrikam.com/path", It.IsAny<CancellationToken>())) |
|
|
|
.ReturnsAsync(true); |
|
|
|
|
|
|
|
|