mirror of
https://github.com/DuendeSoftware/products
synced 2026-05-24 09:28:24 +00:00
Merge pull request #2241 from DuendeSoftware/dh/ms-test-platform
Update to XUnit V3 and use the new Microsoft Test Plaform
This commit is contained in:
commit
8cc6df1f2f
127 changed files with 1831 additions and 1928 deletions
|
|
@ -39,7 +39,6 @@
|
|||
<PackageVersion Include="Aspire.Hosting.SqlServer" Version="9.5.0" />
|
||||
<PackageVersion Include="BenchmarkDotNet" Version="0.15.0" />
|
||||
<PackageVersion Include="BullsEye" Version="5.0.0" />
|
||||
<PackageVersion Include="coverlet.collector" Version="6.0.2" />
|
||||
<!-- Added aspire transitive package to resolve package vulnerability -->
|
||||
<PackageVersion Include="KubernetesClient" Version="17.0.14" />
|
||||
<PackageVersion Include="Duende.AccessTokenManagement" Version="3.2.0" Condition="'$(IsBffProject)' == 'true'" />
|
||||
|
|
@ -54,7 +53,7 @@
|
|||
<PackageVersion Include="Duende.IdentityServer" Version="7.1.0" />
|
||||
<PackageVersion Include="Duende.Private.Licensing" Version="1.0.0" />
|
||||
<PackageVersion Include="IdentityModel.AspNetCore.OAuth2Introspection" Version="6.2.0" />
|
||||
<PackageVersion Include="Meziantou.Extensions.Logging.Xunit" Version="1.0.8" />
|
||||
<PackageVersion Include="MartinCostello.Logging.XUnit.v3" Version="0.6.0" />
|
||||
<PackageVersion Include="Microsoft.AspNetCore.Authentication.Certificate" Version="$(AuthenticationCertificateVersion)" />
|
||||
<PackageVersion Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="$(FrameworkVersion)" />
|
||||
<PackageVersion Include="Microsoft.AspNetCore.Authentication.OpenIdConnect" Version="$(FrameworkVersion)" />
|
||||
|
|
@ -98,10 +97,10 @@
|
|||
<PackageVersion Include="Microsoft.IdentityModel.Logging" Version="$(IdentityModelVersion)" />
|
||||
<PackageVersion Include="Microsoft.IdentityModel.Protocols.OpenIdConnect" Version="$(IdentityModelVersion)" />
|
||||
<PackageVersion Include="Microsoft.Net.Http.Headers" Version="9.0.6" />
|
||||
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.12.0" />
|
||||
<PackageVersion Include="Microsoft.NETCore.Jit" Version="2.0.8" />
|
||||
<PackageVersion Include="Microsoft.Playwright.Xunit" Version="1.50.0" />
|
||||
<PackageVersion Include="Microsoft.SourceLink.GitHub" Version="8.0.0" />
|
||||
<PackageVersion Include="Microsoft.Playwright" Version="1.55.0" />
|
||||
<PackageVersion Include="Microsoft.Playwright.Xunit.v3" Version="1.55.0" />
|
||||
<PackageVersion Include="Microsoft.Testing.Platform.MSBuild" Version="1.8.4" />
|
||||
<PackageVersion Include="MinVer" Version="6.0.0" />
|
||||
<PackageVersion Include="NBomber" Version="6.0.2" />
|
||||
<PackageVersion Include="NBomber.Http" Version="6.0.2" />
|
||||
|
|
@ -117,13 +116,13 @@
|
|||
<PackageVersion Include="OpenTelemetry" Version="1.12.0" />
|
||||
<PackageVersion Include="PublicApiGenerator" Version="11.1.0" />
|
||||
<PackageVersion Include="RichardSzalay.MockHttp" Version="7.0.0" />
|
||||
<PackageVersion Include="Serilog" Version="4.2.0" />
|
||||
<PackageVersion Include="Serilog" Version="4.3.0" />
|
||||
<PackageVersion Include="Serilog.AspNetCore" Version="8.0.3" />
|
||||
<PackageVersion Include="Serilog.Sinks.Console" Version="6.0.0" />
|
||||
<PackageVersion Include="Serilog.Sinks.File" Version="7.0.0" />
|
||||
<PackageVersion Include="Serilog.Sinks.OpenTelemetry" Version="4.2.0" />
|
||||
<PackageVersion Include="Serilog.Sinks.TextWriter" Version="3.0.0" />
|
||||
<PackageVersion Include="Serilog.Sinks.XUnit" Version="3.0.19" />
|
||||
<PackageVersion Include="Serilog.Sinks.XUnit3" Version="1.1.0" />
|
||||
<PackageVersion Include="Serilog.Extensions.Logging" Version="9.0.2" />
|
||||
<PackageVersion Include="Shouldly" Version="4.2.1" />
|
||||
<PackageVersion Include="SimpleExec" Version="12.0.0" />
|
||||
|
|
@ -131,10 +130,11 @@
|
|||
<PackageVersion Include="System.Net.Http" Version="4.3.4" />
|
||||
<PackageVersion Include="System.Text.Json" Version="$(SystemTextJsonVersion)" />
|
||||
<PackageVersion Include="System.Text.RegularExpressions" Version="4.3.1" />
|
||||
<PackageVersion Include="xunit.core" Version="2.9.3" />
|
||||
<PackageVersion Include="xunit.runner.visualstudio" Version="2.8.2" />
|
||||
<PackageVersion Include="Xunit.SkippableFact" Version="1.5.23" />
|
||||
<PackageVersion Include="Verify.Xunit" Version="28.9.0" />
|
||||
<PackageVersion Include="xunit.abstractions" Version="2.0.3" />
|
||||
<PackageVersion Include="xunit.v3" Version="3.1.0" />
|
||||
<PackageVersion Include="xunit.v3.core" Version="3.1.0" />
|
||||
<PackageVersion Include="xunit.v3.extensibility.core" Version="3.1.0" />
|
||||
<PackageVersion Include="Verify.XunitV3" Version="31.0.0" />
|
||||
<PackageVersion Include="Vogen" Version="7.0.3" />
|
||||
<PackageVersion Include="Yarp.ReverseProxy" Version="2.1.0" />
|
||||
</ItemGroup>
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>net8.0;net9.0</TargetFrameworks>
|
||||
<TargetFrameworks>net8.0;net9.0;net10</TargetFrameworks>
|
||||
<Nullable>enable</Nullable>
|
||||
<RootNamespace>Duende.AspNetCore.Authentication.JwtBearer</RootNamespace>
|
||||
<AssemblyName>Duende.AspNetCore.Authentication.JwtBearer</AssemblyName>
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>net8.0;net9.0</TargetFrameworks>
|
||||
<TargetFrameworks>net8.0;net9.0;net10</TargetFrameworks>
|
||||
<Nullable>enable</Nullable>
|
||||
<AssemblyName>Duende.AspNetCore.Authentication.JwtBearer.Tests</AssemblyName>
|
||||
<RootNameSpace>Duende.AspNetCore.Authentication.JwtBearer</RootNameSpace>
|
||||
|
|
@ -15,8 +15,8 @@
|
|||
<PackageReference Include="Duende.IdentityServer" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Mvc.Testing" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" VersionOverride="9.0.4" />
|
||||
<PackageReference Include="Meziantou.Extensions.Logging.Xunit" />
|
||||
<PackageReference Include="MartinCostello.Logging.XUnit.v3" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" />
|
||||
<PackageReference Include="Microsoft.Extensions.TimeProvider.Testing" />
|
||||
<PackageReference Include="NSubstitute" />
|
||||
<PackageReference Include="RichardSzalay.MockHttp" />
|
||||
|
|
|
|||
|
|
@ -7,14 +7,15 @@ namespace Duende.AspNetCore.Authentication.JwtBearer.DPoP;
|
|||
|
||||
public class ReplayTests : DPoPProofValidatorTestBase
|
||||
{
|
||||
private readonly CancellationToken _ct = TestContext.Current.CancellationToken;
|
||||
[Fact]
|
||||
[Trait("Category", "Unit")]
|
||||
public async Task replays_detected_in_ValidateReplay_fail()
|
||||
{
|
||||
ReplayCache.Exists(TokenIdHash).Returns(true);
|
||||
ReplayCache.Exists(TokenIdHash, _ct).Returns(true);
|
||||
Result.TokenIdHash = TokenIdHash;
|
||||
|
||||
await ProofValidator.ValidateReplay(Context, Result);
|
||||
await ProofValidator.ValidateReplay(Context, Result, _ct);
|
||||
|
||||
Result.ShouldBeInvalidProofWithDescription("Detected DPoP proof token replay.");
|
||||
}
|
||||
|
|
@ -28,7 +29,7 @@ public class ReplayTests : DPoPProofValidatorTestBase
|
|||
[InlineData(true, true, ClockSkew * 2, ClockSkew * 2)]
|
||||
public async Task new_proof_tokens_are_added_to_replay_cache(bool validateIat, bool validateNonce, int clientClockSkew, int serverClockSkew)
|
||||
{
|
||||
ReplayCache.Exists(TokenIdHash).Returns(false);
|
||||
ReplayCache.Exists(TokenIdHash, _ct).Returns(false);
|
||||
|
||||
Options.ValidationMode = (validateIat && validateNonce) ? ExpirationValidationMode.Both
|
||||
: validateIat ? ExpirationValidationMode.IssuedAt : ExpirationValidationMode.Nonce;
|
||||
|
|
@ -38,7 +39,7 @@ public class ReplayTests : DPoPProofValidatorTestBase
|
|||
|
||||
Result.TokenIdHash = TokenIdHash;
|
||||
|
||||
await ProofValidator.ValidateReplay(Context, Result);
|
||||
await ProofValidator.ValidateReplay(Context, Result, _ct);
|
||||
|
||||
Result.IsError.ShouldBeFalse();
|
||||
var skew = validateIat && validateNonce
|
||||
|
|
@ -47,6 +48,6 @@ public class ReplayTests : DPoPProofValidatorTestBase
|
|||
var expectedExpiration = ProofValidator.TestTimeProvider.GetUtcNow()
|
||||
.Add(TimeSpan.FromSeconds(skew * 2))
|
||||
.Add(TimeSpan.FromSeconds(ValidFor));
|
||||
await ReplayCache.Received().Add(TokenIdHash, expectedExpiration);
|
||||
await ReplayCache.Received().Add(TokenIdHash, expectedExpiration, _ct);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,13 +16,13 @@ using Microsoft.AspNetCore.Builder;
|
|||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.IdentityModel.Tokens;
|
||||
using Microsoft.Net.Http.Headers;
|
||||
using Xunit.Abstractions;
|
||||
|
||||
namespace Duende.AspNetCore.Authentication.JwtBearer;
|
||||
|
||||
public class DPoPIntegrationTests(ITestOutputHelper testOutputHelper)
|
||||
{
|
||||
private Client DPoPOnlyClient = new()
|
||||
private readonly CancellationToken _ct = TestContext.Current.CancellationToken;
|
||||
private readonly Client DPoPOnlyClient = new()
|
||||
{
|
||||
ClientId = "client1",
|
||||
ClientSecrets = [new Secret("secret".ToSha256())],
|
||||
|
|
@ -39,7 +39,7 @@ public class DPoPIntegrationTests(ITestOutputHelper testOutputHelper)
|
|||
{
|
||||
var api = await CreateDPoPApi();
|
||||
|
||||
var result = await api.HttpClient.GetAsync("/");
|
||||
var result = await api.HttpClient.GetAsync("/", _ct);
|
||||
|
||||
result.StatusCode.ShouldBe(HttpStatusCode.Unauthorized);
|
||||
}
|
||||
|
|
@ -52,7 +52,7 @@ public class DPoPIntegrationTests(ITestOutputHelper testOutputHelper)
|
|||
var bearerToken = "unimportant opaque value";
|
||||
api.HttpClient.SetBearerToken(bearerToken);
|
||||
|
||||
var result = await api.HttpClient.GetAsync("/");
|
||||
var result = await api.HttpClient.GetAsync("/", _ct);
|
||||
|
||||
result.StatusCode.ShouldBe(HttpStatusCode.Unauthorized);
|
||||
}
|
||||
|
|
@ -72,8 +72,8 @@ public class DPoPIntegrationTests(ITestOutputHelper testOutputHelper)
|
|||
|
||||
// Login and get token for api call
|
||||
await app.LoginAsync("sub");
|
||||
var response = await app.BrowserClient.GetAsync(app.Url("/user_token"));
|
||||
var token = await response.Content.ReadFromJsonAsync<UserToken>();
|
||||
var response = await app.BrowserClient.GetAsync(app.Url("/user_token"), _ct);
|
||||
var token = await response.Content.ReadFromJsonAsync<UserToken>(_ct);
|
||||
token.ShouldNotBeNull();
|
||||
token.AccessToken.ToString().ShouldNotBeNull();
|
||||
token.DPoPJsonWebKey.ShouldNotBeNull();
|
||||
|
|
@ -87,11 +87,11 @@ public class DPoPIntegrationTests(ITestOutputHelper testOutputHelper)
|
|||
DPoPProofKey = jwk,
|
||||
Method = HttpMethod.Get,
|
||||
Url = new Uri("http://localhost/")
|
||||
});
|
||||
}, _ct);
|
||||
proof.ShouldNotBeNull();
|
||||
api.HttpClient.DefaultRequestHeaders.Add(OidcConstants.HttpHeaders.DPoP, [proof.Value, proof.Value]);
|
||||
|
||||
var result = await api.HttpClient.GetAsync("/");
|
||||
var result = await api.HttpClient.GetAsync("/", _ct);
|
||||
|
||||
result.StatusCode.ShouldBe(HttpStatusCode.Unauthorized);
|
||||
var error = result.Headers.GetValues(HeaderNames.WWWAuthenticate).FirstOrDefault();
|
||||
|
|
@ -117,8 +117,8 @@ public class DPoPIntegrationTests(ITestOutputHelper testOutputHelper)
|
|||
|
||||
// Login and get token for api call
|
||||
await app.LoginAsync("sub");
|
||||
var response = await app.BrowserClient.GetAsync(app.Url("/user_token"));
|
||||
var token = await response.Content.ReadFromJsonAsync<UserToken>();
|
||||
var response = await app.BrowserClient.GetAsync(app.Url("/user_token"), _ct);
|
||||
var token = await response.Content.ReadFromJsonAsync<UserToken>(_ct);
|
||||
token.ShouldNotBeNull();
|
||||
token.AccessToken.ToString().ShouldNotBeNull();
|
||||
token.DPoPJsonWebKey.ShouldNotBeNull();
|
||||
|
|
@ -132,11 +132,11 @@ public class DPoPIntegrationTests(ITestOutputHelper testOutputHelper)
|
|||
DPoPProofKey = jwk,
|
||||
Method = HttpMethod.Get,
|
||||
Url = new Uri("http://localhost/")
|
||||
});
|
||||
}, _ct);
|
||||
proof.ShouldNotBeNull();
|
||||
api.HttpClient.DefaultRequestHeaders.Add(OidcConstants.HttpHeaders.DPoP, proof.Value);
|
||||
|
||||
var result = await api.HttpClient.GetAsync("/");
|
||||
var result = await api.HttpClient.GetAsync("/", _ct);
|
||||
|
||||
result.StatusCode.ShouldBe(HttpStatusCode.OK);
|
||||
}
|
||||
|
|
@ -156,14 +156,14 @@ public class DPoPIntegrationTests(ITestOutputHelper testOutputHelper)
|
|||
|
||||
// Login and get token for api call
|
||||
await app.LoginAsync("sub");
|
||||
var response = await app.BrowserClient.GetAsync(app.Url("/user_token"));
|
||||
var token = await response.Content.ReadFromJsonAsync<UserToken>();
|
||||
var response = await app.BrowserClient.GetAsync(app.Url("/user_token"), _ct);
|
||||
var token = await response.Content.ReadFromJsonAsync<UserToken>(_ct);
|
||||
token.ShouldNotBeNull();
|
||||
token.AccessToken.ToString().ShouldNotBeNull();
|
||||
token.DPoPJsonWebKey.ShouldNotBeNull();
|
||||
api.HttpClient.SetToken("DPoP", token.AccessToken);
|
||||
|
||||
var result = await api.HttpClient.GetAsync("/");
|
||||
var result = await api.HttpClient.GetAsync("/", _ct);
|
||||
|
||||
result.StatusCode.ShouldBe(HttpStatusCode.Unauthorized);
|
||||
var error = result.Headers.GetValues(HeaderNames.WWWAuthenticate).FirstOrDefault();
|
||||
|
|
@ -189,8 +189,8 @@ public class DPoPIntegrationTests(ITestOutputHelper testOutputHelper)
|
|||
|
||||
// Login and get token for api call
|
||||
await app.LoginAsync("sub");
|
||||
var response = await app.BrowserClient.GetAsync(app.Url("/user_token"));
|
||||
var token = await response.Content.ReadFromJsonAsync<UserToken>();
|
||||
var response = await app.BrowserClient.GetAsync(app.Url("/user_token"), _ct);
|
||||
var token = await response.Content.ReadFromJsonAsync<UserToken>(_ct);
|
||||
token.ShouldNotBeNull();
|
||||
token.AccessToken.ToString().ShouldNotBeNull();
|
||||
token.DPoPJsonWebKey.ShouldNotBeNull();
|
||||
|
|
@ -205,11 +205,11 @@ public class DPoPIntegrationTests(ITestOutputHelper testOutputHelper)
|
|||
Method = HttpMethod.Get,
|
||||
Url = new Uri("http://localhost/"),
|
||||
DPoPNonce = DPoPNonce.Parse(new string('x', maxLength + 1)) // <--- Most important part of the test
|
||||
});
|
||||
}, _ct);
|
||||
proof.ShouldNotBeNull();
|
||||
api.HttpClient.DefaultRequestHeaders.Add(OidcConstants.HttpHeaders.DPoP, proof.Value);
|
||||
|
||||
var result = await api.HttpClient.GetAsync("/");
|
||||
var result = await api.HttpClient.GetAsync("/", _ct);
|
||||
|
||||
result.StatusCode.ShouldBe(HttpStatusCode.Unauthorized);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@
|
|||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Xunit.Abstractions;
|
||||
|
||||
namespace Duende.AspNetCore.TestFramework;
|
||||
|
||||
|
|
|
|||
|
|
@ -11,7 +11,6 @@ using Microsoft.AspNetCore.Builder;
|
|||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using RichardSzalay.MockHttp;
|
||||
using Xunit.Abstractions;
|
||||
|
||||
namespace Duende.AspNetCore.TestFramework;
|
||||
|
||||
|
|
|
|||
|
|
@ -4,18 +4,29 @@
|
|||
using System.Net;
|
||||
using System.Reflection;
|
||||
using System.Security.Claims;
|
||||
using Meziantou.Extensions.Logging.Xunit;
|
||||
using Microsoft.AspNetCore.Authentication;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.TestHost;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Xunit.Abstractions;
|
||||
|
||||
namespace Duende.AspNetCore.TestFramework;
|
||||
|
||||
public class GenericHost
|
||||
{
|
||||
protected readonly string _baseAddress;
|
||||
|
||||
private readonly ITestOutputHelper _testOutputHelper;
|
||||
private IServiceProvider _appServices = default!;
|
||||
|
||||
private TestBrowserClient? _browserClient;
|
||||
|
||||
private HttpClient? _httpClient;
|
||||
private AuthenticationProperties? _propsToSignIn;
|
||||
private TestServer? _server;
|
||||
|
||||
private ClaimsPrincipal? _userToSignIn;
|
||||
|
||||
public GenericHost(ITestOutputHelper testOutputHelper, string baseAddress = "https://server")
|
||||
{
|
||||
if (baseAddress.EndsWith("/"))
|
||||
|
|
@ -27,20 +38,16 @@ public class GenericHost
|
|||
_testOutputHelper = testOutputHelper;
|
||||
}
|
||||
|
||||
protected readonly string _baseAddress;
|
||||
private IServiceProvider _appServices = default!;
|
||||
|
||||
public Assembly? HostAssembly { get; set; }
|
||||
public bool IsDevelopment { get; set; }
|
||||
private TestServer? _server;
|
||||
|
||||
public TestServer Server
|
||||
{
|
||||
get => _server ?? throw new InvalidOperationException(
|
||||
$"Attempt to use {nameof(Server)} before it was initialized. Did you forget to call ${Initialize}?");
|
||||
$"Attempt to use {nameof(Server)} before it was initialized. Did you forget to call {nameof(Initialize)}");
|
||||
private set => _server = value;
|
||||
}
|
||||
|
||||
private TestBrowserClient? _browserClient;
|
||||
public TestBrowserClient BrowserClient
|
||||
{
|
||||
get =>
|
||||
|
|
@ -49,7 +56,6 @@ public class GenericHost
|
|||
private set => _browserClient = value;
|
||||
}
|
||||
|
||||
private HttpClient? _httpClient;
|
||||
public HttpClient HttpClient
|
||||
{
|
||||
get =>
|
||||
|
|
@ -58,17 +64,9 @@ public class GenericHost
|
|||
private set => _httpClient = value;
|
||||
}
|
||||
|
||||
private readonly ITestOutputHelper _testOutputHelper;
|
||||
|
||||
public T Resolve<T>()
|
||||
where T : notnull =>
|
||||
// not calling dispose on scope on purpose
|
||||
_appServices.GetRequiredService<IServiceScopeFactory>().CreateScope().ServiceProvider
|
||||
.GetRequiredService<T>();
|
||||
|
||||
public string Url(string? path = null)
|
||||
{
|
||||
path = path ?? string.Empty;
|
||||
path ??= string.Empty;
|
||||
if (!path.StartsWith("/"))
|
||||
{
|
||||
path = "/" + path;
|
||||
|
|
@ -104,7 +102,7 @@ public class GenericHost
|
|||
private void ConfigureServices(IServiceCollection services)
|
||||
{
|
||||
// This adds log messages to the output of our tests when they fail.
|
||||
// See https://www.meziantou.net/how-to-view-logs-from-ilogger-in-xunitdotnet.htm
|
||||
// See https://github.com/martincostello/xunit-logging
|
||||
services.AddLogging(options =>
|
||||
{
|
||||
// If you need different log output to understand a test failure, configure it here
|
||||
|
|
@ -113,10 +111,7 @@ public class GenericHost
|
|||
options.AddFilter("Duende.IdentityServer.License", LogLevel.Error);
|
||||
options.AddFilter("Duende.IdentityServer.Startup", LogLevel.Error);
|
||||
|
||||
options.AddProvider(new XUnitLoggerProvider(_testOutputHelper, new XUnitLoggerOptions
|
||||
{
|
||||
IncludeCategory = true,
|
||||
}));
|
||||
options.AddXUnit(_testOutputHelper);
|
||||
});
|
||||
|
||||
OnConfigureServices(services);
|
||||
|
|
@ -131,48 +126,41 @@ public class GenericHost
|
|||
ConfigureSignout(builder);
|
||||
}
|
||||
|
||||
private void ConfigureSignout(WebApplication app) => app.Use(async (ctx, next) =>
|
||||
{
|
||||
if (ctx.Request.Path == "/__signout")
|
||||
{
|
||||
await ctx.SignOutAsync();
|
||||
ctx.Response.StatusCode = 204;
|
||||
return;
|
||||
}
|
||||
private void ConfigureSignout(WebApplication app) =>
|
||||
app.Use(async (ctx, next) =>
|
||||
{
|
||||
if (ctx.Request.Path == "/__signout")
|
||||
{
|
||||
await ctx.SignOutAsync();
|
||||
ctx.Response.StatusCode = 204;
|
||||
return;
|
||||
}
|
||||
|
||||
await next();
|
||||
});
|
||||
await next();
|
||||
});
|
||||
|
||||
public async Task RevokeSessionCookieAsync()
|
||||
{
|
||||
var response = await BrowserClient.GetAsync(Url("__signout"));
|
||||
response.StatusCode.ShouldBe((HttpStatusCode)204);
|
||||
}
|
||||
private void ConfigureSignin(WebApplication app) =>
|
||||
app.Use(async (ctx, next) =>
|
||||
{
|
||||
if (ctx.Request.Path == "/__signin")
|
||||
{
|
||||
if (_userToSignIn is not object)
|
||||
{
|
||||
throw new Exception("No User Configured for SignIn");
|
||||
}
|
||||
|
||||
private void ConfigureSignin(WebApplication app) => app.Use(async (ctx, next) =>
|
||||
{
|
||||
if (ctx.Request.Path == "/__signin")
|
||||
{
|
||||
if (_userToSignIn is not object)
|
||||
{
|
||||
throw new Exception("No User Configured for SignIn");
|
||||
}
|
||||
var props = _propsToSignIn ?? new AuthenticationProperties();
|
||||
await ctx.SignInAsync(_userToSignIn, props);
|
||||
|
||||
var props = _propsToSignIn ?? new AuthenticationProperties();
|
||||
await ctx.SignInAsync(_userToSignIn, props);
|
||||
_userToSignIn = null;
|
||||
_propsToSignIn = null;
|
||||
|
||||
_userToSignIn = null;
|
||||
_propsToSignIn = null;
|
||||
ctx.Response.StatusCode = 204;
|
||||
return;
|
||||
}
|
||||
|
||||
ctx.Response.StatusCode = 204;
|
||||
return;
|
||||
}
|
||||
|
||||
await next();
|
||||
});
|
||||
|
||||
private ClaimsPrincipal? _userToSignIn;
|
||||
private AuthenticationProperties? _propsToSignIn;
|
||||
await next();
|
||||
});
|
||||
|
||||
public async Task IssueSessionCookieAsync(params Claim[] claims)
|
||||
{
|
||||
|
|
@ -180,10 +168,10 @@ public class GenericHost
|
|||
var response = await BrowserClient.GetAsync(Url("__signin"));
|
||||
response.StatusCode.ShouldBe((HttpStatusCode)204);
|
||||
}
|
||||
|
||||
public Task IssueSessionCookieAsync(AuthenticationProperties props, params Claim[] claims)
|
||||
{
|
||||
_propsToSignIn = props;
|
||||
return IssueSessionCookieAsync(claims);
|
||||
}
|
||||
public Task IssueSessionCookieAsync(string sub, params Claim[] claims) => IssueSessionCookieAsync(claims.Append(new Claim("sub", sub)).ToArray());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,7 +9,6 @@ using Microsoft.AspNetCore.Builder;
|
|||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.IdentityModel.JsonWebTokens;
|
||||
using Microsoft.IdentityModel.Tokens;
|
||||
using Xunit.Abstractions;
|
||||
|
||||
namespace Duende.AspNetCore.TestFramework;
|
||||
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@
|
|||
<PackageReference Include="Microsoft.Extensions.TimeProvider.Testing" />
|
||||
<PackageReference Include="NSubstitute" />
|
||||
<PackageReference Include="PublicApiGenerator" />
|
||||
<PackageReference Include="Verify.Xunit" />
|
||||
<PackageReference Include="Verify.XunitV3" />
|
||||
|
||||
</ItemGroup>
|
||||
|
||||
|
|
|
|||
|
|
@ -3,28 +3,16 @@
|
|||
<PropertyGroup>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
|
||||
<IsPackable>false</IsPackable>
|
||||
<IsTestProject>true</IsTestProject>
|
||||
<TreatWarningsAsErrors>True</TreatWarningsAsErrors>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="NSubstitute" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.Server" />
|
||||
<PackageReference Include="PublicApiGenerator" />
|
||||
<PackageReference Include="Verify.Xunit" />
|
||||
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Using Include="Xunit" />
|
||||
|
||||
<PackageReference Include="Verify.XunitV3" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
|
@ -32,4 +20,8 @@
|
|||
<ProjectReference Include="..\Bff.Tests\Bff.Tests.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Using Include="Xunit" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
|
|||
|
|
@ -6,24 +6,24 @@ using Duende.Bff;
|
|||
using Duende.Bff.Tests.TestHosts;
|
||||
using Duende.IdentityServer.Models;
|
||||
using Duende.IdentityServer.Services;
|
||||
using Xunit.Abstractions;
|
||||
|
||||
namespace Bff.Blazor.UnitTests;
|
||||
|
||||
public class BffBlazorTests : OutputWritingTestBase
|
||||
{
|
||||
protected readonly IdentityServerHost IdentityServerHost;
|
||||
protected ApiHost ApiHost;
|
||||
protected BffBlazorHost BffHost;
|
||||
private readonly CancellationToken _ct = TestContext.Current.CancellationToken;
|
||||
private readonly IdentityServerHost _identityServerHost;
|
||||
private readonly ApiHost _apiHost;
|
||||
private readonly BffBlazorHost _bffHost;
|
||||
|
||||
public BffBlazorTests(ITestOutputHelper testOutputHelper) : base(testOutputHelper)
|
||||
{
|
||||
IdentityServerHost = new IdentityServerHost(WriteLine);
|
||||
ApiHost = new ApiHost(WriteLine, IdentityServerHost, "scope1");
|
||||
_identityServerHost = new IdentityServerHost(WriteLine);
|
||||
_apiHost = new ApiHost(WriteLine, _identityServerHost, "scope1");
|
||||
|
||||
BffHost = new BffBlazorHost(WriteLine, IdentityServerHost, ApiHost, "spa");
|
||||
_bffHost = new BffBlazorHost(WriteLine, _identityServerHost, _apiHost, "spa");
|
||||
|
||||
IdentityServerHost.Clients.Add(new Client
|
||||
_identityServerHost.Clients.Add(new Client
|
||||
{
|
||||
ClientId = "spa",
|
||||
ClientSecrets = { new Secret("secret".Sha256()) },
|
||||
|
|
@ -37,11 +37,11 @@ public class BffBlazorTests : OutputWritingTestBase
|
|||
|
||||
|
||||
|
||||
IdentityServerHost.OnConfigureServices += services =>
|
||||
_identityServerHost.OnConfigureServices += services =>
|
||||
{
|
||||
services.AddTransient<IBackChannelLogoutHttpClient>(provider =>
|
||||
new DefaultBackChannelLogoutHttpClient(
|
||||
BffHost!.HttpClient,
|
||||
_bffHost!.HttpClient,
|
||||
provider.GetRequiredService<ILoggerFactory>(),
|
||||
provider.GetRequiredService<ICancellationTokenProvider>()));
|
||||
|
||||
|
|
@ -52,38 +52,38 @@ public class BffBlazorTests : OutputWritingTestBase
|
|||
[Fact]
|
||||
public async Task Can_get_home()
|
||||
{
|
||||
var response = await BffHost.BrowserClient.GetAsync("/");
|
||||
var response = await _bffHost.BrowserClient.GetAsync("/", _ct);
|
||||
response.StatusCode.ShouldBe(HttpStatusCode.OK);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Cannot_get_secure_without_loggin_in()
|
||||
public async Task Cannot_get_secure_without_logging_in()
|
||||
{
|
||||
var response = await BffHost.BrowserClient.GetAsync("/secure");
|
||||
var response = await _bffHost.BrowserClient.GetAsync("/secure", _ct);
|
||||
response.StatusCode.ShouldBe(HttpStatusCode.Found, "this indicates we are redirecting to the login page");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Can_get_secure_when_logged_in()
|
||||
{
|
||||
await BffHost.BffLoginAsync("sub");
|
||||
var response = await BffHost.BrowserClient.GetAsync("/secure");
|
||||
await _bffHost.BffLoginAsync("sub");
|
||||
var response = await _bffHost.BrowserClient.GetAsync("/secure", _ct);
|
||||
response.StatusCode.ShouldBe(HttpStatusCode.OK);
|
||||
}
|
||||
|
||||
public override async Task InitializeAsync()
|
||||
public override async ValueTask InitializeAsync()
|
||||
{
|
||||
await IdentityServerHost.InitializeAsync();
|
||||
await ApiHost.InitializeAsync();
|
||||
await BffHost.InitializeAsync();
|
||||
await _identityServerHost.InitializeAsync();
|
||||
await _apiHost.InitializeAsync();
|
||||
await _bffHost.InitializeAsync();
|
||||
await base.InitializeAsync();
|
||||
}
|
||||
|
||||
public override async Task DisposeAsync()
|
||||
public override async ValueTask DisposeAsync()
|
||||
{
|
||||
await ApiHost.DisposeAsync();
|
||||
await BffHost.DisposeAsync();
|
||||
await IdentityServerHost.DisposeAsync();
|
||||
await _apiHost.DisposeAsync();
|
||||
await _bffHost.DisposeAsync();
|
||||
await _identityServerHost.DisposeAsync();
|
||||
await base.DisposeAsync();
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,8 +7,9 @@
|
|||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.InMemory" />
|
||||
<PackageReference Include="PublicApiGenerator" />
|
||||
<PackageReference Include="Verify.Xunit" />
|
||||
<PackageReference Include="Verify.XunitV3" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\src\Bff.EntityFramework\Bff.EntityFramework.csproj" />
|
||||
</ItemGroup>
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ namespace Duende.Bff.EntityFramework.Tests;
|
|||
|
||||
public class UserSessionStoreTests
|
||||
{
|
||||
private readonly CancellationToken _ct = TestContext.Current.CancellationToken;
|
||||
private readonly IUserSessionStore _subject;
|
||||
private readonly SessionDbContext _database;
|
||||
|
||||
|
|
@ -37,7 +38,7 @@ public class UserSessionStoreTests
|
|||
Renewed = new DateTime(2021, 4, 2, 10, 13, 34, DateTimeKind.Utc),
|
||||
Expires = new DateTime(2022, 5, 3, 11, 14, 35, DateTimeKind.Utc),
|
||||
Ticket = "ticket"
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
_database.UserSessions.Count().ShouldBe(1);
|
||||
}
|
||||
|
|
@ -55,9 +56,9 @@ public class UserSessionStoreTests
|
|||
Renewed = new DateTime(2021, 4, 2, 10, 13, 34, DateTimeKind.Utc),
|
||||
Expires = new DateTime(2022, 5, 3, 11, 14, 35, DateTimeKind.Utc),
|
||||
Ticket = "ticket"
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
var item = await _subject.GetUserSessionAsync("key123");
|
||||
var item = await _subject.GetUserSessionAsync("key123", _ct);
|
||||
|
||||
item.ShouldNotBeNull();
|
||||
item.Key.ShouldBe("key123");
|
||||
|
|
@ -71,7 +72,7 @@ public class UserSessionStoreTests
|
|||
[Fact]
|
||||
public async Task GetUserSessionAsync_for_invalid_key_should_return_null()
|
||||
{
|
||||
var item = await _subject.GetUserSessionAsync("invalid");
|
||||
var item = await _subject.GetUserSessionAsync("invalid", _ct);
|
||||
item.ShouldBeNull();
|
||||
}
|
||||
|
||||
|
|
@ -88,7 +89,7 @@ public class UserSessionStoreTests
|
|||
Renewed = new DateTime(2021, 4, 2, 10, 13, 34, DateTimeKind.Utc),
|
||||
Expires = new DateTime(2022, 5, 3, 11, 14, 35, DateTimeKind.Utc),
|
||||
Ticket = "ticket"
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
{
|
||||
await _subject.UpdateUserSessionAsync("key123", new UserSessionUpdate
|
||||
|
|
@ -99,9 +100,9 @@ public class UserSessionStoreTests
|
|||
Created = new DateTime(2020, 3, 1, 9, 12, 33, DateTimeKind.Utc),
|
||||
Renewed = new DateTime(2024, 1, 3, 5, 7, 9, DateTimeKind.Utc),
|
||||
Expires = new DateTime(2025, 2, 4, 6, 8, 10, DateTimeKind.Utc)
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
var item = await _subject.GetUserSessionAsync("key123");
|
||||
var item = await _subject.GetUserSessionAsync("key123", _ct);
|
||||
item.ShouldNotBeNull();
|
||||
item.Key.ShouldBe("key123");
|
||||
item.SubjectId.ShouldBe("sub");
|
||||
|
|
@ -120,9 +121,9 @@ public class UserSessionStoreTests
|
|||
Created = new DateTime(2022, 3, 1, 9, 12, 33, DateTimeKind.Utc),
|
||||
Renewed = new DateTime(2024, 1, 3, 5, 7, 9, DateTimeKind.Utc),
|
||||
Expires = new DateTime(2025, 2, 4, 6, 8, 10, DateTimeKind.Utc)
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
var item = await _subject.GetUserSessionAsync("key123");
|
||||
var item = await _subject.GetUserSessionAsync("key123", _ct);
|
||||
item.ShouldNotBeNull();
|
||||
item.Key.ShouldBe("key123");
|
||||
item.SubjectId.ShouldBe("sub2");
|
||||
|
|
@ -141,9 +142,9 @@ public class UserSessionStoreTests
|
|||
Ticket = "ticket2",
|
||||
Renewed = new DateTime(2024, 1, 3, 5, 7, 9, DateTimeKind.Utc),
|
||||
Expires = new DateTime(2025, 2, 4, 6, 8, 10, DateTimeKind.Utc)
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
var item = await _subject.GetUserSessionAsync("key123");
|
||||
var item = await _subject.GetUserSessionAsync("key123", _ct);
|
||||
item.ShouldBeNull();
|
||||
}
|
||||
|
||||
|
|
@ -157,15 +158,16 @@ public class UserSessionStoreTests
|
|||
SubjectId = "sub",
|
||||
SessionId = "session",
|
||||
Ticket = "ticket",
|
||||
});
|
||||
}, _ct);
|
||||
_database.UserSessions.Count().ShouldBe(1);
|
||||
|
||||
await _subject.DeleteUserSessionAsync("key123");
|
||||
await _subject.DeleteUserSessionAsync("key123", _ct);
|
||||
|
||||
_database.UserSessions.Count().ShouldBe(0);
|
||||
}
|
||||
[Fact]
|
||||
public async Task DeleteUserSessionAsync_for_invalid_key_should_succeed() => await _subject.DeleteUserSessionAsync("invalid");
|
||||
public async Task DeleteUserSessionAsync_for_invalid_key_should_succeed()
|
||||
=> await _subject.DeleteUserSessionAsync("invalid", _ct);
|
||||
|
||||
|
||||
[Fact]
|
||||
|
|
@ -177,44 +179,44 @@ public class UserSessionStoreTests
|
|||
Ticket = "ticket",
|
||||
SubjectId = "sub1",
|
||||
SessionId = "sid1_1",
|
||||
});
|
||||
}, _ct);
|
||||
await _subject.CreateUserSessionAsync(new UserSession
|
||||
{
|
||||
Key = Guid.NewGuid().ToString(),
|
||||
Ticket = "ticket",
|
||||
SubjectId = "sub1",
|
||||
SessionId = "sid1_2",
|
||||
});
|
||||
}, _ct);
|
||||
await _subject.CreateUserSessionAsync(new UserSession
|
||||
{
|
||||
Key = Guid.NewGuid().ToString(),
|
||||
Ticket = "ticket",
|
||||
SubjectId = "sub2",
|
||||
SessionId = "sid2_1",
|
||||
});
|
||||
}, _ct);
|
||||
await _subject.CreateUserSessionAsync(new UserSession
|
||||
{
|
||||
Key = Guid.NewGuid().ToString(),
|
||||
Ticket = "ticket",
|
||||
SubjectId = "sub2",
|
||||
SessionId = "sid2_2",
|
||||
});
|
||||
}, _ct);
|
||||
await _subject.CreateUserSessionAsync(new UserSession
|
||||
{
|
||||
Key = Guid.NewGuid().ToString(),
|
||||
Ticket = "ticket",
|
||||
SubjectId = "sub2",
|
||||
SessionId = "sid2_3",
|
||||
});
|
||||
}, _ct);
|
||||
await _subject.CreateUserSessionAsync(new UserSession
|
||||
{
|
||||
Key = Guid.NewGuid().ToString(),
|
||||
Ticket = "ticket",
|
||||
SubjectId = "sub3",
|
||||
SessionId = "sid3_1",
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
var items = await _subject.GetUserSessionsAsync(new UserSessionsFilter { SubjectId = "sub2" });
|
||||
var items = await _subject.GetUserSessionsAsync(new UserSessionsFilter { SubjectId = "sub2" }, _ct);
|
||||
items.Count().ShouldBe(3);
|
||||
items.Select(x => x.SubjectId).Distinct().ToArray().ShouldBeEquivalentTo(new[] { "sub2" });
|
||||
items.Select(x => x.SessionId).ToArray().ShouldBeEquivalentTo(new[] { "sid2_1", "sid2_2", "sid2_3", });
|
||||
|
|
@ -228,44 +230,44 @@ public class UserSessionStoreTests
|
|||
Ticket = "ticket",
|
||||
SubjectId = "sub1",
|
||||
SessionId = "sid1_1",
|
||||
});
|
||||
}, _ct);
|
||||
await _subject.CreateUserSessionAsync(new UserSession
|
||||
{
|
||||
Key = Guid.NewGuid().ToString(),
|
||||
Ticket = "ticket",
|
||||
SubjectId = "sub1",
|
||||
SessionId = "sid1_2",
|
||||
});
|
||||
}, _ct);
|
||||
await _subject.CreateUserSessionAsync(new UserSession
|
||||
{
|
||||
Key = Guid.NewGuid().ToString(),
|
||||
Ticket = "ticket",
|
||||
SubjectId = "sub2",
|
||||
SessionId = "sid2_1",
|
||||
});
|
||||
}, _ct);
|
||||
await _subject.CreateUserSessionAsync(new UserSession
|
||||
{
|
||||
Key = Guid.NewGuid().ToString(),
|
||||
Ticket = "ticket",
|
||||
SubjectId = "sub2",
|
||||
SessionId = "sid2_2",
|
||||
});
|
||||
}, _ct);
|
||||
await _subject.CreateUserSessionAsync(new UserSession
|
||||
{
|
||||
Key = Guid.NewGuid().ToString(),
|
||||
Ticket = "ticket",
|
||||
SubjectId = "sub2",
|
||||
SessionId = "sid2_3",
|
||||
});
|
||||
}, _ct);
|
||||
await _subject.CreateUserSessionAsync(new UserSession
|
||||
{
|
||||
Key = Guid.NewGuid().ToString(),
|
||||
Ticket = "ticket",
|
||||
SubjectId = "sub3",
|
||||
SessionId = "sid3_1",
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
var items = await _subject.GetUserSessionsAsync(new UserSessionsFilter { SubjectId = "invalid" });
|
||||
var items = await _subject.GetUserSessionsAsync(new UserSessionsFilter { SubjectId = "invalid" }, _ct);
|
||||
items.Count().ShouldBe(0);
|
||||
}
|
||||
[Fact]
|
||||
|
|
@ -277,44 +279,44 @@ public class UserSessionStoreTests
|
|||
Ticket = "ticket",
|
||||
SubjectId = "sub1",
|
||||
SessionId = "sid1_1",
|
||||
});
|
||||
}, _ct);
|
||||
await _subject.CreateUserSessionAsync(new UserSession
|
||||
{
|
||||
Key = Guid.NewGuid().ToString(),
|
||||
Ticket = "ticket",
|
||||
SubjectId = "sub1",
|
||||
SessionId = "sid1_2",
|
||||
});
|
||||
}, _ct);
|
||||
await _subject.CreateUserSessionAsync(new UserSession
|
||||
{
|
||||
Key = Guid.NewGuid().ToString(),
|
||||
Ticket = "ticket",
|
||||
SubjectId = "sub2",
|
||||
SessionId = "sid2_1",
|
||||
});
|
||||
}, _ct);
|
||||
await _subject.CreateUserSessionAsync(new UserSession
|
||||
{
|
||||
Key = Guid.NewGuid().ToString(),
|
||||
Ticket = "ticket",
|
||||
SubjectId = "sub2",
|
||||
SessionId = "sid2_2",
|
||||
});
|
||||
}, _ct);
|
||||
await _subject.CreateUserSessionAsync(new UserSession
|
||||
{
|
||||
Key = Guid.NewGuid().ToString(),
|
||||
Ticket = "ticket",
|
||||
SubjectId = "sub2",
|
||||
SessionId = "sid2_3",
|
||||
});
|
||||
}, _ct);
|
||||
await _subject.CreateUserSessionAsync(new UserSession
|
||||
{
|
||||
Key = Guid.NewGuid().ToString(),
|
||||
Ticket = "ticket",
|
||||
SubjectId = "sub3",
|
||||
SessionId = "sid3_1",
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
var items = await _subject.GetUserSessionsAsync(new UserSessionsFilter { SessionId = "sid2_2" });
|
||||
var items = await _subject.GetUserSessionsAsync(new UserSessionsFilter { SessionId = "sid2_2" }, _ct);
|
||||
items.Count().ShouldBe(1);
|
||||
items.Select(x => x.SubjectId).ToArray().ShouldBeEquivalentTo(new[] { "sub2" });
|
||||
items.Select(x => x.SessionId).ToArray().ShouldBeEquivalentTo(new[] { "sid2_2" });
|
||||
|
|
@ -328,44 +330,44 @@ public class UserSessionStoreTests
|
|||
Ticket = "ticket",
|
||||
SubjectId = "sub1",
|
||||
SessionId = "sid1_1",
|
||||
});
|
||||
}, _ct);
|
||||
await _subject.CreateUserSessionAsync(new UserSession
|
||||
{
|
||||
Key = Guid.NewGuid().ToString(),
|
||||
Ticket = "ticket",
|
||||
SubjectId = "sub1",
|
||||
SessionId = "sid1_2",
|
||||
});
|
||||
}, _ct);
|
||||
await _subject.CreateUserSessionAsync(new UserSession
|
||||
{
|
||||
Key = Guid.NewGuid().ToString(),
|
||||
Ticket = "ticket",
|
||||
SubjectId = "sub2",
|
||||
SessionId = "sid2_1",
|
||||
});
|
||||
}, _ct);
|
||||
await _subject.CreateUserSessionAsync(new UserSession
|
||||
{
|
||||
Key = Guid.NewGuid().ToString(),
|
||||
Ticket = "ticket",
|
||||
SubjectId = "sub2",
|
||||
SessionId = "sid2_2",
|
||||
});
|
||||
}, _ct);
|
||||
await _subject.CreateUserSessionAsync(new UserSession
|
||||
{
|
||||
Key = Guid.NewGuid().ToString(),
|
||||
Ticket = "ticket",
|
||||
SubjectId = "sub2",
|
||||
SessionId = "sid2_3",
|
||||
});
|
||||
}, _ct);
|
||||
await _subject.CreateUserSessionAsync(new UserSession
|
||||
{
|
||||
Key = Guid.NewGuid().ToString(),
|
||||
Ticket = "ticket",
|
||||
SubjectId = "sub3",
|
||||
SessionId = "sid3_1",
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
var items = await _subject.GetUserSessionsAsync(new UserSessionsFilter { SessionId = "invalid" });
|
||||
var items = await _subject.GetUserSessionsAsync(new UserSessionsFilter { SessionId = "invalid" }, _ct);
|
||||
items.Count().ShouldBe(0);
|
||||
}
|
||||
[Fact]
|
||||
|
|
@ -377,44 +379,44 @@ public class UserSessionStoreTests
|
|||
Ticket = "ticket",
|
||||
SubjectId = "sub1",
|
||||
SessionId = "sid1_1",
|
||||
});
|
||||
}, _ct);
|
||||
await _subject.CreateUserSessionAsync(new UserSession
|
||||
{
|
||||
Key = Guid.NewGuid().ToString(),
|
||||
Ticket = "ticket",
|
||||
SubjectId = "sub1",
|
||||
SessionId = "sid1_2",
|
||||
});
|
||||
}, _ct);
|
||||
await _subject.CreateUserSessionAsync(new UserSession
|
||||
{
|
||||
Key = Guid.NewGuid().ToString(),
|
||||
Ticket = "ticket",
|
||||
SubjectId = "sub2",
|
||||
SessionId = "sid2_1",
|
||||
});
|
||||
}, _ct);
|
||||
await _subject.CreateUserSessionAsync(new UserSession
|
||||
{
|
||||
Key = Guid.NewGuid().ToString(),
|
||||
Ticket = "ticket",
|
||||
SubjectId = "sub2",
|
||||
SessionId = "sid2_2",
|
||||
});
|
||||
}, _ct);
|
||||
await _subject.CreateUserSessionAsync(new UserSession
|
||||
{
|
||||
Key = Guid.NewGuid().ToString(),
|
||||
Ticket = "ticket",
|
||||
SubjectId = "sub2",
|
||||
SessionId = "sid2_3",
|
||||
});
|
||||
}, _ct);
|
||||
await _subject.CreateUserSessionAsync(new UserSession
|
||||
{
|
||||
Key = Guid.NewGuid().ToString(),
|
||||
Ticket = "ticket",
|
||||
SubjectId = "sub3",
|
||||
SessionId = "sid3_1",
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
var items = await _subject.GetUserSessionsAsync(new UserSessionsFilter { SubjectId = "sub2", SessionId = "sid2_2" });
|
||||
var items = await _subject.GetUserSessionsAsync(new UserSessionsFilter { SubjectId = "sub2", SessionId = "sid2_2" }, _ct);
|
||||
items.Count().ShouldBe(1);
|
||||
items.Select(x => x.SubjectId).ToArray().ShouldBeEquivalentTo(new[] { "sub2" });
|
||||
items.Select(x => x.SessionId).ToArray().ShouldBeEquivalentTo(new[] { "sid2_2" });
|
||||
|
|
@ -428,60 +430,60 @@ public class UserSessionStoreTests
|
|||
Ticket = "ticket",
|
||||
SubjectId = "sub1",
|
||||
SessionId = "sid1_1",
|
||||
});
|
||||
}, _ct);
|
||||
await _subject.CreateUserSessionAsync(new UserSession
|
||||
{
|
||||
Key = Guid.NewGuid().ToString(),
|
||||
Ticket = "ticket",
|
||||
SubjectId = "sub1",
|
||||
SessionId = "sid1_2",
|
||||
});
|
||||
}, _ct);
|
||||
await _subject.CreateUserSessionAsync(new UserSession
|
||||
{
|
||||
Key = Guid.NewGuid().ToString(),
|
||||
Ticket = "ticket",
|
||||
SubjectId = "sub2",
|
||||
SessionId = "sid2_1",
|
||||
});
|
||||
}, _ct);
|
||||
await _subject.CreateUserSessionAsync(new UserSession
|
||||
{
|
||||
Key = Guid.NewGuid().ToString(),
|
||||
Ticket = "ticket",
|
||||
SubjectId = "sub2",
|
||||
SessionId = "sid2_2",
|
||||
});
|
||||
}, _ct);
|
||||
await _subject.CreateUserSessionAsync(new UserSession
|
||||
{
|
||||
Key = Guid.NewGuid().ToString(),
|
||||
Ticket = "ticket",
|
||||
SubjectId = "sub2",
|
||||
SessionId = "sid2_3",
|
||||
});
|
||||
}, _ct);
|
||||
await _subject.CreateUserSessionAsync(new UserSession
|
||||
{
|
||||
Key = Guid.NewGuid().ToString(),
|
||||
Ticket = "ticket",
|
||||
SubjectId = "sub3",
|
||||
SessionId = "sid3_1",
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
{
|
||||
var items = await _subject.GetUserSessionsAsync(new UserSessionsFilter { SubjectId = "invalid", SessionId = "invalid" });
|
||||
var items = await _subject.GetUserSessionsAsync(new UserSessionsFilter { SubjectId = "invalid", SessionId = "invalid" }, _ct);
|
||||
items.Count().ShouldBe(0);
|
||||
}
|
||||
{
|
||||
var items = await _subject.GetUserSessionsAsync(new UserSessionsFilter { SubjectId = "sub1", SessionId = "invalid" });
|
||||
var items = await _subject.GetUserSessionsAsync(new UserSessionsFilter { SubjectId = "sub1", SessionId = "invalid" }, _ct);
|
||||
items.Count().ShouldBe(0);
|
||||
}
|
||||
{
|
||||
var items = await _subject.GetUserSessionsAsync(new UserSessionsFilter { SubjectId = "invalid", SessionId = "sid1_1" });
|
||||
var items = await _subject.GetUserSessionsAsync(new UserSessionsFilter { SubjectId = "invalid", SessionId = "sid1_1" }, _ct);
|
||||
items.Count().ShouldBe(0);
|
||||
}
|
||||
}
|
||||
[Fact]
|
||||
public async Task GetUserSessionsAsync_for_missing_sub_and_sid_should_throw()
|
||||
{
|
||||
Func<Task> f = () => _subject.GetUserSessionsAsync(new UserSessionsFilter());
|
||||
Func<Task> f = () => _subject.GetUserSessionsAsync(new UserSessionsFilter(), _ct);
|
||||
await f.ShouldThrowAsync<Exception>();
|
||||
}
|
||||
|
||||
|
|
@ -495,44 +497,44 @@ public class UserSessionStoreTests
|
|||
Ticket = "ticket",
|
||||
SubjectId = "sub1",
|
||||
SessionId = "sid1_1",
|
||||
});
|
||||
}, _ct);
|
||||
await _subject.CreateUserSessionAsync(new UserSession
|
||||
{
|
||||
Key = Guid.NewGuid().ToString(),
|
||||
Ticket = "ticket",
|
||||
SubjectId = "sub1",
|
||||
SessionId = "sid1_2",
|
||||
});
|
||||
}, _ct);
|
||||
await _subject.CreateUserSessionAsync(new UserSession
|
||||
{
|
||||
Key = Guid.NewGuid().ToString(),
|
||||
Ticket = "ticket",
|
||||
SubjectId = "sub2",
|
||||
SessionId = "sid2_1",
|
||||
});
|
||||
}, _ct);
|
||||
await _subject.CreateUserSessionAsync(new UserSession
|
||||
{
|
||||
Key = Guid.NewGuid().ToString(),
|
||||
Ticket = "ticket",
|
||||
SubjectId = "sub2",
|
||||
SessionId = "sid2_2",
|
||||
});
|
||||
}, _ct);
|
||||
await _subject.CreateUserSessionAsync(new UserSession
|
||||
{
|
||||
Key = Guid.NewGuid().ToString(),
|
||||
Ticket = "ticket",
|
||||
SubjectId = "sub2",
|
||||
SessionId = "sid2_3",
|
||||
});
|
||||
}, _ct);
|
||||
await _subject.CreateUserSessionAsync(new UserSession
|
||||
{
|
||||
Key = Guid.NewGuid().ToString(),
|
||||
Ticket = "ticket",
|
||||
SubjectId = "sub3",
|
||||
SessionId = "sid3_1",
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
await _subject.DeleteUserSessionsAsync(new UserSessionsFilter { SubjectId = "sub2" });
|
||||
await _subject.DeleteUserSessionsAsync(new UserSessionsFilter { SubjectId = "sub2" }, _ct);
|
||||
_database.UserSessions.Count().ShouldBe(3);
|
||||
_database.UserSessions.Count(x => x.SubjectId == "sub2").ShouldBe(0);
|
||||
}
|
||||
|
|
@ -545,44 +547,44 @@ public class UserSessionStoreTests
|
|||
Ticket = "ticket",
|
||||
SubjectId = "sub1",
|
||||
SessionId = "sid1_1",
|
||||
});
|
||||
}, _ct);
|
||||
await _subject.CreateUserSessionAsync(new UserSession
|
||||
{
|
||||
Key = Guid.NewGuid().ToString(),
|
||||
Ticket = "ticket",
|
||||
SubjectId = "sub1",
|
||||
SessionId = "sid1_2",
|
||||
});
|
||||
}, _ct);
|
||||
await _subject.CreateUserSessionAsync(new UserSession
|
||||
{
|
||||
Key = Guid.NewGuid().ToString(),
|
||||
Ticket = "ticket",
|
||||
SubjectId = "sub2",
|
||||
SessionId = "sid2_1",
|
||||
});
|
||||
}, _ct);
|
||||
await _subject.CreateUserSessionAsync(new UserSession
|
||||
{
|
||||
Key = Guid.NewGuid().ToString(),
|
||||
Ticket = "ticket",
|
||||
SubjectId = "sub2",
|
||||
SessionId = "sid2_2",
|
||||
});
|
||||
}, _ct);
|
||||
await _subject.CreateUserSessionAsync(new UserSession
|
||||
{
|
||||
Key = Guid.NewGuid().ToString(),
|
||||
Ticket = "ticket",
|
||||
SubjectId = "sub2",
|
||||
SessionId = "sid2_3",
|
||||
});
|
||||
}, _ct);
|
||||
await _subject.CreateUserSessionAsync(new UserSession
|
||||
{
|
||||
Key = Guid.NewGuid().ToString(),
|
||||
Ticket = "ticket",
|
||||
SubjectId = "sub3",
|
||||
SessionId = "sid3_1",
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
await _subject.DeleteUserSessionsAsync(new UserSessionsFilter { SubjectId = "invalid" });
|
||||
await _subject.DeleteUserSessionsAsync(new UserSessionsFilter { SubjectId = "invalid" }, _ct);
|
||||
_database.UserSessions.Count().ShouldBe(6);
|
||||
}
|
||||
[Fact]
|
||||
|
|
@ -594,44 +596,47 @@ public class UserSessionStoreTests
|
|||
Ticket = "ticket",
|
||||
SubjectId = "sub1",
|
||||
SessionId = "sid1_1",
|
||||
});
|
||||
}, _ct);
|
||||
await _subject.CreateUserSessionAsync(new UserSession
|
||||
{
|
||||
Key = Guid.NewGuid().ToString(),
|
||||
Ticket = "ticket",
|
||||
SubjectId = "sub1",
|
||||
SessionId = "sid1_2",
|
||||
});
|
||||
}, _ct);
|
||||
await _subject.CreateUserSessionAsync(new UserSession
|
||||
{
|
||||
Key = Guid.NewGuid().ToString(),
|
||||
Ticket = "ticket",
|
||||
SubjectId = "sub2",
|
||||
SessionId = "sid2_1",
|
||||
});
|
||||
}, _ct);
|
||||
await _subject.CreateUserSessionAsync(new UserSession
|
||||
{
|
||||
Key = Guid.NewGuid().ToString(),
|
||||
Ticket = "ticket",
|
||||
SubjectId = "sub2",
|
||||
SessionId = "sid2_2",
|
||||
});
|
||||
}, _ct);
|
||||
await _subject.CreateUserSessionAsync(new UserSession
|
||||
{
|
||||
Key = Guid.NewGuid().ToString(),
|
||||
Ticket = "ticket",
|
||||
SubjectId = "sub2",
|
||||
SessionId = "sid2_3",
|
||||
});
|
||||
}, _ct);
|
||||
await _subject.CreateUserSessionAsync(new UserSession
|
||||
{
|
||||
Key = Guid.NewGuid().ToString(),
|
||||
Ticket = "ticket",
|
||||
SubjectId = "sub3",
|
||||
SessionId = "sid3_1",
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
await _subject.DeleteUserSessionsAsync(new UserSessionsFilter { SessionId = "sid2_2" });
|
||||
await _subject.DeleteUserSessionsAsync(new UserSessionsFilter
|
||||
{
|
||||
SessionId = "sid2_2"
|
||||
}, _ct);
|
||||
_database.UserSessions.Count().ShouldBe(5);
|
||||
_database.UserSessions.Count(x => x.SessionId == "sid2_2").ShouldBe(0);
|
||||
}
|
||||
|
|
@ -644,44 +649,44 @@ public class UserSessionStoreTests
|
|||
Ticket = "ticket",
|
||||
SubjectId = "sub1",
|
||||
SessionId = "sid1_1",
|
||||
});
|
||||
}, _ct);
|
||||
await _subject.CreateUserSessionAsync(new UserSession
|
||||
{
|
||||
Key = Guid.NewGuid().ToString(),
|
||||
Ticket = "ticket",
|
||||
SubjectId = "sub1",
|
||||
SessionId = "sid1_2",
|
||||
});
|
||||
}, _ct);
|
||||
await _subject.CreateUserSessionAsync(new UserSession
|
||||
{
|
||||
Key = Guid.NewGuid().ToString(),
|
||||
Ticket = "ticket",
|
||||
SubjectId = "sub2",
|
||||
SessionId = "sid2_1",
|
||||
});
|
||||
}, _ct);
|
||||
await _subject.CreateUserSessionAsync(new UserSession
|
||||
{
|
||||
Key = Guid.NewGuid().ToString(),
|
||||
Ticket = "ticket",
|
||||
SubjectId = "sub2",
|
||||
SessionId = "sid2_2",
|
||||
});
|
||||
}, _ct);
|
||||
await _subject.CreateUserSessionAsync(new UserSession
|
||||
{
|
||||
Key = Guid.NewGuid().ToString(),
|
||||
Ticket = "ticket",
|
||||
SubjectId = "sub2",
|
||||
SessionId = "sid2_3",
|
||||
});
|
||||
}, _ct);
|
||||
await _subject.CreateUserSessionAsync(new UserSession
|
||||
{
|
||||
Key = Guid.NewGuid().ToString(),
|
||||
Ticket = "ticket",
|
||||
SubjectId = "sub3",
|
||||
SessionId = "sid3_1",
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
await _subject.DeleteUserSessionsAsync(new UserSessionsFilter { SessionId = "invalid" });
|
||||
await _subject.DeleteUserSessionsAsync(new UserSessionsFilter { SessionId = "invalid" }, _ct);
|
||||
_database.UserSessions.Count().ShouldBe(6);
|
||||
}
|
||||
[Fact]
|
||||
|
|
@ -693,44 +698,44 @@ public class UserSessionStoreTests
|
|||
Ticket = "ticket",
|
||||
SubjectId = "sub1",
|
||||
SessionId = "sid1_1",
|
||||
});
|
||||
}, _ct);
|
||||
await _subject.CreateUserSessionAsync(new UserSession
|
||||
{
|
||||
Key = Guid.NewGuid().ToString(),
|
||||
Ticket = "ticket",
|
||||
SubjectId = "sub1",
|
||||
SessionId = "sid1_2",
|
||||
});
|
||||
}, _ct);
|
||||
await _subject.CreateUserSessionAsync(new UserSession
|
||||
{
|
||||
Key = Guid.NewGuid().ToString(),
|
||||
Ticket = "ticket",
|
||||
SubjectId = "sub2",
|
||||
SessionId = "sid2_1",
|
||||
});
|
||||
}, _ct);
|
||||
await _subject.CreateUserSessionAsync(new UserSession
|
||||
{
|
||||
Key = Guid.NewGuid().ToString(),
|
||||
Ticket = "ticket",
|
||||
SubjectId = "sub2",
|
||||
SessionId = "sid2_2",
|
||||
});
|
||||
}, _ct);
|
||||
await _subject.CreateUserSessionAsync(new UserSession
|
||||
{
|
||||
Key = Guid.NewGuid().ToString(),
|
||||
Ticket = "ticket",
|
||||
SubjectId = "sub2",
|
||||
SessionId = "sid2_3",
|
||||
});
|
||||
}, _ct);
|
||||
await _subject.CreateUserSessionAsync(new UserSession
|
||||
{
|
||||
Key = Guid.NewGuid().ToString(),
|
||||
Ticket = "ticket",
|
||||
SubjectId = "sub3",
|
||||
SessionId = "sid3_1",
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
await _subject.DeleteUserSessionsAsync(new UserSessionsFilter { SubjectId = "sub2", SessionId = "sid2_2" });
|
||||
await _subject.DeleteUserSessionsAsync(new UserSessionsFilter { SubjectId = "sub2", SessionId = "sid2_2" }, _ct);
|
||||
_database.UserSessions.Count().ShouldBe(5);
|
||||
_database.UserSessions.Count(x => x.SubjectId == "sub2" && x.SessionId == "sid2_2").ShouldBe(0);
|
||||
}
|
||||
|
|
@ -743,60 +748,60 @@ public class UserSessionStoreTests
|
|||
Ticket = "ticket",
|
||||
SubjectId = "sub1",
|
||||
SessionId = "sid1_1",
|
||||
});
|
||||
}, _ct);
|
||||
await _subject.CreateUserSessionAsync(new UserSession
|
||||
{
|
||||
Key = Guid.NewGuid().ToString(),
|
||||
Ticket = "ticket",
|
||||
SubjectId = "sub1",
|
||||
SessionId = "sid1_2",
|
||||
});
|
||||
}, _ct);
|
||||
await _subject.CreateUserSessionAsync(new UserSession
|
||||
{
|
||||
Key = Guid.NewGuid().ToString(),
|
||||
Ticket = "ticket",
|
||||
SubjectId = "sub2",
|
||||
SessionId = "sid2_1",
|
||||
});
|
||||
}, _ct);
|
||||
await _subject.CreateUserSessionAsync(new UserSession
|
||||
{
|
||||
Key = Guid.NewGuid().ToString(),
|
||||
Ticket = "ticket",
|
||||
SubjectId = "sub2",
|
||||
SessionId = "sid2_2",
|
||||
});
|
||||
}, _ct);
|
||||
await _subject.CreateUserSessionAsync(new UserSession
|
||||
{
|
||||
Key = Guid.NewGuid().ToString(),
|
||||
Ticket = "ticket",
|
||||
SubjectId = "sub2",
|
||||
SessionId = "sid2_3",
|
||||
});
|
||||
}, _ct);
|
||||
await _subject.CreateUserSessionAsync(new UserSession
|
||||
{
|
||||
Key = Guid.NewGuid().ToString(),
|
||||
Ticket = "ticket",
|
||||
SubjectId = "sub3",
|
||||
SessionId = "sid3_1",
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
{
|
||||
await _subject.DeleteUserSessionsAsync(new UserSessionsFilter { SubjectId = "invalid", SessionId = "invalid" });
|
||||
await _subject.DeleteUserSessionsAsync(new UserSessionsFilter { SubjectId = "invalid", SessionId = "invalid" }, _ct);
|
||||
_database.UserSessions.Count().ShouldBe(6);
|
||||
}
|
||||
{
|
||||
await _subject.DeleteUserSessionsAsync(new UserSessionsFilter { SubjectId = "sub1", SessionId = "invalid" });
|
||||
await _subject.DeleteUserSessionsAsync(new UserSessionsFilter { SubjectId = "sub1", SessionId = "invalid" }, _ct);
|
||||
_database.UserSessions.Count().ShouldBe(6);
|
||||
}
|
||||
{
|
||||
await _subject.DeleteUserSessionsAsync(new UserSessionsFilter { SubjectId = "invalid", SessionId = "sid1_1" });
|
||||
await _subject.DeleteUserSessionsAsync(new UserSessionsFilter { SubjectId = "invalid", SessionId = "sid1_1" }, _ct);
|
||||
_database.UserSessions.Count().ShouldBe(6);
|
||||
}
|
||||
}
|
||||
[Fact]
|
||||
public async Task DeleteUserSessionsAsync_for_missing_sub_and_sid_should_throw()
|
||||
{
|
||||
Func<Task> f = () => _subject.DeleteUserSessionsAsync(new UserSessionsFilter());
|
||||
Func<Task> f = () => _subject.DeleteUserSessionsAsync(new UserSessionsFilter(), _ct);
|
||||
await f.ShouldThrowAsync<Exception>();
|
||||
}
|
||||
|
||||
|
|
@ -820,7 +825,7 @@ public class UserSessionStoreTests
|
|||
SubjectId = "sub",
|
||||
SessionId = "sid",
|
||||
});
|
||||
await ctx0.SaveChangesAsync();
|
||||
await ctx0.SaveChangesAsync(_ct);
|
||||
|
||||
using var scope1 = provider.CreateScope();
|
||||
var ctx1 = scope1.ServiceProvider.GetRequiredService<SessionDbContext>();
|
||||
|
|
@ -832,14 +837,14 @@ public class UserSessionStoreTests
|
|||
var item2 = ctx2.UserSessions.Single(x => x.Key == key);
|
||||
ctx2.UserSessions.Remove(item2);
|
||||
|
||||
await ctx1.SaveChangesAsync();
|
||||
await ctx1.SaveChangesAsync(_ct);
|
||||
|
||||
Func<Task> f1 = async () => await ctx2.SaveChangesAsync();
|
||||
Func<Task> f1 = async () => await ctx2.SaveChangesAsync(_ct);
|
||||
await f1.ShouldThrowAsync<DbUpdateConcurrencyException>();
|
||||
|
||||
try
|
||||
{
|
||||
await ctx2.SaveChangesAsync();
|
||||
await ctx2.SaveChangesAsync(_ct);
|
||||
}
|
||||
catch (DbUpdateConcurrencyException ex)
|
||||
{
|
||||
|
|
@ -851,6 +856,6 @@ public class UserSessionStoreTests
|
|||
}
|
||||
|
||||
// calling again to not throw
|
||||
await ctx2.SaveChangesAsync();
|
||||
await ctx2.SaveChangesAsync(_ct);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@
|
|||
<PackageReference Include="Microsoft.AspNetCore.TestHost" />
|
||||
<PackageReference Include="Microsoft.Extensions.TimeProvider.Testing" />
|
||||
<PackageReference Include="PublicApiGenerator" />
|
||||
<PackageReference Include="Verify.Xunit" />
|
||||
<PackageReference Include="Verify.XunitV3" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
|
|
|||
|
|
@ -7,12 +7,13 @@ using Duende.Bff.Tests.TestFramework;
|
|||
using Duende.Bff.Tests.TestHosts;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.IdentityModel.Tokens;
|
||||
using Xunit.Abstractions;
|
||||
|
||||
namespace Duende.Bff.Tests.Endpoints;
|
||||
|
||||
public class DpopRemoteEndpointTests : BffIntegrationTestBase
|
||||
{
|
||||
private readonly CancellationToken _ct = TestContext.Current.CancellationToken;
|
||||
|
||||
public DpopRemoteEndpointTests(ITestOutputHelper output) : base(output)
|
||||
{
|
||||
var rsaKey = new RsaSecurityKey(RSA.Create(2048));
|
||||
|
|
@ -20,9 +21,9 @@ public class DpopRemoteEndpointTests : BffIntegrationTestBase
|
|||
jsonWebKey.Alg = "PS256";
|
||||
var jwk = JsonSerializer.Serialize(jsonWebKey);
|
||||
|
||||
BffHost.OnConfigureServices += svcs =>
|
||||
BffHost.OnConfigureServices += services =>
|
||||
{
|
||||
svcs.PostConfigure<BffOptions>(opts =>
|
||||
services.PostConfigure<BffOptions>(opts =>
|
||||
{
|
||||
opts.DPoPJsonWebKey = jwk;
|
||||
});
|
||||
|
|
@ -33,8 +34,7 @@ public class DpopRemoteEndpointTests : BffIntegrationTestBase
|
|||
public async Task test_dpop()
|
||||
{
|
||||
ApiResponse apiResult = await BffHost.BrowserClient.CallBffHostApi(
|
||||
url: BffHost.Url("/api_client/test")
|
||||
);
|
||||
url: BffHost.Url("/api_client/test"), ct: _ct);
|
||||
|
||||
apiResult.RequestHeaders["DPoP"].First().ShouldNotBeNullOrEmpty();
|
||||
apiResult.RequestHeaders["Authorization"].First().StartsWith("DPoP ").ShouldBeTrue();
|
||||
|
|
|
|||
|
|
@ -6,20 +6,21 @@ using System.Net.Http.Json;
|
|||
using Duende.Bff.Tests.TestFramework;
|
||||
using Duende.Bff.Tests.TestHosts;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Xunit.Abstractions;
|
||||
|
||||
namespace Duende.Bff.Tests.Endpoints;
|
||||
|
||||
public class LocalEndpointTests(ITestOutputHelper output) : BffIntegrationTestBase(output)
|
||||
{
|
||||
private readonly CancellationToken _ct = TestContext.Current.CancellationToken;
|
||||
|
||||
[Fact]
|
||||
public async Task calls_to_authorized_local_endpoint_should_succeed()
|
||||
{
|
||||
await BffHost.BffLoginAsync("alice");
|
||||
|
||||
ApiResponse apiResult = await BffHost.BrowserClient.CallBffHostApi(
|
||||
url: BffHost.Url("/local_authz")
|
||||
);
|
||||
url: BffHost.Url("/local_authz"),
|
||||
ct: _ct);
|
||||
|
||||
apiResult.Method.ShouldBe("GET");
|
||||
apiResult.Path.ShouldBe("/local_authz");
|
||||
|
|
@ -32,8 +33,8 @@ public class LocalEndpointTests(ITestOutputHelper output) : BffIntegrationTestBa
|
|||
await BffHost.BffLoginAsync("alice");
|
||||
|
||||
ApiResponse apiResult = await BffHost.BrowserClient.CallBffHostApi(
|
||||
url: BffHost.Url("/local_authz_no_csrf")
|
||||
);
|
||||
url: BffHost.Url("/local_authz_no_csrf"),
|
||||
ct: _ct);
|
||||
|
||||
apiResult.Method.ShouldBe("GET");
|
||||
apiResult.Path.ShouldBe("/local_authz_no_csrf");
|
||||
|
|
@ -45,15 +46,15 @@ public class LocalEndpointTests(ITestOutputHelper output) : BffIntegrationTestBa
|
|||
{
|
||||
var response = await BffHost.BrowserClient.CallBffHostApi(
|
||||
url: BffHost.Url("/local_authz"),
|
||||
expectedStatusCode: HttpStatusCode.Unauthorized
|
||||
);
|
||||
expectedStatusCode: HttpStatusCode.Unauthorized,
|
||||
ct: _ct);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task calls_to_local_endpoint_should_require_antiforgery_header()
|
||||
{
|
||||
var req = new HttpRequestMessage(HttpMethod.Get, BffHost.Url("/local_anon"));
|
||||
var response = await BffHost.BrowserClient.SendAsync(req);
|
||||
var response = await BffHost.BrowserClient.SendAsync(req, _ct);
|
||||
|
||||
response.StatusCode.ShouldBe(HttpStatusCode.Unauthorized);
|
||||
}
|
||||
|
|
@ -64,16 +65,16 @@ public class LocalEndpointTests(ITestOutputHelper output) : BffIntegrationTestBa
|
|||
{
|
||||
var response = await BffHost.BrowserClient.CallBffHostApi(
|
||||
url: BffHost.Url("/local_anon_no_csrf"),
|
||||
expectedStatusCode: HttpStatusCode.OK
|
||||
);
|
||||
expectedStatusCode: HttpStatusCode.OK,
|
||||
ct: _ct);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task calls_to_anon_endpoint_should_allow_anonymous()
|
||||
{
|
||||
ApiResponse apiResult = await BffHost.BrowserClient.CallBffHostApi(
|
||||
url: BffHost.Url("/local_anon")
|
||||
);
|
||||
url: BffHost.Url("/local_anon"),
|
||||
ct: _ct);
|
||||
|
||||
apiResult.Method.ShouldBe("GET");
|
||||
apiResult.Path.ShouldBe("/local_anon");
|
||||
|
|
@ -88,8 +89,8 @@ public class LocalEndpointTests(ITestOutputHelper output) : BffIntegrationTestBa
|
|||
ApiResponse apiResult = await BffHost.BrowserClient.CallBffHostApi(
|
||||
url: BffHost.Url("/local_authz"),
|
||||
method: HttpMethod.Put,
|
||||
content: JsonContent.Create(new TestPayload("hello test api"))
|
||||
);
|
||||
content: JsonContent.Create(new TestPayload("hello test api")),
|
||||
ct: _ct);
|
||||
|
||||
apiResult.Method.ShouldBe("PUT");
|
||||
apiResult.Path.ShouldBe("/local_authz");
|
||||
|
|
@ -103,7 +104,7 @@ public class LocalEndpointTests(ITestOutputHelper output) : BffIntegrationTestBa
|
|||
{
|
||||
var req = new HttpRequestMessage(HttpMethod.Get, BffHost.Url("/always_fail_authz_non_bff_endpoint"));
|
||||
req.Headers.Add("x-csrf", "1");
|
||||
var response = await BffHost.BrowserClient.SendAsync(req);
|
||||
var response = await BffHost.BrowserClient.SendAsync(req, _ct);
|
||||
|
||||
response.StatusCode.ShouldBe(HttpStatusCode.Redirect);
|
||||
response.Headers.Location
|
||||
|
|
@ -114,23 +115,21 @@ public class LocalEndpointTests(ITestOutputHelper output) : BffIntegrationTestBa
|
|||
}
|
||||
|
||||
[Fact]
|
||||
public async Task unauthenticated_api_call_should_return_401()
|
||||
{
|
||||
var response = await BffHost.BrowserClient.CallBffHostApi(
|
||||
public async Task unauthenticated_api_call_should_return_401() =>
|
||||
_ = await BffHost.BrowserClient.CallBffHostApi(
|
||||
url: BffHost.Url("/always_fail_authz"),
|
||||
expectedStatusCode: HttpStatusCode.Unauthorized
|
||||
);
|
||||
}
|
||||
expectedStatusCode: HttpStatusCode.Unauthorized,
|
||||
ct: _ct);
|
||||
|
||||
[Fact]
|
||||
public async Task forbidden_api_call_should_return_403()
|
||||
{
|
||||
await BffHost.BffLoginAsync("alice");
|
||||
|
||||
var response = await BffHost.BrowserClient.CallBffHostApi(
|
||||
_ = await BffHost.BrowserClient.CallBffHostApi(
|
||||
url: BffHost.Url("/always_fail_authz"),
|
||||
expectedStatusCode: HttpStatusCode.Forbidden
|
||||
);
|
||||
expectedStatusCode: HttpStatusCode.Forbidden,
|
||||
ct: _ct);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
|
@ -139,10 +138,10 @@ public class LocalEndpointTests(ITestOutputHelper output) : BffIntegrationTestBa
|
|||
await BffHost.BffLoginAsync("alice");
|
||||
BffHost.LocalApiResponseStatus = BffHost.ResponseStatus.Challenge;
|
||||
|
||||
var response = await BffHost.BrowserClient.CallBffHostApi(
|
||||
_ = await BffHost.BrowserClient.CallBffHostApi(
|
||||
url: BffHost.Url("/local_authz"),
|
||||
expectedStatusCode: HttpStatusCode.Unauthorized
|
||||
);
|
||||
expectedStatusCode: HttpStatusCode.Unauthorized,
|
||||
ct: _ct);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
|
@ -153,8 +152,8 @@ public class LocalEndpointTests(ITestOutputHelper output) : BffIntegrationTestBa
|
|||
|
||||
var response = await BffHost.BrowserClient.CallBffHostApi(
|
||||
url: BffHost.Url("/local_authz"),
|
||||
expectedStatusCode: HttpStatusCode.Forbidden
|
||||
);
|
||||
expectedStatusCode: HttpStatusCode.Forbidden,
|
||||
ct: _ct);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
|
@ -165,16 +164,16 @@ public class LocalEndpointTests(ITestOutputHelper output) : BffIntegrationTestBa
|
|||
|
||||
var response = await BffHost.BrowserClient.CallBffHostApi(
|
||||
url: BffHost.Url("/local_anon_no_csrf_no_response_handling"),
|
||||
expectedStatusCode: HttpStatusCode.Redirect
|
||||
);
|
||||
expectedStatusCode: HttpStatusCode.Redirect,
|
||||
ct: _ct);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task fallback_policy_should_not_fail()
|
||||
{
|
||||
BffHost.OnConfigureServices += svcs =>
|
||||
BffHost.OnConfigureServices += services =>
|
||||
{
|
||||
svcs.AddAuthorization(opts =>
|
||||
services.AddAuthorization(opts =>
|
||||
{
|
||||
opts.FallbackPolicy =
|
||||
new Microsoft.AspNetCore.Authorization.AuthorizationPolicyBuilder()
|
||||
|
|
@ -184,7 +183,7 @@ public class LocalEndpointTests(ITestOutputHelper output) : BffIntegrationTestBa
|
|||
};
|
||||
await BffHost.InitializeAsync();
|
||||
|
||||
var response = await BffHost.HttpClient.GetAsync(BffHost.Url("/not-found"));
|
||||
var response = await BffHost.HttpClient.GetAsync(BffHost.Url("/not-found"), _ct);
|
||||
response.StatusCode.ShouldNotBe(HttpStatusCode.InternalServerError);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,18 +4,19 @@
|
|||
using System.Net;
|
||||
using Duende.Bff.Tests.TestHosts;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Xunit.Abstractions;
|
||||
|
||||
namespace Duende.Bff.Tests.Endpoints.Management;
|
||||
|
||||
public class BackchannelLogoutEndpointTests(ITestOutputHelper output) : BffIntegrationTestBase(output)
|
||||
{
|
||||
private readonly CancellationToken _ct = TestContext.Current.CancellationToken;
|
||||
|
||||
[Fact]
|
||||
public async Task backchannel_logout_should_allow_anonymous()
|
||||
{
|
||||
BffHost.OnConfigureServices += svcs =>
|
||||
BffHost.OnConfigureServices += services =>
|
||||
{
|
||||
svcs.AddAuthorization(opts =>
|
||||
services.AddAuthorization(opts =>
|
||||
{
|
||||
opts.FallbackPolicy =
|
||||
new Microsoft.AspNetCore.Authorization.AuthorizationPolicyBuilder()
|
||||
|
|
@ -25,7 +26,7 @@ public class BackchannelLogoutEndpointTests(ITestOutputHelper output) : BffInteg
|
|||
};
|
||||
await BffHost.InitializeAsync();
|
||||
|
||||
var response = await BffHost.HttpClient.PostAsync(BffHost.Url("/bff/backchannel"), null);
|
||||
var response = await BffHost.HttpClient.PostAsync(BffHost.Url("/bff/backchannel"), null, _ct);
|
||||
response.StatusCode.ShouldNotBe(HttpStatusCode.Unauthorized);
|
||||
}
|
||||
|
||||
|
|
@ -75,7 +76,9 @@ public class BackchannelLogoutEndpointTests(ITestOutputHelper output) : BffInteg
|
|||
|
||||
{
|
||||
var store = BffHost.Resolve<IUserSessionStore>();
|
||||
var sessions = await store.GetUserSessionsAsync(new UserSessionsFilter { SubjectId = "alice" });
|
||||
var sessions = await store.GetUserSessionsAsync(
|
||||
new UserSessionsFilter { SubjectId = "alice" },
|
||||
_ct);
|
||||
sessions.Count().ShouldBe(2);
|
||||
}
|
||||
|
||||
|
|
@ -83,7 +86,9 @@ public class BackchannelLogoutEndpointTests(ITestOutputHelper output) : BffInteg
|
|||
|
||||
{
|
||||
var store = BffHost.Resolve<IUserSessionStore>();
|
||||
var sessions = await store.GetUserSessionsAsync(new UserSessionsFilter { SubjectId = "alice" });
|
||||
var sessions = await store.GetUserSessionsAsync(
|
||||
new UserSessionsFilter { SubjectId = "alice" },
|
||||
_ct);
|
||||
var session = sessions.Single();
|
||||
session.SessionId.ShouldBe("sid1");
|
||||
}
|
||||
|
|
@ -100,7 +105,9 @@ public class BackchannelLogoutEndpointTests(ITestOutputHelper output) : BffInteg
|
|||
|
||||
{
|
||||
var store = BffHost.Resolve<IUserSessionStore>();
|
||||
var sessions = await store.GetUserSessionsAsync(new UserSessionsFilter { SubjectId = "alice" });
|
||||
var sessions = await store.GetUserSessionsAsync(
|
||||
new UserSessionsFilter { SubjectId = "alice" },
|
||||
_ct);
|
||||
sessions.Count().ShouldBe(2);
|
||||
}
|
||||
|
||||
|
|
@ -108,7 +115,9 @@ public class BackchannelLogoutEndpointTests(ITestOutputHelper output) : BffInteg
|
|||
|
||||
{
|
||||
var store = BffHost.Resolve<IUserSessionStore>();
|
||||
var sessions = await store.GetUserSessionsAsync(new UserSessionsFilter { SubjectId = "alice" });
|
||||
var sessions = await store.GetUserSessionsAsync(
|
||||
new UserSessionsFilter { SubjectId = "alice" },
|
||||
_ct);
|
||||
sessions.ShouldBeEmpty();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,18 +4,19 @@
|
|||
using System.Net;
|
||||
using Duende.Bff.Tests.TestHosts;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Xunit.Abstractions;
|
||||
|
||||
namespace Duende.Bff.Tests.Endpoints.Management;
|
||||
|
||||
public class LoginEndpointTests(ITestOutputHelper output) : BffIntegrationTestBase(output)
|
||||
{
|
||||
private readonly CancellationToken _ct = TestContext.Current.CancellationToken;
|
||||
|
||||
[Fact]
|
||||
public async Task login_should_allow_anonymous()
|
||||
{
|
||||
BffHost.OnConfigureServices += svcs =>
|
||||
BffHost.OnConfigureServices += services =>
|
||||
{
|
||||
svcs.AddAuthorization(opts =>
|
||||
services.AddAuthorization(opts =>
|
||||
{
|
||||
opts.FallbackPolicy =
|
||||
new Microsoft.AspNetCore.Authorization.AuthorizationPolicyBuilder()
|
||||
|
|
@ -25,23 +26,23 @@ public class LoginEndpointTests(ITestOutputHelper output) : BffIntegrationTestBa
|
|||
};
|
||||
await BffHost.InitializeAsync();
|
||||
|
||||
var response = await BffHost.BrowserClient.GetAsync(BffHost.Url("/bff/login"));
|
||||
var response = await BffHost.BrowserClient.GetAsync(BffHost.Url("/bff/login"), _ct);
|
||||
response.StatusCode.ShouldNotBe(HttpStatusCode.Unauthorized);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task login_endpoint_should_challenge_and_redirect_to_root()
|
||||
{
|
||||
var response = await BffHost.BrowserClient.GetAsync(BffHost.Url("/bff/login"));
|
||||
var response = await BffHost.BrowserClient.GetAsync(BffHost.Url("/bff/login"), _ct);
|
||||
response.StatusCode.ShouldBe(HttpStatusCode.Redirect);
|
||||
response.Headers.Location!.ToString().ShouldStartWith(IdentityServerHost.Url("/connect/authorize"));
|
||||
|
||||
await IdentityServerHost.IssueSessionCookieAsync("alice");
|
||||
response = await IdentityServerHost.BrowserClient.GetAsync(response.Headers.Location.ToString());
|
||||
response = await IdentityServerHost.BrowserClient.GetAsync(response.Headers.Location.ToString(), _ct);
|
||||
response.StatusCode.ShouldBe(HttpStatusCode.Redirect);
|
||||
response.Headers.Location!.ToString().ShouldStartWith(BffHost.Url("/signin-oidc"));
|
||||
|
||||
response = await BffHost.BrowserClient.GetAsync(response.Headers.Location.ToString());
|
||||
response = await BffHost.BrowserClient.GetAsync(response.Headers.Location.ToString(), _ct);
|
||||
response.StatusCode.ShouldBe(HttpStatusCode.Redirect);
|
||||
response.Headers.Location!.ToString().ShouldBe("/");
|
||||
}
|
||||
|
|
@ -49,25 +50,25 @@ public class LoginEndpointTests(ITestOutputHelper output) : BffIntegrationTestBa
|
|||
[Fact]
|
||||
public async Task login_endpoint_should_challenge_and_redirect_to_root_with_custom_prefix()
|
||||
{
|
||||
BffHost.OnConfigureServices += svcs =>
|
||||
BffHost.OnConfigureServices += services =>
|
||||
{
|
||||
svcs.Configure<BffOptions>(options =>
|
||||
services.Configure<BffOptions>(options =>
|
||||
{
|
||||
options.ManagementBasePath = "/custom/bff";
|
||||
});
|
||||
};
|
||||
await BffHost.InitializeAsync();
|
||||
|
||||
var response = await BffHost.BrowserClient.GetAsync(BffHost.Url("/custom/bff/login"));
|
||||
var response = await BffHost.BrowserClient.GetAsync(BffHost.Url("/custom/bff/login"), _ct);
|
||||
response.StatusCode.ShouldBe(HttpStatusCode.Redirect);
|
||||
response.Headers.Location!.ToString().ShouldStartWith(IdentityServerHost.Url("/connect/authorize"));
|
||||
|
||||
await IdentityServerHost.IssueSessionCookieAsync("alice");
|
||||
response = await IdentityServerHost.BrowserClient.GetAsync(response.Headers.Location.ToString());
|
||||
response = await IdentityServerHost.BrowserClient.GetAsync(response.Headers.Location.ToString(), _ct);
|
||||
response.StatusCode.ShouldBe(HttpStatusCode.Redirect);
|
||||
response.Headers.Location!.ToString().ShouldStartWith(BffHost.Url("/signin-oidc"));
|
||||
|
||||
response = await BffHost.BrowserClient.GetAsync(response.Headers.Location.ToString());
|
||||
response = await BffHost.BrowserClient.GetAsync(response.Headers.Location.ToString(), _ct);
|
||||
response.StatusCode.ShouldBe(HttpStatusCode.Redirect);
|
||||
response.Headers.Location!.ToString().ShouldBe("/");
|
||||
}
|
||||
|
|
@ -75,25 +76,25 @@ public class LoginEndpointTests(ITestOutputHelper output) : BffIntegrationTestBa
|
|||
[Fact]
|
||||
public async Task login_endpoint_should_challenge_and_redirect_to_root_with_custom_prefix_trailing_slash()
|
||||
{
|
||||
BffHost.OnConfigureServices += svcs =>
|
||||
BffHost.OnConfigureServices += services =>
|
||||
{
|
||||
svcs.Configure<BffOptions>(options =>
|
||||
services.Configure<BffOptions>(options =>
|
||||
{
|
||||
options.ManagementBasePath = "/custom/bff/";
|
||||
});
|
||||
};
|
||||
await BffHost.InitializeAsync();
|
||||
|
||||
var response = await BffHost.BrowserClient.GetAsync(BffHost.Url("/custom/bff/login"));
|
||||
var response = await BffHost.BrowserClient.GetAsync(BffHost.Url("/custom/bff/login"), _ct);
|
||||
response.StatusCode.ShouldBe(HttpStatusCode.Redirect);
|
||||
response.Headers.Location!.ToString().ShouldStartWith(IdentityServerHost.Url("/connect/authorize"));
|
||||
|
||||
await IdentityServerHost.IssueSessionCookieAsync("alice");
|
||||
response = await IdentityServerHost.BrowserClient.GetAsync(response.Headers.Location.ToString());
|
||||
response = await IdentityServerHost.BrowserClient.GetAsync(response.Headers.Location.ToString(), _ct);
|
||||
response.StatusCode.ShouldBe(HttpStatusCode.Redirect);
|
||||
response.Headers.Location!.ToString().ShouldStartWith(BffHost.Url("/signin-oidc"));
|
||||
|
||||
response = await BffHost.BrowserClient.GetAsync(response.Headers.Location.ToString());
|
||||
response = await BffHost.BrowserClient.GetAsync(response.Headers.Location.ToString(), _ct);
|
||||
response.StatusCode.ShouldBe(HttpStatusCode.Redirect);
|
||||
response.Headers.Location!.ToString().ShouldBe("/");
|
||||
}
|
||||
|
|
@ -101,25 +102,25 @@ public class LoginEndpointTests(ITestOutputHelper output) : BffIntegrationTestBa
|
|||
[Fact]
|
||||
public async Task login_endpoint_should_challenge_and_redirect_to_root_with_root_prefix()
|
||||
{
|
||||
BffHost.OnConfigureServices += svcs =>
|
||||
BffHost.OnConfigureServices += services =>
|
||||
{
|
||||
svcs.Configure<BffOptions>(options =>
|
||||
services.Configure<BffOptions>(options =>
|
||||
{
|
||||
options.ManagementBasePath = "/";
|
||||
});
|
||||
};
|
||||
await BffHost.InitializeAsync();
|
||||
|
||||
var response = await BffHost.BrowserClient.GetAsync(BffHost.Url("/login"));
|
||||
var response = await BffHost.BrowserClient.GetAsync(BffHost.Url("/login"), _ct);
|
||||
response.StatusCode.ShouldBe(HttpStatusCode.Redirect);
|
||||
response.Headers.Location!.ToString().ShouldStartWith(IdentityServerHost.Url("/connect/authorize"));
|
||||
|
||||
await IdentityServerHost.IssueSessionCookieAsync("alice");
|
||||
response = await IdentityServerHost.BrowserClient.GetAsync(response.Headers.Location.ToString());
|
||||
response = await IdentityServerHost.BrowserClient.GetAsync(response.Headers.Location.ToString(), _ct);
|
||||
response.StatusCode.ShouldBe(HttpStatusCode.Redirect);
|
||||
response.Headers.Location!.ToString().ShouldStartWith(BffHost.Url("/signin-oidc"));
|
||||
|
||||
response = await BffHost.BrowserClient.GetAsync(response.Headers.Location.ToString());
|
||||
response = await BffHost.BrowserClient.GetAsync(response.Headers.Location.ToString(), _ct);
|
||||
response.StatusCode.ShouldBe(HttpStatusCode.Redirect);
|
||||
response.Headers.Location!.ToString().ShouldBe("/");
|
||||
}
|
||||
|
|
@ -129,7 +130,7 @@ public class LoginEndpointTests(ITestOutputHelper output) : BffIntegrationTestBa
|
|||
{
|
||||
await BffHost.BffLoginAsync("alice");
|
||||
|
||||
var response = await BffHost.BrowserClient.GetAsync(BffHost.Url("/bff/login"));
|
||||
var response = await BffHost.BrowserClient.GetAsync(BffHost.Url("/bff/login"), _ct);
|
||||
response.StatusCode.ShouldBe(HttpStatusCode.Redirect);
|
||||
response.Headers.Location!.ToString().ShouldStartWith(IdentityServerHost.Url("/connect/authorize"));
|
||||
}
|
||||
|
|
@ -137,16 +138,16 @@ public class LoginEndpointTests(ITestOutputHelper output) : BffIntegrationTestBa
|
|||
[Fact]
|
||||
public async Task login_endpoint_should_accept_returnUrl()
|
||||
{
|
||||
var response = await BffHost.BrowserClient.GetAsync(BffHost.Url("/bff/login") + "?returnUrl=/foo");
|
||||
var response = await BffHost.BrowserClient.GetAsync(BffHost.Url("/bff/login") + "?returnUrl=/foo", _ct);
|
||||
response.StatusCode.ShouldBe(HttpStatusCode.Redirect);
|
||||
response.Headers.Location!.ToString().ShouldStartWith(IdentityServerHost.Url("/connect/authorize"));
|
||||
|
||||
await IdentityServerHost.IssueSessionCookieAsync("alice");
|
||||
response = await IdentityServerHost.BrowserClient.GetAsync(response.Headers.Location.ToString());
|
||||
response = await IdentityServerHost.BrowserClient.GetAsync(response.Headers.Location.ToString(), _ct);
|
||||
response.StatusCode.ShouldBe(HttpStatusCode.Redirect);
|
||||
response.Headers.Location!.ToString().ShouldStartWith(BffHost.Url("/signin-oidc"));
|
||||
|
||||
response = await BffHost.BrowserClient.GetAsync(response.Headers.Location.ToString());
|
||||
response = await BffHost.BrowserClient.GetAsync(response.Headers.Location.ToString(), _ct);
|
||||
response.StatusCode.ShouldBe(HttpStatusCode.Redirect);
|
||||
response.Headers.Location!.ToString().ShouldBe("/foo");
|
||||
}
|
||||
|
|
@ -154,7 +155,7 @@ public class LoginEndpointTests(ITestOutputHelper output) : BffIntegrationTestBa
|
|||
[Fact]
|
||||
public async Task login_endpoint_should_not_accept_non_local_returnUrl()
|
||||
{
|
||||
var response = await BffHost.BrowserClient.GetAsync(BffHost.Url("/bff/login") + "?returnUrl=https://foo");
|
||||
var response = await BffHost.BrowserClient.GetAsync(BffHost.Url("/bff/login") + "?returnUrl=https://foo", _ct);
|
||||
response.StatusCode.ShouldBe(HttpStatusCode.BadRequest);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,18 +4,19 @@
|
|||
using System.Net;
|
||||
using Duende.Bff.Tests.TestHosts;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Xunit.Abstractions;
|
||||
|
||||
namespace Duende.Bff.Tests.Endpoints.Management;
|
||||
|
||||
public class LogoutEndpointTests(ITestOutputHelper output) : BffIntegrationTestBase(output)
|
||||
{
|
||||
private readonly CancellationToken _ct = TestContext.Current.CancellationToken;
|
||||
|
||||
[Fact]
|
||||
public async Task logout_endpoint_should_allow_anonymous()
|
||||
{
|
||||
BffHost.OnConfigureServices += svcs =>
|
||||
BffHost.OnConfigureServices += services =>
|
||||
{
|
||||
svcs.AddAuthorization(opts =>
|
||||
services.AddAuthorization(opts =>
|
||||
{
|
||||
opts.FallbackPolicy =
|
||||
new Microsoft.AspNetCore.Authorization.AuthorizationPolicyBuilder()
|
||||
|
|
@ -25,7 +26,7 @@ public class LogoutEndpointTests(ITestOutputHelper output) : BffIntegrationTestB
|
|||
};
|
||||
await BffHost.InitializeAsync();
|
||||
|
||||
var response = await BffHost.BrowserClient.GetAsync(BffHost.Url("/bff/logout"));
|
||||
var response = await BffHost.BrowserClient.GetAsync(BffHost.Url("/bff/logout"), _ct);
|
||||
response.StatusCode.ShouldNotBe(HttpStatusCode.Unauthorized);
|
||||
}
|
||||
|
||||
|
|
@ -44,7 +45,7 @@ public class LogoutEndpointTests(ITestOutputHelper output) : BffIntegrationTestB
|
|||
{
|
||||
await BffHost.BffLoginAsync("alice", "sid123");
|
||||
|
||||
var response = await BffHost.BrowserClient.GetAsync(BffHost.Url("/bff/logout"));
|
||||
var response = await BffHost.BrowserClient.GetAsync(BffHost.Url("/bff/logout"), _ct);
|
||||
response.StatusCode.ShouldBe(HttpStatusCode.BadRequest);
|
||||
|
||||
(await BffHost.GetIsUserLoggedInAsync()).ShouldBeTrue();
|
||||
|
|
@ -57,7 +58,7 @@ public class LogoutEndpointTests(ITestOutputHelper output) : BffIntegrationTestB
|
|||
|
||||
BffHost.BffOptions.RequireLogoutSessionId = false;
|
||||
|
||||
var response = await BffHost.BrowserClient.GetAsync(BffHost.Url("/bff/logout"));
|
||||
var response = await BffHost.BrowserClient.GetAsync(BffHost.Url("/bff/logout"), _ct);
|
||||
response.StatusCode.ShouldBe(HttpStatusCode.Redirect); // endsession
|
||||
response.Headers.Location!.ToString().ToLowerInvariant().ShouldStartWith(IdentityServerHost.Url("/connect/endsession"));
|
||||
}
|
||||
|
|
@ -66,9 +67,9 @@ public class LogoutEndpointTests(ITestOutputHelper output) : BffIntegrationTestB
|
|||
public async Task logout_endpoint_for_authenticated_user_without_sid_should_succeed()
|
||||
{
|
||||
// workaround for RevokeUserRefreshTokenAsync throwing when no RT in session
|
||||
BffHost.OnConfigureServices += svcs =>
|
||||
BffHost.OnConfigureServices += services =>
|
||||
{
|
||||
svcs.Configure<BffOptions>(options =>
|
||||
services.Configure<BffOptions>(options =>
|
||||
{
|
||||
options.RevokeRefreshTokenOnLogout = false;
|
||||
});
|
||||
|
|
@ -77,7 +78,7 @@ public class LogoutEndpointTests(ITestOutputHelper output) : BffIntegrationTestB
|
|||
|
||||
await BffHost.IssueSessionCookieAsync("alice");
|
||||
|
||||
var response = await BffHost.BrowserClient.GetAsync(BffHost.Url("/bff/logout"));
|
||||
var response = await BffHost.BrowserClient.GetAsync(BffHost.Url("/bff/logout"), _ct);
|
||||
response.StatusCode.ShouldBe(HttpStatusCode.Redirect); // endsession
|
||||
response.Headers.Location!.ToString().ToLowerInvariant().ShouldStartWith(IdentityServerHost.Url("/connect/endsession"));
|
||||
}
|
||||
|
|
@ -85,7 +86,7 @@ public class LogoutEndpointTests(ITestOutputHelper output) : BffIntegrationTestB
|
|||
[Fact]
|
||||
public async Task logout_endpoint_for_anonymous_user_without_sid_should_succeed()
|
||||
{
|
||||
var response = await BffHost.BrowserClient.GetAsync(BffHost.Url("/bff/logout"));
|
||||
var response = await BffHost.BrowserClient.GetAsync(BffHost.Url("/bff/logout"), _ct);
|
||||
response.StatusCode.ShouldBe(HttpStatusCode.Redirect); // endsession
|
||||
response.Headers.Location!.ToString().ToLowerInvariant().ShouldStartWith(IdentityServerHost.Url("/connect/endsession"));
|
||||
}
|
||||
|
|
@ -113,7 +114,7 @@ public class LogoutEndpointTests(ITestOutputHelper output) : BffIntegrationTestB
|
|||
|
||||
await BffHost.BffLogoutAsync("sid123");
|
||||
|
||||
var response = await BffHost.BrowserClient.GetAsync(BffHost.Url("/bff/logout") + "?sid=123");
|
||||
var response = await BffHost.BrowserClient.GetAsync(BffHost.Url("/bff/logout") + "?sid=123", _ct);
|
||||
response.StatusCode.ShouldBe(HttpStatusCode.Redirect); // endsession
|
||||
response.Headers.Location!.ToString().ToLowerInvariant().ShouldStartWith(IdentityServerHost.Url("/connect/endsession"));
|
||||
|
||||
|
|
@ -126,19 +127,19 @@ public class LogoutEndpointTests(ITestOutputHelper output) : BffIntegrationTestB
|
|||
{
|
||||
await BffHost.BffLoginAsync("alice", "sid123");
|
||||
|
||||
var response = await BffHost.BrowserClient.GetAsync(BffHost.Url("/bff/logout") + "?sid=sid123&returnUrl=/foo");
|
||||
var response = await BffHost.BrowserClient.GetAsync(BffHost.Url("/bff/logout") + "?sid=sid123&returnUrl=/foo", _ct);
|
||||
response.StatusCode.ShouldBe(HttpStatusCode.Redirect); // endsession
|
||||
response.Headers.Location!.ToString().ToLowerInvariant().ShouldStartWith(IdentityServerHost.Url("/connect/endsession"));
|
||||
|
||||
response = await IdentityServerHost.BrowserClient.GetAsync(response.Headers.Location!.ToString());
|
||||
response = await IdentityServerHost.BrowserClient.GetAsync(response.Headers.Location!.ToString(), _ct);
|
||||
response.StatusCode.ShouldBe(HttpStatusCode.Redirect); // logout
|
||||
response.Headers.Location!.ToString().ToLowerInvariant().ShouldStartWith(IdentityServerHost.Url("/account/logout"));
|
||||
|
||||
response = await IdentityServerHost.BrowserClient.GetAsync(response.Headers.Location!.ToString());
|
||||
response = await IdentityServerHost.BrowserClient.GetAsync(response.Headers.Location!.ToString(), _ct);
|
||||
response.StatusCode.ShouldBe(HttpStatusCode.Redirect); // post logout redirect uri
|
||||
response.Headers.Location!.ToString().ToLowerInvariant().ShouldStartWith(BffHost.Url("/signout-callback-oidc"));
|
||||
|
||||
response = await BffHost.BrowserClient.GetAsync(response.Headers.Location!.ToString());
|
||||
response = await BffHost.BrowserClient.GetAsync(response.Headers.Location!.ToString(), _ct);
|
||||
response.StatusCode.ShouldBe(HttpStatusCode.Redirect); // root
|
||||
response.Headers.Location!.ToString().ToLowerInvariant().ShouldBe("/foo");
|
||||
}
|
||||
|
|
@ -148,7 +149,7 @@ public class LogoutEndpointTests(ITestOutputHelper output) : BffIntegrationTestB
|
|||
{
|
||||
await BffHost.BffLoginAsync("alice", "sid123");
|
||||
|
||||
var response = await BffHost.BrowserClient.GetAsync(BffHost.Url("/bff/logout") + "?sid=sid123&returnUrl=https://foo");
|
||||
var response = await BffHost.BrowserClient.GetAsync(BffHost.Url("/bff/logout") + "?sid=sid123&returnUrl=https://foo", _ct);
|
||||
response.StatusCode.ShouldBe(HttpStatusCode.BadRequest);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,12 +5,13 @@ using System.Net;
|
|||
using Duende.Bff.Tests.TestHosts;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Xunit.Abstractions;
|
||||
|
||||
namespace Duende.Bff.Tests.Endpoints.Management;
|
||||
|
||||
public class ManagementBasePathTests(ITestOutputHelper output) : BffIntegrationTestBase(output)
|
||||
{
|
||||
private readonly CancellationToken _ct = TestContext.Current.CancellationToken;
|
||||
|
||||
[Theory]
|
||||
[InlineData(Constants.ManagementEndpoints.Login)]
|
||||
[InlineData(Constants.ManagementEndpoints.Logout)]
|
||||
|
|
@ -19,9 +20,9 @@ public class ManagementBasePathTests(ITestOutputHelper output) : BffIntegrationT
|
|||
[InlineData(Constants.ManagementEndpoints.User)]
|
||||
public async Task custom_ManagementBasePath_should_affect_basepath(string path)
|
||||
{
|
||||
BffHost.OnConfigureServices += svcs =>
|
||||
BffHost.OnConfigureServices += services =>
|
||||
{
|
||||
svcs.Configure<BffOptions>(options =>
|
||||
services.Configure<BffOptions>(options =>
|
||||
{
|
||||
options.ManagementBasePath = new PathString("/{path:regex(^[a-zA-Z\\d-]+$)}/bff");
|
||||
});
|
||||
|
|
@ -31,7 +32,7 @@ public class ManagementBasePathTests(ITestOutputHelper output) : BffIntegrationT
|
|||
var req = new HttpRequestMessage(HttpMethod.Get, BffHost.Url("/custom/bff" + path));
|
||||
req.Headers.Add("x-csrf", "1");
|
||||
|
||||
var response = await BffHost.BrowserClient.SendAsync(req);
|
||||
var response = await BffHost.BrowserClient.SendAsync(req, _ct);
|
||||
|
||||
response.StatusCode.ShouldNotBe(HttpStatusCode.NotFound);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,12 +4,13 @@
|
|||
using System.Net;
|
||||
using System.Security.Claims;
|
||||
using Duende.Bff.Tests.TestHosts;
|
||||
using Xunit.Abstractions;
|
||||
|
||||
namespace Duende.Bff.Tests.Endpoints.Management;
|
||||
|
||||
public class UserEndpointTests(ITestOutputHelper output) : BffIntegrationTestBase(output)
|
||||
{
|
||||
private readonly CancellationToken _ct = TestContext.Current.CancellationToken;
|
||||
|
||||
[Fact]
|
||||
public async Task user_endpoint_for_authenticated_user_should_return_claims()
|
||||
{
|
||||
|
|
@ -54,7 +55,7 @@ public class UserEndpointTests(ITestOutputHelper output) : BffIntegrationTestBas
|
|||
await BffHost.IssueSessionCookieAsync(new Claim("sub", "alice"), new Claim("foo", "foo1"), new Claim("foo", "foo2"));
|
||||
|
||||
var req = new HttpRequestMessage(HttpMethod.Get, BffHost.Url("/bff/user"));
|
||||
var response = await BffHost.BrowserClient.SendAsync(req);
|
||||
var response = await BffHost.BrowserClient.SendAsync(req, _ct);
|
||||
|
||||
response.StatusCode.ShouldBe(HttpStatusCode.Unauthorized);
|
||||
}
|
||||
|
|
@ -64,7 +65,7 @@ public class UserEndpointTests(ITestOutputHelper output) : BffIntegrationTestBas
|
|||
{
|
||||
var req = new HttpRequestMessage(HttpMethod.Get, BffHost.Url("/bff/user"));
|
||||
req.Headers.Add("x-csrf", "1");
|
||||
var response = await BffHost.BrowserClient.SendAsync(req);
|
||||
var response = await BffHost.BrowserClient.SendAsync(req, _ct);
|
||||
|
||||
response.StatusCode.ShouldBe(HttpStatusCode.Unauthorized);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,17 +6,19 @@ using System.Net.Http.Json;
|
|||
using System.Text.Json;
|
||||
using Duende.Bff.Tests.TestFramework;
|
||||
using Duende.Bff.Tests.TestHosts;
|
||||
using Xunit.Abstractions;
|
||||
|
||||
namespace Duende.Bff.Tests.Endpoints;
|
||||
|
||||
public class RemoteEndpointTests(ITestOutputHelper output) : BffIntegrationTestBase(output)
|
||||
{
|
||||
private readonly CancellationToken _ct = TestContext.Current.CancellationToken;
|
||||
|
||||
[Fact]
|
||||
public async Task unauthenticated_calls_to_remote_endpoint_should_return_401() => await BffHost.BrowserClient.CallBffHostApi(
|
||||
public async Task unauthenticated_calls_to_remote_endpoint_should_return_401()
|
||||
=> await BffHost.BrowserClient.CallBffHostApi(
|
||||
url: BffHost.Url("/api_user/test"),
|
||||
expectedStatusCode: HttpStatusCode.Unauthorized
|
||||
);
|
||||
expectedStatusCode: HttpStatusCode.Unauthorized,
|
||||
ct: _ct);
|
||||
|
||||
[Fact]
|
||||
public async Task calls_to_remote_endpoint_should_forward_user_to_api()
|
||||
|
|
@ -24,8 +26,8 @@ public class RemoteEndpointTests(ITestOutputHelper output) : BffIntegrationTestB
|
|||
await BffHost.BffLoginAsync("alice");
|
||||
|
||||
var (response, apiResult) = await BffHost.BrowserClient.CallBffHostApi(
|
||||
url: BffHost.Url("/api_user/test")
|
||||
);
|
||||
url: BffHost.Url("/api_user/test"),
|
||||
ct: _ct);
|
||||
|
||||
apiResult.Method.ShouldBe("GET");
|
||||
apiResult.Path.ShouldBe("/test");
|
||||
|
|
@ -37,15 +39,14 @@ public class RemoteEndpointTests(ITestOutputHelper output) : BffIntegrationTestB
|
|||
}
|
||||
|
||||
[Fact]
|
||||
public async Task
|
||||
calls_to_remote_endpoint_with_useraccesstokenparameters_having_stored_named_token_should_forward_user_to_api()
|
||||
public async Task calls_to_remote_endpoint_with_useraccesstokenparameters_having_stored_named_token_should_forward_user_to_api()
|
||||
{
|
||||
await BffHostWithNamedTokens.BffLoginAsync("alice");
|
||||
|
||||
ApiResponse apiResult = await BffHostWithNamedTokens.BrowserClient.CallBffHostApi(
|
||||
url: BffHostWithNamedTokens.Url(
|
||||
"/api_user_with_useraccesstokenparameters_having_stored_named_token/test")
|
||||
);
|
||||
"/api_user_with_useraccesstokenparameters_having_stored_named_token/test"),
|
||||
ct: _ct);
|
||||
|
||||
apiResult.Method.ShouldBe("GET");
|
||||
apiResult.Path.ShouldBe("/test");
|
||||
|
|
@ -62,8 +63,8 @@ public class RemoteEndpointTests(ITestOutputHelper output) : BffIntegrationTestB
|
|||
await BffHostWithNamedTokens.BrowserClient.CallBffHostApi(
|
||||
url: BffHostWithNamedTokens.Url(
|
||||
"/api_user_with_useraccesstokenparameters_having_not_stored_named_token/test"),
|
||||
expectedStatusCode: HttpStatusCode.Unauthorized
|
||||
);
|
||||
expectedStatusCode: HttpStatusCode.Unauthorized,
|
||||
ct: _ct);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
|
@ -74,8 +75,8 @@ public class RemoteEndpointTests(ITestOutputHelper output) : BffIntegrationTestB
|
|||
ApiResponse apiResult = await BffHost.BrowserClient.CallBffHostApi(
|
||||
url: BffHost.Url("/api_user/test"),
|
||||
method: HttpMethod.Put,
|
||||
content: JsonContent.Create(new TestPayload("hello test api"))
|
||||
);
|
||||
content: JsonContent.Create(new TestPayload("hello test api")),
|
||||
ct: _ct);
|
||||
|
||||
apiResult.Method.ShouldBe("PUT");
|
||||
apiResult.Path.ShouldBe("/test");
|
||||
|
|
@ -93,8 +94,8 @@ public class RemoteEndpointTests(ITestOutputHelper output) : BffIntegrationTestB
|
|||
ApiResponse apiResult = await BffHost.BrowserClient.CallBffHostApi(
|
||||
url: BffHost.Url("/api_user/test"),
|
||||
method: HttpMethod.Post,
|
||||
content: JsonContent.Create(new TestPayload("hello test api"))
|
||||
);
|
||||
content: JsonContent.Create(new TestPayload("hello test api")),
|
||||
ct: _ct);
|
||||
|
||||
apiResult.Method.ShouldBe("POST");
|
||||
apiResult.Path.ShouldBe("/test");
|
||||
|
|
@ -109,8 +110,8 @@ public class RemoteEndpointTests(ITestOutputHelper output) : BffIntegrationTestB
|
|||
{
|
||||
{
|
||||
ApiResponse apiResult = await BffHost.BrowserClient.CallBffHostApi(
|
||||
url: BffHost.Url("/api_user_or_anon/test")
|
||||
);
|
||||
url: BffHost.Url("/api_user_or_anon/test"),
|
||||
ct: _ct);
|
||||
|
||||
apiResult.Method.ShouldBe("GET");
|
||||
apiResult.Path.ShouldBe("/test");
|
||||
|
|
@ -122,8 +123,8 @@ public class RemoteEndpointTests(ITestOutputHelper output) : BffIntegrationTestB
|
|||
await BffHost.BffLoginAsync("alice");
|
||||
|
||||
ApiResponse apiResult = await BffHost.BrowserClient.CallBffHostApi(
|
||||
url: BffHost.Url("/api_user_or_anon/test")
|
||||
);
|
||||
url: BffHost.Url("/api_user_or_anon/test"),
|
||||
ct: _ct);
|
||||
|
||||
apiResult.Method.ShouldBe("GET");
|
||||
apiResult.Path.ShouldBe("/test");
|
||||
|
|
@ -138,8 +139,8 @@ public class RemoteEndpointTests(ITestOutputHelper output) : BffIntegrationTestB
|
|||
await BffHost.BffLoginAsync("alice");
|
||||
|
||||
ApiResponse apiResult = await BffHost.BrowserClient.CallBffHostApi(
|
||||
url: BffHost.Url("/api_client/test")
|
||||
);
|
||||
url: BffHost.Url("/api_client/test"),
|
||||
ct: _ct);
|
||||
|
||||
apiResult.Method.ShouldBe("GET");
|
||||
apiResult.Path.ShouldBe("/test");
|
||||
|
|
@ -154,8 +155,8 @@ public class RemoteEndpointTests(ITestOutputHelper output) : BffIntegrationTestB
|
|||
|
||||
await BffHost.BrowserClient.CallBffHostApi(
|
||||
url: BffHost.Url("/api_with_access_token_retrieval_that_fails"),
|
||||
expectedStatusCode: HttpStatusCode.Unauthorized
|
||||
);
|
||||
expectedStatusCode: HttpStatusCode.Unauthorized,
|
||||
ct: _ct);
|
||||
|
||||
// user should be signed out
|
||||
var result = await BffHost.GetIsUserLoggedInAsync();
|
||||
|
|
@ -169,8 +170,8 @@ public class RemoteEndpointTests(ITestOutputHelper output) : BffIntegrationTestB
|
|||
|
||||
await BffHost.BrowserClient.CallBffHostApi(
|
||||
url: BffHost.Url("/api_forbidden"),
|
||||
expectedStatusCode: HttpStatusCode.Forbidden
|
||||
);
|
||||
expectedStatusCode: HttpStatusCode.Forbidden,
|
||||
ct: _ct);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
|
@ -180,8 +181,8 @@ public class RemoteEndpointTests(ITestOutputHelper output) : BffIntegrationTestB
|
|||
|
||||
await BffHost.BrowserClient.CallBffHostApi(
|
||||
url: BffHost.Url("/api_unauthenticated"),
|
||||
expectedStatusCode: HttpStatusCode.Unauthorized
|
||||
);
|
||||
expectedStatusCode: HttpStatusCode.Unauthorized,
|
||||
ct: _ct);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
|
@ -190,8 +191,8 @@ public class RemoteEndpointTests(ITestOutputHelper output) : BffIntegrationTestB
|
|||
await BffHost.BffLoginAsync("alice");
|
||||
|
||||
ApiResponse apiResult = await BffHost.BrowserClient.CallBffHostApi(
|
||||
url: BffHost.Url("/api_with_access_token_retriever")
|
||||
);
|
||||
url: BffHost.Url("/api_with_access_token_retriever"),
|
||||
ct: _ct);
|
||||
|
||||
apiResult.Sub.ShouldBe("123");
|
||||
apiResult.ClientId.ShouldBe("fake-client");
|
||||
|
|
@ -202,8 +203,8 @@ public class RemoteEndpointTests(ITestOutputHelper output) : BffIntegrationTestB
|
|||
{
|
||||
{
|
||||
ApiResponse apiResult = await BffHost.BrowserClient.CallBffHostApi(
|
||||
url: BffHost.Url("/api_user_or_client/test")
|
||||
);
|
||||
url: BffHost.Url("/api_user_or_client/test"),
|
||||
ct: _ct);
|
||||
|
||||
apiResult.Method.ShouldBe("GET");
|
||||
apiResult.Path.ShouldBe("/test");
|
||||
|
|
@ -215,8 +216,8 @@ public class RemoteEndpointTests(ITestOutputHelper output) : BffIntegrationTestB
|
|||
await BffHost.BffLoginAsync("alice");
|
||||
|
||||
ApiResponse apiResult = await BffHost.BrowserClient.CallBffHostApi(
|
||||
url: BffHost.Url("/api_user_or_client/test")
|
||||
);
|
||||
url: BffHost.Url("/api_user_or_client/test"),
|
||||
ct: _ct);
|
||||
|
||||
apiResult.Method.ShouldBe("GET");
|
||||
apiResult.Path.ShouldBe("/test");
|
||||
|
|
@ -230,8 +231,8 @@ public class RemoteEndpointTests(ITestOutputHelper output) : BffIntegrationTestB
|
|||
{
|
||||
{
|
||||
ApiResponse apiResult = await BffHost.BrowserClient.CallBffHostApi(
|
||||
url: BffHost.Url("/api_anon_only/test")
|
||||
);
|
||||
url: BffHost.Url("/api_anon_only/test"),
|
||||
ct: _ct);
|
||||
|
||||
apiResult.Method.ShouldBe("GET");
|
||||
apiResult.Path.ShouldBe("/test");
|
||||
|
|
@ -243,8 +244,8 @@ public class RemoteEndpointTests(ITestOutputHelper output) : BffIntegrationTestB
|
|||
await BffHost.BffLoginAsync("alice");
|
||||
|
||||
ApiResponse apiResult = await BffHost.BrowserClient.CallBffHostApi(
|
||||
url: BffHost.Url("/api_anon_only/test")
|
||||
);
|
||||
url: BffHost.Url("/api_anon_only/test"),
|
||||
ct: _ct);
|
||||
|
||||
apiResult.Method.ShouldBe("GET");
|
||||
apiResult.Path.ShouldBe("/test");
|
||||
|
|
@ -261,13 +262,13 @@ public class RemoteEndpointTests(ITestOutputHelper output) : BffIntegrationTestB
|
|||
|
||||
await BffHost.BrowserClient.CallBffHostApi(
|
||||
url: BffHost.Url("/api_user_or_client/test"),
|
||||
expectedStatusCode: HttpStatusCode.Unauthorized
|
||||
);
|
||||
expectedStatusCode: HttpStatusCode.Unauthorized,
|
||||
ct: _ct);
|
||||
|
||||
await BffHost.BrowserClient.CallBffHostApi(
|
||||
url: BffHost.Url("/api_client/test"),
|
||||
expectedStatusCode: HttpStatusCode.Unauthorized
|
||||
);
|
||||
expectedStatusCode: HttpStatusCode.Unauthorized,
|
||||
ct: _ct);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
|
@ -278,8 +279,8 @@ public class RemoteEndpointTests(ITestOutputHelper output) : BffIntegrationTestB
|
|||
|
||||
await BffHost.BrowserClient.CallBffHostApi(
|
||||
url: BffHost.Url("/api_user/test"),
|
||||
expectedStatusCode: HttpStatusCode.Unauthorized
|
||||
);
|
||||
expectedStatusCode: HttpStatusCode.Unauthorized,
|
||||
ct: _ct);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
|
@ -290,14 +291,14 @@ public class RemoteEndpointTests(ITestOutputHelper output) : BffIntegrationTestB
|
|||
|
||||
await BffHost.BrowserClient.CallBffHostApi(
|
||||
url: BffHost.Url("/api_user/test"),
|
||||
expectedStatusCode: HttpStatusCode.Forbidden
|
||||
);
|
||||
expectedStatusCode: HttpStatusCode.Forbidden,
|
||||
ct: _ct);
|
||||
}
|
||||
[Fact]
|
||||
public async Task calls_to_remote_endpoint_should_require_csrf()
|
||||
{
|
||||
var req = new HttpRequestMessage(HttpMethod.Get, BffHost.Url("/api_user_or_client/test"));
|
||||
var response = await BffHost.BrowserClient.SendAsync(req);
|
||||
var response = await BffHost.BrowserClient.SendAsync(req, _ct);
|
||||
|
||||
response.StatusCode.ShouldBe(HttpStatusCode.Unauthorized);
|
||||
}
|
||||
|
|
@ -308,8 +309,8 @@ public class RemoteEndpointTests(ITestOutputHelper output) : BffIntegrationTestB
|
|||
await BffHost.BffLoginAsync("alice");
|
||||
|
||||
ApiResponse apiResult = await BffHost.BrowserClient.CallBffHostApi(
|
||||
url: BffHost.Url("/api_user_no_csrf/test")
|
||||
);
|
||||
url: BffHost.Url("/api_user_no_csrf/test"),
|
||||
ct: _ct);
|
||||
|
||||
apiResult.Method.ShouldBe("GET");
|
||||
apiResult.Path.ShouldBe("/test");
|
||||
|
|
@ -325,11 +326,11 @@ public class RemoteEndpointTests(ITestOutputHelper output) : BffIntegrationTestB
|
|||
var req = new HttpRequestMessage(HttpMethod.Get, BffHost.Url("/api_custom_transform/test"));
|
||||
req.Headers.Add("x-csrf", "1");
|
||||
req.Headers.Add("my-header-to-be-copied-by-yarp", "copied-value");
|
||||
var response = await BffHost.BrowserClient.SendAsync(req);
|
||||
var response = await BffHost.BrowserClient.SendAsync(req, _ct);
|
||||
|
||||
response.IsSuccessStatusCode.ShouldBeTrue();
|
||||
response.Content.Headers.ContentType!.MediaType.ShouldBe("application/json");
|
||||
var json = await response.Content.ReadAsStringAsync();
|
||||
var json = await response.Content.ReadAsStringAsync(_ct);
|
||||
var apiResult = JsonSerializer.Deserialize<ApiResponse>(json).ShouldNotBeNull();
|
||||
apiResult.RequestHeaders["my-header-to-be-copied-by-yarp"].First().ShouldBe("copied-value");
|
||||
|
||||
|
|
|
|||
|
|
@ -4,46 +4,51 @@
|
|||
using System.Net;
|
||||
using Duende.Bff.Tests.TestFramework;
|
||||
using Duende.Bff.Tests.TestHosts;
|
||||
using Xunit.Abstractions;
|
||||
|
||||
namespace Duende.Bff.Tests.Endpoints;
|
||||
|
||||
public class YarpRemoteEndpointTests(ITestOutputHelper output) : YarpBffIntegrationTestBase(output)
|
||||
{
|
||||
private readonly CancellationToken _ct = TestContext.Current.CancellationToken;
|
||||
|
||||
|
||||
[Fact]
|
||||
public async Task anonymous_call_with_no_csrf_header_to_no_token_requirement_no_csrf_route_should_succeed() => await YarpBasedBffHost.BrowserClient.CallBffHostApi(
|
||||
public async Task anonymous_call_with_no_csrf_header_to_no_token_requirement_no_csrf_route_should_succeed()
|
||||
=> await YarpBasedBffHost.BrowserClient.CallBffHostApi(
|
||||
url: YarpBasedBffHost.Url("/api_anon_no_csrf/test"),
|
||||
expectedStatusCode: HttpStatusCode.OK
|
||||
);
|
||||
expectedStatusCode: HttpStatusCode.OK,
|
||||
ct: _ct);
|
||||
|
||||
[Fact]
|
||||
public async Task anonymous_call_with_no_csrf_header_to_csrf_route_should_fail()
|
||||
{
|
||||
var req = new HttpRequestMessage(HttpMethod.Get, YarpBasedBffHost.Url("/api_anon/test"));
|
||||
var response = await YarpBasedBffHost.BrowserClient.SendAsync(req);
|
||||
var response = await YarpBasedBffHost.BrowserClient.SendAsync(req, _ct);
|
||||
|
||||
response.StatusCode.ShouldBe(HttpStatusCode.Unauthorized);
|
||||
}
|
||||
|
||||
|
||||
[Fact]
|
||||
public async Task anonymous_call_to_no_token_requirement_route_should_succeed() => await YarpBasedBffHost.BrowserClient.CallBffHostApi(
|
||||
public async Task anonymous_call_to_no_token_requirement_route_should_succeed()
|
||||
=> await YarpBasedBffHost.BrowserClient.CallBffHostApi(
|
||||
url: YarpBasedBffHost.Url("/api_anon/test"),
|
||||
expectedStatusCode: HttpStatusCode.OK
|
||||
);
|
||||
expectedStatusCode: HttpStatusCode.OK,
|
||||
ct: _ct);
|
||||
|
||||
[Fact]
|
||||
public async Task anonymous_call_to_user_token_requirement_route_should_fail() => await YarpBasedBffHost.BrowserClient.CallBffHostApi(
|
||||
public async Task anonymous_call_to_user_token_requirement_route_should_fail()
|
||||
=> await YarpBasedBffHost.BrowserClient.CallBffHostApi(
|
||||
url: YarpBasedBffHost.Url("/api_user/test"),
|
||||
expectedStatusCode: HttpStatusCode.Unauthorized
|
||||
);
|
||||
expectedStatusCode: HttpStatusCode.Unauthorized,
|
||||
ct: _ct);
|
||||
|
||||
[Fact]
|
||||
public async Task anonymous_call_to_optional_user_token_route_should_succeed()
|
||||
{
|
||||
ApiResponse apiResult = await YarpBasedBffHost.BrowserClient.CallBffHostApi(
|
||||
url: YarpBasedBffHost.Url("/api_optional_user/test")
|
||||
);
|
||||
url: YarpBasedBffHost.Url("/api_optional_user/test"),
|
||||
ct: _ct);
|
||||
|
||||
apiResult.Method.ShouldBe("GET");
|
||||
apiResult.Path.ShouldBe("/api_optional_user/test");
|
||||
|
|
@ -55,8 +60,8 @@ public class YarpRemoteEndpointTests(ITestOutputHelper output) : YarpBffIntegrat
|
|||
public async Task call_to_api_badly_cased_anti_forgery()
|
||||
{
|
||||
var result = await YarpBasedBffHost.BrowserClient.GetAsync(
|
||||
new Uri(YarpBasedBffHost.Url("/api_badly_cased_anti_forgery/test"))
|
||||
);
|
||||
new Uri(YarpBasedBffHost.Url("/api_badly_cased_anti_forgery/test")),
|
||||
_ct);
|
||||
|
||||
result.StatusCode.ShouldBe(HttpStatusCode.Unauthorized);
|
||||
|
||||
|
|
@ -67,10 +72,9 @@ public class YarpRemoteEndpointTests(ITestOutputHelper output) : YarpBffIntegrat
|
|||
{
|
||||
await YarpBasedBffHost.BffLoginAsync("alice");
|
||||
|
||||
|
||||
ApiResponse apiResult = await YarpBasedBffHost.BrowserClient.CallBffHostApi(
|
||||
YarpBasedBffHost.Url("/api_badly_cased_optional_token/test")
|
||||
);
|
||||
YarpBasedBffHost.Url("/api_badly_cased_optional_token/test"),
|
||||
ct: _ct);
|
||||
|
||||
apiResult.Method.ShouldBe("GET");
|
||||
apiResult.Sub.ShouldBe("alice");
|
||||
|
|
@ -86,8 +90,8 @@ public class YarpRemoteEndpointTests(ITestOutputHelper output) : YarpBffIntegrat
|
|||
await YarpBasedBffHost.BffLoginAsync("alice");
|
||||
|
||||
ApiResponse apiResult = await YarpBasedBffHost.BrowserClient.CallBffHostApi(
|
||||
url: YarpBasedBffHost.Url(route)
|
||||
);
|
||||
url: YarpBasedBffHost.Url(route),
|
||||
ct: _ct);
|
||||
|
||||
apiResult.Method.ShouldBe("GET");
|
||||
apiResult.Path.ShouldBe(route);
|
||||
|
|
@ -104,8 +108,8 @@ public class YarpRemoteEndpointTests(ITestOutputHelper output) : YarpBffIntegrat
|
|||
|
||||
ApiResponse apiResult = await YarpBasedBffHost.BrowserClient.CallBffHostApi(
|
||||
url: YarpBasedBffHost.Url(route),
|
||||
method: HttpMethod.Put
|
||||
);
|
||||
method: HttpMethod.Put,
|
||||
ct: _ct);
|
||||
|
||||
apiResult.Method.ShouldBe("PUT");
|
||||
apiResult.Path.ShouldBe(route);
|
||||
|
|
@ -122,8 +126,8 @@ public class YarpRemoteEndpointTests(ITestOutputHelper output) : YarpBffIntegrat
|
|||
|
||||
ApiResponse apiResult = await YarpBasedBffHost.BrowserClient.CallBffHostApi(
|
||||
url: YarpBasedBffHost.Url(route),
|
||||
method: HttpMethod.Post
|
||||
);
|
||||
method: HttpMethod.Post,
|
||||
ct: _ct);
|
||||
|
||||
apiResult.Method.ShouldBe("POST");
|
||||
apiResult.Path.ShouldBe(route);
|
||||
|
|
@ -137,8 +141,8 @@ public class YarpRemoteEndpointTests(ITestOutputHelper output) : YarpBffIntegrat
|
|||
await YarpBasedBffHost.BffLoginAsync("alice");
|
||||
|
||||
ApiResponse apiResult = await YarpBasedBffHost.BrowserClient.CallBffHostApi(
|
||||
url: YarpBasedBffHost.Url("/api_client/test")
|
||||
);
|
||||
url: YarpBasedBffHost.Url("/api_client/test"),
|
||||
ct: _ct);
|
||||
|
||||
apiResult.Method.ShouldBe("GET");
|
||||
apiResult.Path.ShouldBe("/api_client/test");
|
||||
|
|
@ -151,8 +155,8 @@ public class YarpRemoteEndpointTests(ITestOutputHelper output) : YarpBffIntegrat
|
|||
{
|
||||
{
|
||||
ApiResponse apiResult = await YarpBasedBffHost.BrowserClient.CallBffHostApi(
|
||||
url: YarpBasedBffHost.Url("/api_user_or_client/test")
|
||||
);
|
||||
url: YarpBasedBffHost.Url("/api_user_or_client/test"),
|
||||
ct: _ct);
|
||||
|
||||
apiResult.Method.ShouldBe("GET");
|
||||
apiResult.Path.ShouldBe("/api_user_or_client/test");
|
||||
|
|
@ -164,8 +168,8 @@ public class YarpRemoteEndpointTests(ITestOutputHelper output) : YarpBffIntegrat
|
|||
await YarpBasedBffHost.BffLoginAsync("alice");
|
||||
|
||||
ApiResponse apiResult = await YarpBasedBffHost.BrowserClient.CallBffHostApi(
|
||||
url: YarpBasedBffHost.Url("/api_user_or_client/test")
|
||||
);
|
||||
url: YarpBasedBffHost.Url("/api_user_or_client/test"),
|
||||
ct: _ct);
|
||||
|
||||
apiResult.Method.ShouldBe("GET");
|
||||
apiResult.Path.ShouldBe("/api_user_or_client/test");
|
||||
|
|
@ -182,8 +186,8 @@ public class YarpRemoteEndpointTests(ITestOutputHelper output) : YarpBffIntegrat
|
|||
|
||||
var response = await YarpBasedBffHost.BrowserClient.CallBffHostApi(
|
||||
url: YarpBasedBffHost.Url("/api_user/test"),
|
||||
expectedStatusCode: HttpStatusCode.Unauthorized
|
||||
);
|
||||
expectedStatusCode: HttpStatusCode.Unauthorized,
|
||||
ct: _ct);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
|
@ -192,18 +196,17 @@ public class YarpRemoteEndpointTests(ITestOutputHelper output) : YarpBffIntegrat
|
|||
await YarpBasedBffHost.BffLoginAsync("alice");
|
||||
ApiHost.ApiStatusCodeToReturn = 403;
|
||||
|
||||
var response = await YarpBasedBffHost.BrowserClient.CallBffHostApi(
|
||||
_ = await YarpBasedBffHost.BrowserClient.CallBffHostApi(
|
||||
url: YarpBasedBffHost.Url("/api_user/test"),
|
||||
expectedStatusCode: HttpStatusCode.Forbidden
|
||||
);
|
||||
expectedStatusCode: HttpStatusCode.Forbidden,
|
||||
ct: _ct);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task invalid_configuration_of_routes_should_return_500()
|
||||
{
|
||||
var response = await YarpBasedBffHost.BrowserClient.CallBffHostApi(
|
||||
=>
|
||||
_ = await YarpBasedBffHost.BrowserClient.CallBffHostApi(
|
||||
url: YarpBasedBffHost.Url("/api_invalid/test"),
|
||||
expectedStatusCode: HttpStatusCode.InternalServerError
|
||||
);
|
||||
}
|
||||
expectedStatusCode: HttpStatusCode.InternalServerError,
|
||||
ct: _ct);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,12 +4,13 @@
|
|||
using System.Net;
|
||||
using Duende.Bff.Tests.TestFramework;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Xunit.Abstractions;
|
||||
|
||||
namespace Duende.Bff.Tests;
|
||||
|
||||
public class GenericHostTests(ITestOutputHelper output)
|
||||
{
|
||||
private readonly CancellationToken _ct = TestContext.Current.CancellationToken;
|
||||
|
||||
[Fact]
|
||||
public async Task Test1()
|
||||
{
|
||||
|
|
@ -21,7 +22,7 @@ public class GenericHostTests(ITestOutputHelper output)
|
|||
});
|
||||
await host.InitializeAsync();
|
||||
|
||||
var response = await host.HttpClient.GetAsync("/test");
|
||||
var response = await host.HttpClient.GetAsync("/test", _ct);
|
||||
|
||||
response.StatusCode.ShouldBe(HttpStatusCode.NoContent);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,12 +4,13 @@
|
|||
using System.Text.Json;
|
||||
using Duende.Bff.Tests.TestFramework;
|
||||
using Duende.Bff.Tests.TestHosts;
|
||||
using Xunit.Abstractions;
|
||||
|
||||
namespace Duende.Bff.Tests.Headers;
|
||||
|
||||
public class ApiAndBffUseForwardedHeaders : BffIntegrationTestBase
|
||||
{
|
||||
private readonly CancellationToken _ct = TestContext.Current.CancellationToken;
|
||||
|
||||
public ApiAndBffUseForwardedHeaders(ITestOutputHelper output) : base(output)
|
||||
{
|
||||
BffHost.UseForwardedHeaders = true;
|
||||
|
|
@ -21,10 +22,10 @@ public class ApiAndBffUseForwardedHeaders : BffIntegrationTestBase
|
|||
{
|
||||
var req = new HttpRequestMessage(HttpMethod.Get, BffHost.Url("/api_anon_only/test"));
|
||||
req.Headers.Add("x-csrf", "1");
|
||||
var response = await BffHost.BrowserClient.SendAsync(req);
|
||||
var response = await BffHost.BrowserClient.SendAsync(req, _ct);
|
||||
|
||||
response.IsSuccessStatusCode.ShouldBeTrue();
|
||||
var json = await response.Content.ReadAsStringAsync();
|
||||
var json = await response.Content.ReadAsStringAsync(_ct);
|
||||
var apiResult = JsonSerializer.Deserialize<ApiResponse>(json).ShouldNotBeNull();
|
||||
|
||||
var host = apiResult.RequestHeaders["Host"].Single();
|
||||
|
|
@ -39,10 +40,10 @@ public class ApiAndBffUseForwardedHeaders : BffIntegrationTestBase
|
|||
var req = new HttpRequestMessage(HttpMethod.Get, BffHost.Url("/api_anon_only/test"));
|
||||
req.Headers.Add("x-csrf", "1");
|
||||
req.Headers.Add("X-Forwarded-Host", "external");
|
||||
var response = await BffHost.BrowserClient.SendAsync(req);
|
||||
var response = await BffHost.BrowserClient.SendAsync(req, _ct);
|
||||
|
||||
response.IsSuccessStatusCode.ShouldBeTrue();
|
||||
var json = await response.Content.ReadAsStringAsync();
|
||||
var json = await response.Content.ReadAsStringAsync(_ct);
|
||||
var apiResult = JsonSerializer.Deserialize<ApiResponse>(json).ShouldNotBeNull();
|
||||
|
||||
var host = apiResult.RequestHeaders["Host"].Single();
|
||||
|
|
@ -57,10 +58,10 @@ public class ApiAndBffUseForwardedHeaders : BffIntegrationTestBase
|
|||
var req = new HttpRequestMessage(HttpMethod.Get, BffHost.Url("/api_anon_only/test"));
|
||||
req.Headers.Add("x-csrf", "1");
|
||||
req.Headers.Add("X-Forwarded-Host", "external");
|
||||
var response = await BffHost.BrowserClient.SendAsync(req);
|
||||
var response = await BffHost.BrowserClient.SendAsync(req, _ct);
|
||||
|
||||
response.IsSuccessStatusCode.ShouldBeTrue();
|
||||
var json = await response.Content.ReadAsStringAsync();
|
||||
var json = await response.Content.ReadAsStringAsync(_ct);
|
||||
var apiResult = JsonSerializer.Deserialize<ApiResponse>(json).ShouldNotBeNull();
|
||||
|
||||
var host = apiResult.RequestHeaders["Host"].Single();
|
||||
|
|
|
|||
|
|
@ -4,23 +4,25 @@
|
|||
using System.Text.Json;
|
||||
using Duende.Bff.Tests.TestFramework;
|
||||
using Duende.Bff.Tests.TestHosts;
|
||||
using Xunit.Abstractions;
|
||||
|
||||
namespace Duende.Bff.Tests.Headers;
|
||||
|
||||
public class ApiUseForwardedHeaders : BffIntegrationTestBase
|
||||
{
|
||||
public ApiUseForwardedHeaders(ITestOutputHelper output) : base(output) => ApiHost.UseForwardedHeaders = true;
|
||||
private readonly CancellationToken _ct = TestContext.Current.CancellationToken;
|
||||
|
||||
public ApiUseForwardedHeaders(ITestOutputHelper output)
|
||||
: base(output) => ApiHost.UseForwardedHeaders = true;
|
||||
|
||||
[Fact]
|
||||
public async Task bff_host_name_should_propagate_to_api()
|
||||
{
|
||||
var req = new HttpRequestMessage(HttpMethod.Get, BffHost.Url("/api_anon_only/test"));
|
||||
req.Headers.Add("x-csrf", "1");
|
||||
var response = await BffHost.BrowserClient.SendAsync(req);
|
||||
var response = await BffHost.BrowserClient.SendAsync(req, _ct);
|
||||
|
||||
response.IsSuccessStatusCode.ShouldBeTrue();
|
||||
var json = await response.Content.ReadAsStringAsync();
|
||||
var json = await response.Content.ReadAsStringAsync(_ct);
|
||||
var apiResult = JsonSerializer.Deserialize<ApiResponse>(json).ShouldNotBeNull();
|
||||
|
||||
var host = apiResult.RequestHeaders["Host"].Single();
|
||||
|
|
@ -33,10 +35,10 @@ public class ApiUseForwardedHeaders : BffIntegrationTestBase
|
|||
var req = new HttpRequestMessage(HttpMethod.Get, BffHost.Url("/api_anon_only/test"));
|
||||
req.Headers.Add("x-csrf", "1");
|
||||
req.Headers.Add("X-Forwarded-Host", "external");
|
||||
var response = await BffHost.BrowserClient.SendAsync(req);
|
||||
var response = await BffHost.BrowserClient.SendAsync(req, _ct);
|
||||
|
||||
response.IsSuccessStatusCode.ShouldBeTrue();
|
||||
var json = await response.Content.ReadAsStringAsync();
|
||||
var json = await response.Content.ReadAsStringAsync(_ct);
|
||||
var apiResult = JsonSerializer.Deserialize<ApiResponse>(json).ShouldNotBeNull();
|
||||
|
||||
var host = apiResult.RequestHeaders["Host"].Single();
|
||||
|
|
|
|||
|
|
@ -4,21 +4,22 @@
|
|||
using System.Text.Json;
|
||||
using Duende.Bff.Tests.TestFramework;
|
||||
using Duende.Bff.Tests.TestHosts;
|
||||
using Xunit.Abstractions;
|
||||
|
||||
namespace Duende.Bff.Tests.Headers;
|
||||
|
||||
public class General(ITestOutputHelper output) : BffIntegrationTestBase(output)
|
||||
{
|
||||
private readonly CancellationToken _ct = TestContext.Current.CancellationToken;
|
||||
|
||||
[Fact]
|
||||
public async Task local_endpoint_should_receive_standard_headers()
|
||||
{
|
||||
var req = new HttpRequestMessage(HttpMethod.Get, BffHost.Url("/local_anon"));
|
||||
req.Headers.Add("x-csrf", "1");
|
||||
var response = await BffHost.BrowserClient.SendAsync(req);
|
||||
var response = await BffHost.BrowserClient.SendAsync(req, _ct);
|
||||
|
||||
response.IsSuccessStatusCode.ShouldBeTrue();
|
||||
var json = await response.Content.ReadAsStringAsync();
|
||||
var json = await response.Content.ReadAsStringAsync(_ct);
|
||||
var apiResult = JsonSerializer.Deserialize<ApiResponse>(json).ShouldNotBeNull();
|
||||
|
||||
apiResult.RequestHeaders.Count.ShouldBe(2);
|
||||
|
|
@ -34,10 +35,10 @@ public class General(ITestOutputHelper output) : BffIntegrationTestBase(output)
|
|||
var req = new HttpRequestMessage(HttpMethod.Get, BffHost.Url("/api_anon_only/test"));
|
||||
req.Headers.Add("x-csrf", "1");
|
||||
req.Headers.Add("x-custom", "custom");
|
||||
var response = await BffHost.BrowserClient.SendAsync(req);
|
||||
var response = await BffHost.BrowserClient.SendAsync(req, _ct);
|
||||
|
||||
response.IsSuccessStatusCode.ShouldBeTrue();
|
||||
var json = await response.Content.ReadAsStringAsync();
|
||||
var json = await response.Content.ReadAsStringAsync(_ct);
|
||||
var apiResult = JsonSerializer.Deserialize<ApiResponse>(json).ShouldNotBeNull();
|
||||
|
||||
apiResult.RequestHeaders["Host"].Single().ShouldBe("api");
|
||||
|
|
@ -52,10 +53,10 @@ public class General(ITestOutputHelper output) : BffIntegrationTestBase(output)
|
|||
var req = new HttpRequestMessage(HttpMethod.Get, BffHost.Url("/api_anon_only/test"));
|
||||
req.Headers.Add("x-csrf", "1");
|
||||
req.Headers.Add("x-custom", "custom");
|
||||
var response = await BffHost.BrowserClient.SendAsync(req);
|
||||
var response = await BffHost.BrowserClient.SendAsync(req, _ct);
|
||||
|
||||
response.IsSuccessStatusCode.ShouldBeTrue();
|
||||
var json = await response.Content.ReadAsStringAsync();
|
||||
var json = await response.Content.ReadAsStringAsync(_ct);
|
||||
var apiResult = JsonSerializer.Deserialize<ApiResponse>(json).ShouldNotBeNull();
|
||||
|
||||
apiResult.RequestHeaders["X-Forwarded-Host"].Single().ShouldBe("app");
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@ using Microsoft.AspNetCore.Builder;
|
|||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Logging.Abstractions;
|
||||
using Xunit.Abstractions;
|
||||
|
||||
namespace Duende.Bff.Tests;
|
||||
|
||||
|
|
@ -15,14 +14,15 @@ namespace Duende.Bff.Tests;
|
|||
/// </summary>
|
||||
public class IAccessTokenRetriever_Extensibility_tests : BffIntegrationTestBase
|
||||
{
|
||||
private readonly CancellationToken _ct = TestContext.Current.CancellationToken;
|
||||
|
||||
private ContextCapturingAccessTokenRetriever _customAccessTokenReceiver { get; } = new(NullLogger<DefaultAccessTokenRetriever>.Instance);
|
||||
private ContextCapturingAccessTokenRetriever CustomAccessTokenReceiver { get; } = new(NullLogger<DefaultAccessTokenRetriever>.Instance);
|
||||
|
||||
public IAccessTokenRetriever_Extensibility_tests(ITestOutputHelper output) : base(output)
|
||||
{
|
||||
BffHost.OnConfigureServices += services =>
|
||||
{
|
||||
services.AddSingleton(_customAccessTokenReceiver);
|
||||
services.AddSingleton(CustomAccessTokenReceiver);
|
||||
};
|
||||
|
||||
BffHost.OnConfigure += app =>
|
||||
|
|
@ -55,9 +55,9 @@ public class IAccessTokenRetriever_Extensibility_tests : BffIntegrationTestBase
|
|||
{
|
||||
await BffHost.BffLoginAsync("alice");
|
||||
|
||||
await BffHost.BrowserClient.CallBffHostApi(BffHost.Url("/custom"));
|
||||
await BffHost.BrowserClient.CallBffHostApi(BffHost.Url("/custom"), ct: _ct);
|
||||
|
||||
var usedContext = _customAccessTokenReceiver.UsedContext.ShouldNotBeNull();
|
||||
var usedContext = CustomAccessTokenReceiver.UsedContext.ShouldNotBeNull();
|
||||
|
||||
usedContext.Metadata.RequiredTokenType.ShouldBe(TokenType.User);
|
||||
|
||||
|
|
@ -71,9 +71,9 @@ public class IAccessTokenRetriever_Extensibility_tests : BffIntegrationTestBase
|
|||
{
|
||||
await BffHost.BffLoginAsync("alice");
|
||||
|
||||
await BffHost.BrowserClient.CallBffHostApi(BffHost.Url("/subPath/custom_within_subpath"));
|
||||
await BffHost.BrowserClient.CallBffHostApi(BffHost.Url("/subPath/custom_within_subpath"), ct: _ct);
|
||||
|
||||
var usedContext = _customAccessTokenReceiver.UsedContext.ShouldNotBeNull();
|
||||
var usedContext = CustomAccessTokenReceiver.UsedContext.ShouldNotBeNull();
|
||||
|
||||
usedContext.ApiAddress.ShouldBe(new Uri(ApiHost.Url("/some/path")));
|
||||
usedContext.LocalPath.ToString().ShouldBe("/custom_within_subpath");
|
||||
|
|
@ -83,12 +83,10 @@ public class IAccessTokenRetriever_Extensibility_tests : BffIntegrationTestBase
|
|||
/// <summary>
|
||||
/// Captures the context in which the access token retriever is called, so we can assert on it
|
||||
/// </summary>
|
||||
private class ContextCapturingAccessTokenRetriever : DefaultAccessTokenRetriever
|
||||
private class ContextCapturingAccessTokenRetriever(ILogger<DefaultAccessTokenRetriever> logger)
|
||||
: DefaultAccessTokenRetriever(logger)
|
||||
{
|
||||
public AccessTokenRetrievalContext? UsedContext { get; private set; }
|
||||
public ContextCapturingAccessTokenRetriever(ILogger<DefaultAccessTokenRetriever> logger) : base(logger)
|
||||
{
|
||||
}
|
||||
|
||||
public override Task<AccessTokenResult> GetAccessToken(AccessTokenRetrievalContext context)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -5,26 +5,27 @@ using Duende.Bff.Tests.TestHosts;
|
|||
using Microsoft.AspNetCore.Authentication.Cookies;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Time.Testing;
|
||||
using Xunit.Abstractions;
|
||||
|
||||
|
||||
namespace Duende.Bff.Tests.SessionManagement;
|
||||
|
||||
public class CookieSlidingTests : BffIntegrationTestBase
|
||||
{
|
||||
readonly InMemoryUserSessionStore _sessionStore = new();
|
||||
readonly FakeTimeProvider _clock = new(DateTime.UtcNow);
|
||||
private readonly CancellationToken _ct = TestContext.Current.CancellationToken;
|
||||
private readonly InMemoryUserSessionStore _sessionStore = new();
|
||||
private readonly FakeTimeProvider _clock = new(DateTime.UtcNow);
|
||||
|
||||
public CookieSlidingTests(ITestOutputHelper output) : base(output) => BffHost.OnConfigureServices += services =>
|
||||
{
|
||||
services.AddSingleton<IUserSessionStore>(_sessionStore);
|
||||
services.Configure<CookieAuthenticationOptions>("cookie", options =>
|
||||
{
|
||||
options.SlidingExpiration = true;
|
||||
options.ExpireTimeSpan = TimeSpan.FromMinutes(10);
|
||||
});
|
||||
services.AddSingleton<TimeProvider>(_clock);
|
||||
};
|
||||
public CookieSlidingTests(ITestOutputHelper output) : base(output)
|
||||
=> BffHost.OnConfigureServices += services =>
|
||||
{
|
||||
services.AddSingleton<IUserSessionStore>(_sessionStore);
|
||||
services.Configure<CookieAuthenticationOptions>("cookie", options =>
|
||||
{
|
||||
options.SlidingExpiration = true;
|
||||
options.ExpireTimeSpan = TimeSpan.FromMinutes(10);
|
||||
});
|
||||
services.AddSingleton<TimeProvider>(_clock);
|
||||
};
|
||||
|
||||
private void SetClock(TimeSpan t) => _clock.SetUtcNow(_clock.GetUtcNow().Add(t));
|
||||
|
||||
|
|
@ -33,19 +34,19 @@ public class CookieSlidingTests : BffIntegrationTestBase
|
|||
{
|
||||
await BffHost.BffLoginAsync("alice");
|
||||
|
||||
var sessions = await _sessionStore.GetUserSessionsAsync(new UserSessionsFilter { SubjectId = "alice" });
|
||||
var sessions = await _sessionStore.GetUserSessionsAsync(new UserSessionsFilter { SubjectId = "alice" }, _ct);
|
||||
sessions.Count().ShouldBe(1);
|
||||
|
||||
var session = sessions.Single();
|
||||
|
||||
var ticketStore = BffHost.Resolve<IServerTicketStore>();
|
||||
var firstTicket = await ticketStore.RetrieveAsync(session.Key);
|
||||
var firstTicket = await ticketStore.RetrieveAsync(session.Key, _ct);
|
||||
firstTicket.ShouldNotBeNull();
|
||||
|
||||
SetClock(TimeSpan.FromMinutes(8));
|
||||
(await BffHost.GetIsUserLoggedInAsync()).ShouldBeTrue();
|
||||
|
||||
var secondTicket = await ticketStore.RetrieveAsync(session.Key);
|
||||
var secondTicket = await ticketStore.RetrieveAsync(session.Key, _ct);
|
||||
secondTicket.ShouldNotBeNull();
|
||||
|
||||
(secondTicket.Properties.IssuedUtc > firstTicket.Properties.IssuedUtc).ShouldBeTrue();
|
||||
|
|
@ -57,19 +58,19 @@ public class CookieSlidingTests : BffIntegrationTestBase
|
|||
{
|
||||
await BffHost.BffLoginAsync("alice");
|
||||
|
||||
var sessions = await _sessionStore.GetUserSessionsAsync(new UserSessionsFilter { SubjectId = "alice" });
|
||||
var sessions = await _sessionStore.GetUserSessionsAsync(new UserSessionsFilter { SubjectId = "alice" }, _ct);
|
||||
sessions.Count().ShouldBe(1);
|
||||
|
||||
var session = sessions.Single();
|
||||
|
||||
var ticketStore = BffHost.Resolve<IServerTicketStore>();
|
||||
var firstTicket = await ticketStore.RetrieveAsync(session.Key);
|
||||
var firstTicket = await ticketStore.RetrieveAsync(session.Key, _ct);
|
||||
firstTicket.ShouldNotBeNull();
|
||||
|
||||
SetClock(TimeSpan.FromMinutes(8));
|
||||
(await BffHost.GetIsUserLoggedInAsync("slide=false")).ShouldBeTrue();
|
||||
|
||||
var secondTicket = await ticketStore.RetrieveAsync(session.Key);
|
||||
var secondTicket = await ticketStore.RetrieveAsync(session.Key, _ct);
|
||||
secondTicket.ShouldNotBeNull();
|
||||
|
||||
(secondTicket.Properties.IssuedUtc == firstTicket.Properties.IssuedUtc).ShouldBeTrue();
|
||||
|
|
@ -96,20 +97,20 @@ public class CookieSlidingTests : BffIntegrationTestBase
|
|||
|
||||
await BffHost.BffLoginAsync("alice");
|
||||
|
||||
var sessions = await _sessionStore.GetUserSessionsAsync(new UserSessionsFilter { SubjectId = "alice" });
|
||||
var sessions = await _sessionStore.GetUserSessionsAsync(new UserSessionsFilter { SubjectId = "alice" }, _ct);
|
||||
sessions.Count().ShouldBe(1);
|
||||
|
||||
var session = sessions.Single();
|
||||
|
||||
var ticketStore = BffHost.Resolve<IServerTicketStore>();
|
||||
var firstTicket = await ticketStore.RetrieveAsync(session.Key);
|
||||
var firstTicket = await ticketStore.RetrieveAsync(session.Key, _ct);
|
||||
firstTicket.ShouldNotBeNull();
|
||||
|
||||
shouldRenew = true;
|
||||
SetClock(TimeSpan.FromSeconds(1));
|
||||
(await BffHost.GetIsUserLoggedInAsync()).ShouldBeTrue();
|
||||
|
||||
var secondTicket = await ticketStore.RetrieveAsync(session.Key);
|
||||
var secondTicket = await ticketStore.RetrieveAsync(session.Key, _ct);
|
||||
secondTicket.ShouldNotBeNull();
|
||||
|
||||
(secondTicket.Properties.IssuedUtc > firstTicket.Properties.IssuedUtc).ShouldBeTrue();
|
||||
|
|
@ -137,20 +138,20 @@ public class CookieSlidingTests : BffIntegrationTestBase
|
|||
|
||||
await BffHost.BffLoginAsync("alice");
|
||||
|
||||
var sessions = await _sessionStore.GetUserSessionsAsync(new UserSessionsFilter { SubjectId = "alice" });
|
||||
var sessions = await _sessionStore.GetUserSessionsAsync(new UserSessionsFilter { SubjectId = "alice" }, _ct);
|
||||
sessions.Count().ShouldBe(1);
|
||||
|
||||
var session = sessions.Single();
|
||||
|
||||
var ticketStore = BffHost.Resolve<IServerTicketStore>();
|
||||
var firstTicket = await ticketStore.RetrieveAsync(session.Key);
|
||||
var firstTicket = await ticketStore.RetrieveAsync(session.Key, _ct);
|
||||
firstTicket.ShouldNotBeNull();
|
||||
|
||||
shouldRenew = true;
|
||||
SetClock(TimeSpan.FromSeconds(1));
|
||||
(await BffHost.GetIsUserLoggedInAsync("slide=false")).ShouldBeTrue();
|
||||
|
||||
var secondTicket = await ticketStore.RetrieveAsync(session.Key);
|
||||
var secondTicket = await ticketStore.RetrieveAsync(session.Key, _ct);
|
||||
secondTicket.ShouldNotBeNull();
|
||||
|
||||
(secondTicket.Properties.IssuedUtc == firstTicket.Properties.IssuedUtc).ShouldBeTrue();
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@
|
|||
using Duende.Bff.Tests.TestHosts;
|
||||
using Duende.IdentityServer.Stores;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Xunit.Abstractions;
|
||||
|
||||
namespace Duende.Bff.Tests.SessionManagement;
|
||||
|
||||
|
|
|
|||
|
|
@ -3,18 +3,19 @@
|
|||
|
||||
using Duende.Bff.Tests.TestHosts;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Xunit.Abstractions;
|
||||
|
||||
namespace Duende.Bff.Tests.SessionManagement;
|
||||
|
||||
public class ServerSideTicketStoreTests : BffIntegrationTestBase
|
||||
{
|
||||
private readonly CancellationToken _ct = TestContext.Current.CancellationToken;
|
||||
readonly InMemoryUserSessionStore _sessionStore = new();
|
||||
|
||||
public ServerSideTicketStoreTests(ITestOutputHelper output) : base(output) => BffHost.OnConfigureServices += services =>
|
||||
{
|
||||
services.AddSingleton<IUserSessionStore>(_sessionStore);
|
||||
};
|
||||
public ServerSideTicketStoreTests(ITestOutputHelper output) : base(output)
|
||||
=> BffHost.OnConfigureServices += services =>
|
||||
{
|
||||
services.AddSingleton<IUserSessionStore>(_sessionStore);
|
||||
};
|
||||
|
||||
[Fact]
|
||||
public async Task StoreAsync_should_remove_conflicting_entries_prior_to_creating_new_entry()
|
||||
|
|
@ -22,10 +23,13 @@ public class ServerSideTicketStoreTests : BffIntegrationTestBase
|
|||
await BffHost.BffLoginAsync("alice");
|
||||
|
||||
BffHost.BrowserClient.RemoveCookie("bff");
|
||||
(await _sessionStore.GetUserSessionsAsync(new UserSessionsFilter { SubjectId = "alice" })).Count().ShouldBe(1);
|
||||
var userSessionsFilter = new UserSessionsFilter { SubjectId = "alice" };
|
||||
var result = await _sessionStore.GetUserSessionsAsync(userSessionsFilter, _ct);
|
||||
result.Count.ShouldBe(1);
|
||||
|
||||
await BffHost.BffOidcLoginAsync();
|
||||
|
||||
(await _sessionStore.GetUserSessionsAsync(new UserSessionsFilter { SubjectId = "alice" })).Count().ShouldBe(1);
|
||||
result = await _sessionStore.GetUserSessionsAsync(userSessionsFilter, _ct);
|
||||
result.Count.ShouldBe(1);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@ public class GenericHost(WriteTestOutput writeOutput, string baseAddress = "http
|
|||
return _baseAddress + path;
|
||||
}
|
||||
|
||||
public async Task InitializeAsync()
|
||||
public async ValueTask InitializeAsync()
|
||||
{
|
||||
var hostBuilder = new HostBuilder()
|
||||
.ConfigureWebHost(builder =>
|
||||
|
|
|
|||
|
|
@ -6,18 +6,17 @@ using Duende.IdentityServer.Models;
|
|||
using Duende.IdentityServer.Services;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Xunit.Abstractions;
|
||||
|
||||
namespace Duende.Bff.Tests.TestHosts;
|
||||
|
||||
public class BffIntegrationTestBase : OutputWritingTestBase
|
||||
{
|
||||
protected readonly IdentityServerHost IdentityServerHost;
|
||||
protected ApiHost ApiHost;
|
||||
protected BffHost BffHost;
|
||||
protected BffHostUsingResourceNamedTokens BffHostWithNamedTokens;
|
||||
protected readonly ApiHost ApiHost;
|
||||
protected readonly BffHost BffHost;
|
||||
protected readonly BffHostUsingResourceNamedTokens BffHostWithNamedTokens;
|
||||
|
||||
public BffIntegrationTestBase(ITestOutputHelper output) : base(output)
|
||||
protected BffIntegrationTestBase(ITestOutputHelper output) : base(output)
|
||||
{
|
||||
IdentityServerHost = new IdentityServerHost(WriteLine);
|
||||
ApiHost = new ApiHost(WriteLine, IdentityServerHost, "scope1");
|
||||
|
|
@ -47,12 +46,11 @@ public class BffIntegrationTestBase : OutputWritingTestBase
|
|||
|
||||
services.AddSingleton<DefaultAccessTokenRetriever>();
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
public async Task Login(string sub) => await IdentityServerHost.IssueSessionCookieAsync(new Claim("sub", sub));
|
||||
|
||||
public override async Task InitializeAsync()
|
||||
public override async ValueTask InitializeAsync()
|
||||
{
|
||||
await IdentityServerHost.InitializeAsync();
|
||||
await ApiHost.InitializeAsync();
|
||||
|
|
@ -61,13 +59,12 @@ public class BffIntegrationTestBase : OutputWritingTestBase
|
|||
await base.InitializeAsync();
|
||||
}
|
||||
|
||||
public override async Task DisposeAsync()
|
||||
public override async ValueTask DisposeAsync()
|
||||
{
|
||||
await ApiHost.DisposeAsync();
|
||||
await BffHost.DisposeAsync();
|
||||
await BffHostWithNamedTokens.DisposeAsync();
|
||||
await IdentityServerHost.DisposeAsync();
|
||||
await base.DisposeAsync();
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,15 +2,16 @@
|
|||
// See LICENSE in the project root for license information.
|
||||
|
||||
using System.Text;
|
||||
using Xunit.Abstractions;
|
||||
|
||||
namespace Duende.Bff.Tests.TestHosts;
|
||||
|
||||
public class OutputWritingTestBase(ITestOutputHelper testOutputHelper) : IAsyncLifetime
|
||||
{
|
||||
private readonly StringBuilder _output = new StringBuilder();
|
||||
private readonly StringBuilder _output = new();
|
||||
|
||||
public void WriteLine(string message)
|
||||
public virtual ValueTask InitializeAsync() => default;
|
||||
|
||||
protected void WriteLine(string message)
|
||||
{
|
||||
lock (_output)
|
||||
{
|
||||
|
|
@ -18,16 +19,12 @@ public class OutputWritingTestBase(ITestOutputHelper testOutputHelper) : IAsyncL
|
|||
}
|
||||
}
|
||||
|
||||
public virtual Task InitializeAsync() => Task.CompletedTask;
|
||||
|
||||
public virtual Task DisposeAsync()
|
||||
public virtual ValueTask DisposeAsync()
|
||||
{
|
||||
lock (_output)
|
||||
{
|
||||
testOutputHelper.WriteLine(_output.ToString());
|
||||
}
|
||||
|
||||
|
||||
return Task.CompletedTask;
|
||||
return default;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@ using Duende.IdentityServer.Models;
|
|||
using Duende.IdentityServer.Services;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Xunit.Abstractions;
|
||||
|
||||
namespace Duende.Bff.Tests.TestHosts;
|
||||
|
||||
|
|
@ -51,7 +50,7 @@ public class YarpBffIntegrationTestBase : OutputWritingTestBase
|
|||
|
||||
public async Task Login(string sub) => await _identityServerHost.IssueSessionCookieAsync(new Claim("sub", sub));
|
||||
|
||||
public override async Task InitializeAsync()
|
||||
public override async ValueTask InitializeAsync()
|
||||
{
|
||||
await _identityServerHost.InitializeAsync();
|
||||
await ApiHost.InitializeAsync();
|
||||
|
|
@ -60,7 +59,7 @@ public class YarpBffIntegrationTestBase : OutputWritingTestBase
|
|||
await base.InitializeAsync();
|
||||
}
|
||||
|
||||
public override async Task DisposeAsync()
|
||||
public override async ValueTask DisposeAsync()
|
||||
{
|
||||
await _identityServerHost.DisposeAsync();
|
||||
await ApiHost.DisposeAsync();
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@
|
|||
using Hosts.ServiceDefaults;
|
||||
using Hosts.Tests.PageModels;
|
||||
using Hosts.Tests.TestInfra;
|
||||
using Xunit.Abstractions;
|
||||
|
||||
namespace Hosts.Tests;
|
||||
|
||||
|
|
@ -20,7 +19,7 @@ public class BffBlazorWebAssemblyTests(ITestOutputHelper output, AppHostFixture
|
|||
};
|
||||
}
|
||||
|
||||
[SkippableFact]
|
||||
[Fact]
|
||||
public async Task Can_login_and_load_local_api()
|
||||
{
|
||||
await Warmup();
|
||||
|
|
|
|||
|
|
@ -3,12 +3,12 @@
|
|||
|
||||
using Hosts.ServiceDefaults;
|
||||
using Hosts.Tests.TestInfra;
|
||||
using Xunit.Abstractions;
|
||||
|
||||
namespace Hosts.Tests;
|
||||
|
||||
public class BffTests : IntegrationTestBase
|
||||
{
|
||||
private readonly CancellationToken _ct = TestContext.Current.CancellationToken;
|
||||
private readonly HttpClient _httpClient;
|
||||
private readonly BffClient _bffClient;
|
||||
|
||||
|
|
@ -18,28 +18,28 @@ public class BffTests : IntegrationTestBase
|
|||
_bffClient = new BffClient(CreateHttpClient(AppHostServices.Bff));
|
||||
}
|
||||
|
||||
[SkippableFact]
|
||||
[Fact]
|
||||
public async Task Can_invoke_home()
|
||||
{
|
||||
var response = await _httpClient.GetAsync("/");
|
||||
var response = await _httpClient.GetAsync("/", _ct);
|
||||
response.StatusCode.ShouldBe(HttpStatusCode.OK);
|
||||
}
|
||||
|
||||
[SkippableFact]
|
||||
[Fact]
|
||||
public async Task Can_initiate_login()
|
||||
{
|
||||
|
||||
var response = await _httpClient.GetAsync("/");
|
||||
var response = await _httpClient.GetAsync("/", _ct);
|
||||
response.StatusCode.ShouldBe(HttpStatusCode.OK);
|
||||
|
||||
await _bffClient.TriggerLogin();
|
||||
await _bffClient.TriggerLogin(ct: _ct);
|
||||
|
||||
// Verify that there are user claims
|
||||
var claims = await _bffClient.GetUserClaims();
|
||||
claims.Any().ShouldBeTrue();
|
||||
}
|
||||
|
||||
[SkippableTheory]
|
||||
[Theory]
|
||||
[InlineData("/local/self-contained")]
|
||||
[InlineData("/local/invokes-external-api")]
|
||||
[InlineData("/api/user-token")]
|
||||
|
|
@ -51,14 +51,14 @@ public class BffTests : IntegrationTestBase
|
|||
[InlineData("/api/audience-constrained")]
|
||||
public async Task Once_authenticated_can_call_proxied_urls(string url)
|
||||
{
|
||||
await _bffClient.TriggerLogin();
|
||||
await _bffClient.TriggerLogin(ct: _ct);
|
||||
await _bffClient.InvokeApi(url);
|
||||
}
|
||||
|
||||
[SkippableFact]
|
||||
[Fact]
|
||||
public async Task Can_logout()
|
||||
{
|
||||
await _bffClient.TriggerLogin();
|
||||
await _bffClient.TriggerLogin(ct: _ct);
|
||||
await _bffClient.TriggerLogout();
|
||||
|
||||
await _bffClient.InvokeApi(url: "/local/self-contained", expectedResponse: HttpStatusCode.Unauthorized);
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@
|
|||
using Hosts.ServiceDefaults;
|
||||
using Hosts.Tests.PageModels;
|
||||
using Hosts.Tests.TestInfra;
|
||||
using Xunit.Abstractions;
|
||||
|
||||
namespace Hosts.Tests;
|
||||
|
||||
|
|
@ -21,7 +20,7 @@ public class BlazorPerComponentTests(ITestOutputHelper output, AppHostFixture fi
|
|||
};
|
||||
}
|
||||
|
||||
[SkippableFact]
|
||||
[Fact]
|
||||
public async Task Can_load_blazor_webassembly_app()
|
||||
{
|
||||
await Warmup();
|
||||
|
|
|
|||
|
|
@ -13,30 +13,25 @@
|
|||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
<PackageReference Include="AngleSharp" />
|
||||
<PackageReference Include="Aspire.Hosting.Testing" />
|
||||
<PackageReference Include="Serilog" />
|
||||
<PackageReference Include="Serilog.Extensions.Logging" />
|
||||
<PackageReference Include="Serilog.Sinks.TextWriter" />
|
||||
<PackageReference Include="Serilog.Sinks.XUnit" />
|
||||
<PackageReference Include="Serilog.Sinks.XUnit3" />
|
||||
<PackageReference Include="Serilog.AspNetCore" />
|
||||
<PackageReference Include="Aspire.Hosting.Testing" />
|
||||
<PackageReference Include="Xunit.SkippableFact" />
|
||||
<PackageReference Include="Microsoft.Playwright.Xunit" />
|
||||
|
||||
<PackageReference Include="Microsoft.Playwright.Xunit.v3" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition="'$(Configuration)' != 'Debug_NCrunch'">
|
||||
|
||||
<ProjectReference Include="..\..\hosts\Hosts.AppHost\Hosts.AppHost.csproj" />
|
||||
<Using Include="Aspire.Hosting.ApplicationModel" />
|
||||
<Using Include="Aspire.Hosting.Testing" />
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
<ItemGroup>
|
||||
<Using Include="System.Net" />
|
||||
<Using Include="Aspire.Hosting.ApplicationModel" />
|
||||
<Using Include="Aspire.Hosting.Testing" />
|
||||
<Using Include="Microsoft.Extensions.DependencyInjection" />
|
||||
<Using Include="System.Net" />
|
||||
<Using Include="Xunit" />
|
||||
</ItemGroup>
|
||||
|
||||
|
|
|
|||
|
|
@ -4,9 +4,8 @@
|
|||
using System.Reflection;
|
||||
using Hosts.Tests.TestInfra;
|
||||
using Microsoft.Playwright;
|
||||
using Microsoft.Playwright.Xunit;
|
||||
using Xunit.Abstractions;
|
||||
using Xunit.Sdk;
|
||||
using Microsoft.Playwright.Xunit.v3;
|
||||
using Xunit.v3;
|
||||
|
||||
namespace Hosts.Tests;
|
||||
|
||||
|
|
@ -31,12 +30,12 @@ public class PlaywrightTestBase : PageTest, IDisposable
|
|||
#if DEBUG_NCRUNCH
|
||||
// Running in NCrunch. NCrunch cannot build the aspire project, so it needs
|
||||
// to be started manually.
|
||||
Skip.If(true, "When running the Host.Tests using NCrunch, you must start the Hosts.AppHost project manually. IE: dotnet run -p bff/samples/Hosts.AppHost. Or start without debugging from the UI. ");
|
||||
Assert.Skip("When running the Host.Tests using NCrunch, you must start the Hosts.AppHost project manually. IE: dotnet run -p bff/samples/Hosts.AppHost. Or start without debugging from the UI. ");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
public override async Task InitializeAsync()
|
||||
public override async ValueTask InitializeAsync()
|
||||
{
|
||||
await base.InitializeAsync();
|
||||
Context.SetDefaultTimeout(10_000);
|
||||
|
|
@ -49,7 +48,7 @@ public class PlaywrightTestBase : PageTest, IDisposable
|
|||
});
|
||||
}
|
||||
|
||||
public override async Task DisposeAsync()
|
||||
public override async ValueTask DisposeAsync()
|
||||
{
|
||||
var path = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) ?? Environment.CurrentDirectory;
|
||||
// if path ends with /bin/{build configuration}/{dotnetversion}, then strip that from the path.
|
||||
|
|
@ -59,7 +58,6 @@ public class PlaywrightTestBase : PageTest, IDisposable
|
|||
path = Path.GetFullPath(Path.Combine(path, "../../../"));
|
||||
}
|
||||
|
||||
|
||||
await Context.Tracing.StopAsync(new()
|
||||
{
|
||||
Path = Path.Combine(
|
||||
|
|
@ -106,18 +104,17 @@ public class PlaywrightTestBase : PageTest, IDisposable
|
|||
public HttpClient CreateHttpClient(string clientName) => Fixture.CreateHttpClient(clientName);
|
||||
}
|
||||
|
||||
public class WithTestNameAttribute : BeforeAfterTestAttribute
|
||||
public class WithTestNameAttribute : Attribute, IBeforeAfterTestAttribute
|
||||
{
|
||||
public static string CurrentTestName = string.Empty;
|
||||
public static string CurrentClassName = string.Empty;
|
||||
|
||||
public override void Before(MethodInfo methodInfo)
|
||||
public void Before(MethodInfo methodInfo, IXunitTest _)
|
||||
{
|
||||
CurrentTestName = methodInfo.Name;
|
||||
CurrentClassName = methodInfo.DeclaringType!.Name;
|
||||
}
|
||||
|
||||
public override void After(MethodInfo methodInfo)
|
||||
{
|
||||
}
|
||||
public void After(MethodInfo methodInfo, IXunitTest _)
|
||||
{ }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -51,7 +51,7 @@ public class AppHostFixture : IAsyncLifetime
|
|||
public bool UsingAlreadyRunningInstance { get; private set; }
|
||||
public string StartupLogs => _startupLogs.ToString() ?? string.Empty;
|
||||
|
||||
public async Task InitializeAsync()
|
||||
public async ValueTask InitializeAsync()
|
||||
{
|
||||
using var startupLogWriter = ConnectLogger(s => _startupLogs.Write(s));
|
||||
|
||||
|
|
@ -130,7 +130,7 @@ public class AppHostFixture : IAsyncLifetime
|
|||
}
|
||||
|
||||
|
||||
public async Task DisposeAsync()
|
||||
public async ValueTask DisposeAsync()
|
||||
{
|
||||
if (_app != null)
|
||||
{
|
||||
|
|
@ -272,7 +272,7 @@ public class AppHostFixture : IAsyncLifetime
|
|||
|
||||
return _app.GetEndpoint(clientName);
|
||||
#else
|
||||
Skip.If(true, "When running the Host.Tests using NCrunch, you must start the Hosts.AppHost project manually. IE: dotnet run -p bff/samples/Hosts.AppHost. Or start without debugging from the UI. ");
|
||||
Assert.Skip("When running the Host.Tests using NCrunch, you must start the Hosts.AppHost project manually. IE: dotnet run -p bff/samples/Hosts.AppHost. Or start without debugging from the UI. ");
|
||||
return null!;
|
||||
#endif
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
// Copyright (c) Duende Software. All rights reserved.
|
||||
// See LICENSE in the project root for license information.
|
||||
|
||||
using Xunit.Abstractions;
|
||||
|
||||
namespace Hosts.Tests.TestInfra;
|
||||
|
||||
|
|
@ -24,7 +23,7 @@ public class IntegrationTestBase : IDisposable
|
|||
#if DEBUG_NCRUNCH
|
||||
// Running in NCrunch. NCrunch cannot build the aspire project, so it needs
|
||||
// to be started manually.
|
||||
Skip.If(true, "When running the Host.Tests using NCrunch, you must start the Hosts.AppHost project manually. IE: dotnet run -p bff/samples/Hosts.AppHost. Or start without debugging from the UI. ");
|
||||
Assert.Skip("When running the Host.Tests using NCrunch, you must start the Hosts.AppHost project manually. IE: dotnet run -p bff/samples/Hosts.AppHost. Or start without debugging from the UI. ");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,11 +12,9 @@
|
|||
<PackageReference Include="Serilog" />
|
||||
<PackageReference Include="Serilog.Extensions.Logging" />
|
||||
<PackageReference Include="Serilog.Sinks.TextWriter" />
|
||||
<PackageReference Include="Serilog.Sinks.XUnit" />
|
||||
<PackageReference Include="Serilog.Sinks.XUnit3" />
|
||||
<PackageReference Include="Serilog.AspNetCore" />
|
||||
<PackageReference Include="Aspire.Hosting.Testing" />
|
||||
<PackageReference Include="Xunit.SkippableFact" />
|
||||
<PackageReference Include="Microsoft.Playwright.Xunit" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
|
|
|||
|
|
@ -5,7 +5,6 @@ using Duende.IdentityServer.EndToEndTests.TestInfra;
|
|||
using Duende.Xunit.Playwright;
|
||||
using Projects;
|
||||
using ServiceDefaults;
|
||||
using Xunit.Abstractions;
|
||||
|
||||
namespace Duende.IdentityServer.EndToEndTests;
|
||||
|
||||
|
|
@ -13,6 +12,8 @@ namespace Duende.IdentityServer.EndToEndTests;
|
|||
public class IdentityServerTests(ITestOutputHelper output, IdentityServerHostTestFixture fixture)
|
||||
: PlaywrightTestBase<All>(output, fixture)
|
||||
{
|
||||
private readonly CancellationToken _ct = TestContext.Current.CancellationToken;
|
||||
|
||||
[Theory]
|
||||
[InlineData(AppHostServices.MvcAutomaticTokenManagement)]
|
||||
[InlineData(AppHostServices.MvcCode)]
|
||||
|
|
@ -24,7 +25,7 @@ public class IdentityServerTests(ITestOutputHelper output, IdentityServerHostTes
|
|||
public async Task clients_can_login_use_tokens_and_logout(string clientName)
|
||||
{
|
||||
await Page.GotoAsync(Fixture.GetUrlTo(clientName).ToString());
|
||||
await Page.Login();
|
||||
await Page.Login(ct: _ct);
|
||||
await Page.CallApi();
|
||||
await Page.RenewTokens();
|
||||
await Page.CallApi();
|
||||
|
|
@ -41,7 +42,7 @@ public class IdentityServerTests(ITestOutputHelper output, IdentityServerHostTes
|
|||
public async Task templates_can_serve_discovery(string templateName)
|
||||
{
|
||||
var client = CreateHttpClient(templateName);
|
||||
var response = await client.GetAsync(".well-known/openid-configuration");
|
||||
var response = await client.GetAsync(".well-known/openid-configuration", _ct);
|
||||
response.IsSuccessStatusCode.ShouldBeTrue();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@
|
|||
|
||||
using Duende.Xunit.Playwright;
|
||||
using Projects;
|
||||
using Xunit.Abstractions;
|
||||
|
||||
namespace Duende.IdentityServer.EndToEndTests.TestInfra;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
// Copyright (c) Duende Software. All rights reserved.
|
||||
// See LICENSE in the project root for license information.
|
||||
|
||||
|
||||
using System.IdentityModel.Tokens.Jwt;
|
||||
using System.Security.Claims;
|
||||
using System.Text;
|
||||
|
|
@ -19,6 +18,7 @@ namespace Duende.IdentityServer.IntegrationTests.Clients;
|
|||
|
||||
public class ClientAssertionClient
|
||||
{
|
||||
private readonly CancellationToken _ct = TestContext.Current.CancellationToken;
|
||||
private const string TokenEndpoint = "https://idsvr4/connect/token";
|
||||
private const string ClientId = "certificate_base64_valid";
|
||||
|
||||
|
|
@ -74,7 +74,7 @@ public class ClientAssertionClient
|
|||
},
|
||||
|
||||
Scope = "api1"
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
AssertValidToken(response);
|
||||
}
|
||||
|
|
@ -97,7 +97,7 @@ public class ClientAssertionClient
|
|||
},
|
||||
|
||||
Scope = "api1"
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
AssertValidToken(response);
|
||||
}
|
||||
|
|
@ -120,7 +120,7 @@ public class ClientAssertionClient
|
|||
},
|
||||
|
||||
Scope = "api1"
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
AssertValidToken(response);
|
||||
|
||||
|
|
@ -138,7 +138,7 @@ public class ClientAssertionClient
|
|||
},
|
||||
|
||||
Scope = "api1"
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
response.IsError.ShouldBeTrue();
|
||||
response.Error.ShouldBe("invalid_client");
|
||||
|
|
@ -160,7 +160,7 @@ public class ClientAssertionClient
|
|||
},
|
||||
|
||||
Scope = "api1"
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
response.IsError.ShouldBe(true);
|
||||
response.Error.ShouldBe(OidcConstants.TokenErrors.InvalidClient);
|
||||
|
|
@ -186,7 +186,7 @@ public class ClientAssertionClient
|
|||
},
|
||||
|
||||
Scope = "api1"
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
response.IsError.ShouldBe(true);
|
||||
response.Error.ShouldBe(OidcConstants.TokenErrors.InvalidClient);
|
||||
|
|
@ -195,7 +195,7 @@ public class ClientAssertionClient
|
|||
|
||||
private async Task<TokenResponse> GetToken(FormUrlEncodedContent body)
|
||||
{
|
||||
var response = await _client.PostAsync(TokenEndpoint, body);
|
||||
var response = await _client.PostAsync(TokenEndpoint, body, _ct);
|
||||
return await ProtocolResponse.FromHttpResponseAsync<TokenResponse>(response);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ namespace Duende.IdentityServer.IntegrationTests.Clients;
|
|||
|
||||
public class ClientCredentialsandResourceOwnerClient
|
||||
{
|
||||
private readonly CancellationToken _ct = TestContext.Current.CancellationToken;
|
||||
private const string TokenEndpoint = "https://server/connect/token";
|
||||
|
||||
private readonly HttpClient _client;
|
||||
|
|
@ -39,7 +40,7 @@ public class ClientCredentialsandResourceOwnerClient
|
|||
ClientId = "client.and.ro",
|
||||
ClientSecret = "secret",
|
||||
Scope = "api1"
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
response.IsError.ShouldBe(false);
|
||||
}
|
||||
|
|
@ -53,7 +54,7 @@ public class ClientCredentialsandResourceOwnerClient
|
|||
ClientId = "client.and.ro",
|
||||
ClientSecret = "secret",
|
||||
Scope = "openid api1"
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
response.IsError.ShouldBe(true);
|
||||
}
|
||||
|
|
@ -70,7 +71,7 @@ public class ClientCredentialsandResourceOwnerClient
|
|||
|
||||
UserName = "bob",
|
||||
Password = "bob"
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
response.IsError.ShouldBe(false);
|
||||
}
|
||||
|
|
@ -87,7 +88,7 @@ public class ClientCredentialsandResourceOwnerClient
|
|||
|
||||
UserName = "bob",
|
||||
Password = "bob"
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
response.IsError.ShouldBe(false);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ namespace Duende.IdentityServer.IntegrationTests.Clients;
|
|||
|
||||
public class ClientCredentialsClient
|
||||
{
|
||||
private readonly CancellationToken _ct = TestContext.Current.CancellationToken;
|
||||
private const string TokenEndpoint = "https://server/connect/token";
|
||||
|
||||
private readonly HttpClient _client;
|
||||
|
|
@ -43,7 +44,7 @@ public class ClientCredentialsClient
|
|||
ClientId = "client",
|
||||
ClientSecret = "secret",
|
||||
Scope = "api1"
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
response.IsError.ShouldBe(true);
|
||||
response.ErrorType.ShouldBe(ResponseErrorType.Http);
|
||||
|
|
@ -60,7 +61,7 @@ public class ClientCredentialsClient
|
|||
ClientId = "client",
|
||||
ClientSecret = "secret",
|
||||
Scope = "api1"
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
response.IsError.ShouldBe(false);
|
||||
response.ExpiresIn.ShouldBe(3600);
|
||||
|
|
@ -90,7 +91,7 @@ public class ClientCredentialsClient
|
|||
ClientId = "client",
|
||||
ClientSecret = "secret",
|
||||
Scope = "api1 other_api"
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
response.IsError.ShouldBe(false);
|
||||
response.ExpiresIn.ShouldBe(3600);
|
||||
|
|
@ -124,7 +125,7 @@ public class ClientCredentialsClient
|
|||
ClientId = "client.cnf",
|
||||
ClientSecret = "foo",
|
||||
Scope = "api1"
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
response.IsError.ShouldBe(false);
|
||||
response.ExpiresIn.ShouldBe(3600);
|
||||
|
|
@ -157,7 +158,7 @@ public class ClientCredentialsClient
|
|||
ClientId = "client",
|
||||
ClientSecret = "secret",
|
||||
Scope = "api1 api2"
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
response.IsError.ShouldBe(false);
|
||||
response.ExpiresIn.ShouldBe(3600);
|
||||
|
|
@ -188,7 +189,7 @@ public class ClientCredentialsClient
|
|||
Address = TokenEndpoint,
|
||||
ClientId = "client",
|
||||
ClientSecret = "secret"
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
response.IsError.ShouldBe(false);
|
||||
response.ExpiresIn.ShouldBe(3600);
|
||||
|
|
@ -224,7 +225,7 @@ public class ClientCredentialsClient
|
|||
Address = TokenEndpoint,
|
||||
ClientId = "client.no_default_scopes",
|
||||
ClientSecret = "secret"
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
response.IsError.ShouldBe(true);
|
||||
response.ExpiresIn.ShouldBe(0);
|
||||
|
|
@ -245,7 +246,7 @@ public class ClientCredentialsClient
|
|||
Scope = "api1",
|
||||
|
||||
ClientCredentialStyle = ClientCredentialStyle.PostBody
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
response.IsError.ShouldBe(false);
|
||||
response.ExpiresIn.ShouldBe(3600);
|
||||
|
|
@ -272,7 +273,7 @@ public class ClientCredentialsClient
|
|||
Address = TokenEndpoint,
|
||||
ClientId = "client.no_secret",
|
||||
Scope = "api1"
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
response.IsError.ShouldBeTrue();
|
||||
response.Error.ShouldBe("invalid_client");
|
||||
|
|
@ -287,7 +288,7 @@ public class ClientCredentialsClient
|
|||
ClientId = "client",
|
||||
ClientSecret = "invalid",
|
||||
Scope = "api1"
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
response.IsError.ShouldBe(true);
|
||||
response.Error.ShouldBe("invalid_client");
|
||||
|
|
@ -302,7 +303,7 @@ public class ClientCredentialsClient
|
|||
ClientId = "invalid",
|
||||
ClientSecret = "secret",
|
||||
Scope = "api1"
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
response.IsError.ShouldBe(true);
|
||||
response.ErrorType.ShouldBe(ResponseErrorType.Protocol);
|
||||
|
|
@ -318,7 +319,7 @@ public class ClientCredentialsClient
|
|||
Address = TokenEndpoint,
|
||||
ClientId = "implicit",
|
||||
Scope = "api1"
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
response.IsError.ShouldBe(true);
|
||||
response.ErrorType.ShouldBe(ResponseErrorType.Protocol);
|
||||
|
|
@ -335,7 +336,7 @@ public class ClientCredentialsClient
|
|||
ClientId = "implicit_and_client_creds",
|
||||
ClientSecret = "invalid",
|
||||
Scope = "api1"
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
response.IsError.ShouldBe(true);
|
||||
response.ErrorType.ShouldBe(ResponseErrorType.Protocol);
|
||||
|
|
@ -353,7 +354,7 @@ public class ClientCredentialsClient
|
|||
ClientId = "client",
|
||||
ClientSecret = "secret",
|
||||
Scope = "unknown"
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
response.IsError.ShouldBe(true);
|
||||
response.ErrorType.ShouldBe(ResponseErrorType.Protocol);
|
||||
|
|
@ -370,7 +371,7 @@ public class ClientCredentialsClient
|
|||
ClientId = "client.identityscopes",
|
||||
ClientSecret = "secret",
|
||||
Scope = "openid api1"
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
response.IsError.ShouldBe(true);
|
||||
response.ErrorType.ShouldBe(ResponseErrorType.Protocol);
|
||||
|
|
@ -387,7 +388,7 @@ public class ClientCredentialsClient
|
|||
ClientId = "client",
|
||||
ClientSecret = "secret",
|
||||
Scope = "api1 offline_access"
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
response.IsError.ShouldBe(true);
|
||||
response.ErrorType.ShouldBe(ResponseErrorType.Protocol);
|
||||
|
|
@ -404,7 +405,7 @@ public class ClientCredentialsClient
|
|||
ClientId = "client",
|
||||
ClientSecret = "secret",
|
||||
Scope = "api3"
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
response.IsError.ShouldBe(true);
|
||||
response.ErrorType.ShouldBe(ResponseErrorType.Protocol);
|
||||
|
|
@ -421,7 +422,7 @@ public class ClientCredentialsClient
|
|||
ClientId = "client",
|
||||
ClientSecret = "secret",
|
||||
Scope = "api1 api3"
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
response.IsError.ShouldBe(true);
|
||||
response.ErrorType.ShouldBe(ResponseErrorType.Protocol);
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ namespace Duende.IdentityServer.IntegrationTests.Clients;
|
|||
|
||||
public class CustomTokenRequestValidatorClient
|
||||
{
|
||||
private readonly CancellationToken _ct = TestContext.Current.CancellationToken;
|
||||
private const string TokenEndpoint = "https://server/connect/token";
|
||||
|
||||
private readonly HttpClient _client;
|
||||
|
|
@ -45,7 +46,7 @@ public class CustomTokenRequestValidatorClient
|
|||
ClientId = "client",
|
||||
ClientSecret = "secret",
|
||||
Scope = "api1"
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
var fields = GetFields(response);
|
||||
fields["custom"].GetString().ShouldBe("custom");
|
||||
|
|
@ -64,7 +65,7 @@ public class CustomTokenRequestValidatorClient
|
|||
|
||||
UserName = "bob",
|
||||
Password = "bob"
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
var fields = GetFields(response);
|
||||
fields["custom"].GetString().ShouldBe("custom");
|
||||
|
|
@ -83,7 +84,7 @@ public class CustomTokenRequestValidatorClient
|
|||
|
||||
UserName = "bob",
|
||||
Password = "bob"
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
response = await _client.RequestRefreshTokenAsync(new RefreshTokenRequest
|
||||
{
|
||||
|
|
@ -92,7 +93,7 @@ public class CustomTokenRequestValidatorClient
|
|||
ClientSecret = "secret",
|
||||
|
||||
RefreshToken = response.RefreshToken
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
var fields = GetFields(response);
|
||||
fields["custom"].GetString().ShouldBe("custom");
|
||||
|
|
@ -114,7 +115,7 @@ public class CustomTokenRequestValidatorClient
|
|||
{ "scope", "api1" },
|
||||
{ "custom_credential", "custom credential"}
|
||||
}
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
var fields = GetFields(response);
|
||||
fields["custom"].GetString().ShouldBe("custom");
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ namespace Duende.IdentityServer.IntegrationTests.Clients;
|
|||
|
||||
public class CustomTokenResponseClients
|
||||
{
|
||||
private readonly CancellationToken _ct = TestContext.Current.CancellationToken;
|
||||
private const string TokenEndpoint = "https://server/connect/token";
|
||||
|
||||
private readonly HttpClient _client;
|
||||
|
|
@ -46,7 +47,7 @@ public class CustomTokenResponseClients
|
|||
UserName = "bob",
|
||||
Password = "bob",
|
||||
Scope = "api1"
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
// raw fields
|
||||
var fields = GetFields(response);
|
||||
|
|
@ -109,7 +110,7 @@ public class CustomTokenResponseClients
|
|||
UserName = "bob",
|
||||
Password = "invalid",
|
||||
Scope = "api1"
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
// raw fields
|
||||
var fields = GetFields(response);
|
||||
|
|
@ -161,7 +162,7 @@ public class CustomTokenResponseClients
|
|||
{ "scope", "api1" },
|
||||
{ "outcome", "succeed"}
|
||||
}
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
|
||||
// raw fields
|
||||
|
|
@ -229,7 +230,7 @@ public class CustomTokenResponseClients
|
|||
{ "scope", "api1" },
|
||||
{ "outcome", "fail"}
|
||||
}
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
|
||||
// raw fields
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ namespace Duende.IdentityServer.IntegrationTests.Clients;
|
|||
public class DiscoveryClientTests
|
||||
{
|
||||
private const string DiscoveryEndpoint = "https://server/.well-known/openid-configuration";
|
||||
|
||||
private readonly CancellationToken _ct = TestContext.Current.CancellationToken;
|
||||
private readonly HttpClient _client;
|
||||
|
||||
public DiscoveryClientTests()
|
||||
|
|
@ -40,7 +40,7 @@ public class DiscoveryClientTests
|
|||
{
|
||||
ValidateIssuerName = false
|
||||
}
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
// endpoints
|
||||
doc.TokenEndpoint.ShouldBe("https://server/connect/token");
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ namespace Duende.IdentityServer.IntegrationTests.Clients;
|
|||
public class ExtensionGrantClient
|
||||
{
|
||||
private const string TokenEndpoint = "https://server/connect/token";
|
||||
|
||||
private readonly CancellationToken _ct = TestContext.Current.CancellationToken;
|
||||
private readonly HttpClient _client;
|
||||
|
||||
public ExtensionGrantClient()
|
||||
|
|
@ -51,7 +51,7 @@ public class ExtensionGrantClient
|
|||
{ "custom_credential", "custom credential"},
|
||||
{ "scope", "api1" }
|
||||
}
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
response.IsError.ShouldBeFalse();
|
||||
response.HttpStatusCode.ShouldBe(HttpStatusCode.OK);
|
||||
|
|
@ -96,7 +96,7 @@ public class ExtensionGrantClient
|
|||
{ "extra_claim", "extra_value" },
|
||||
{ "scope", "api1" }
|
||||
}
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
response.IsError.ShouldBeFalse();
|
||||
response.HttpStatusCode.ShouldBe(HttpStatusCode.OK);
|
||||
|
|
@ -148,7 +148,7 @@ public class ExtensionGrantClient
|
|||
{ "extra_claim", "extra_value" },
|
||||
{ "scope", "api1 offline_access" }
|
||||
}
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
response.IsError.ShouldBeFalse();
|
||||
response.HttpStatusCode.ShouldBe(HttpStatusCode.OK);
|
||||
|
|
@ -165,7 +165,7 @@ public class ExtensionGrantClient
|
|||
ClientSecret = "secret",
|
||||
|
||||
RefreshToken = response.RefreshToken
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
refreshResponse.IsError.ShouldBeFalse();
|
||||
refreshResponse.HttpStatusCode.ShouldBe(HttpStatusCode.OK);
|
||||
|
|
@ -215,7 +215,7 @@ public class ExtensionGrantClient
|
|||
{ "custom_credential", "custom credential"},
|
||||
{ "scope", "api1" }
|
||||
}
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
response.IsError.ShouldBeFalse();
|
||||
response.HttpStatusCode.ShouldBe(HttpStatusCode.OK);
|
||||
|
|
@ -250,7 +250,7 @@ public class ExtensionGrantClient
|
|||
{
|
||||
{ "custom_credential", "custom credential"}
|
||||
}
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
response.IsError.ShouldBeFalse();
|
||||
response.HttpStatusCode.ShouldBe(HttpStatusCode.OK);
|
||||
|
|
@ -296,7 +296,7 @@ public class ExtensionGrantClient
|
|||
{
|
||||
{ "scope", "api1" }
|
||||
}
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
response.IsError.ShouldBe(true);
|
||||
response.ErrorType.ShouldBe(ResponseErrorType.Protocol);
|
||||
|
|
@ -320,7 +320,7 @@ public class ExtensionGrantClient
|
|||
{ "custom_credential", "custom credential"},
|
||||
{ "scope", "api1" }
|
||||
}
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
response.IsError.ShouldBe(true);
|
||||
response.ErrorType.ShouldBe(ResponseErrorType.Protocol);
|
||||
|
|
@ -344,7 +344,7 @@ public class ExtensionGrantClient
|
|||
{ "custom_credential", "custom credential"},
|
||||
{ "scope", "api1" }
|
||||
}
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
response.IsError.ShouldBe(true);
|
||||
response.ErrorType.ShouldBe(ResponseErrorType.Protocol);
|
||||
|
|
@ -370,7 +370,7 @@ public class ExtensionGrantClient
|
|||
{ "lifetime", "5000"},
|
||||
{ "sub", "818727"}
|
||||
}
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
response.IsError.ShouldBeFalse();
|
||||
response.HttpStatusCode.ShouldBe(HttpStatusCode.OK);
|
||||
|
|
@ -421,7 +421,7 @@ public class ExtensionGrantClient
|
|||
{ "type", "jwt"},
|
||||
{ "sub", "818727"}
|
||||
}
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
response.IsError.ShouldBeFalse();
|
||||
response.HttpStatusCode.ShouldBe(HttpStatusCode.OK);
|
||||
|
|
@ -452,7 +452,7 @@ public class ExtensionGrantClient
|
|||
{ "impersonated_client", "impersonated_client_id"},
|
||||
{ "sub", "818727"}
|
||||
}
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
response.IsError.ShouldBeFalse();
|
||||
response.HttpStatusCode.ShouldBe(HttpStatusCode.OK);
|
||||
|
|
@ -485,7 +485,7 @@ public class ExtensionGrantClient
|
|||
{ "type", "reference"},
|
||||
{ "sub", "818727"}
|
||||
}
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
response.IsError.ShouldBeFalse();
|
||||
response.HttpStatusCode.ShouldBe(HttpStatusCode.OK);
|
||||
|
|
@ -515,7 +515,7 @@ public class ExtensionGrantClient
|
|||
{ "claim", "extra_claim"},
|
||||
{ "sub", "818727"}
|
||||
}
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
response.IsError.ShouldBeFalse();
|
||||
response.HttpStatusCode.ShouldBe(HttpStatusCode.OK);
|
||||
|
|
@ -561,7 +561,7 @@ public class ExtensionGrantClient
|
|||
|
||||
{ "claim", "extra_claim"},
|
||||
}
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
response.IsError.ShouldBeFalse();
|
||||
response.HttpStatusCode.ShouldBe(HttpStatusCode.OK);
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ public class RefreshTokenClient
|
|||
{
|
||||
private const string TokenEndpoint = "https://server/connect/token";
|
||||
private const string RevocationEndpoint = "https://server/connect/revocation";
|
||||
|
||||
private readonly CancellationToken _ct = TestContext.Current.CancellationToken;
|
||||
private readonly HttpClient _client;
|
||||
|
||||
public RefreshTokenClient()
|
||||
|
|
@ -43,7 +43,7 @@ public class RefreshTokenClient
|
|||
Scope = "api1 offline_access",
|
||||
UserName = "bob",
|
||||
Password = "bob"
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
response.IsError.ShouldBeFalse();
|
||||
response.ExpiresIn.ShouldBe(3600);
|
||||
|
|
@ -58,7 +58,7 @@ public class RefreshTokenClient
|
|||
ClientSecret = "secret",
|
||||
|
||||
RefreshToken = response.RefreshToken
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
response.IsError.ShouldBeFalse();
|
||||
response.ExpiresIn.ShouldBe(3600);
|
||||
|
|
@ -79,7 +79,7 @@ public class RefreshTokenClient
|
|||
Scope = "openid api1 offline_access",
|
||||
UserName = "bob",
|
||||
Password = "bob"
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
response.IsError.ShouldBeFalse();
|
||||
response.ExpiresIn.ShouldBe(3600);
|
||||
|
|
@ -94,7 +94,7 @@ public class RefreshTokenClient
|
|||
ClientSecret = "secret",
|
||||
|
||||
RefreshToken = response.RefreshToken
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
response.IsError.ShouldBeFalse();
|
||||
response.ExpiresIn.ShouldBe(3600);
|
||||
|
|
@ -115,7 +115,7 @@ public class RefreshTokenClient
|
|||
Scope = "openid api1 offline_access",
|
||||
UserName = "bob",
|
||||
Password = "bob"
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
response.IsError.ShouldBeFalse();
|
||||
response.ExpiresIn.ShouldBe(3600);
|
||||
|
|
@ -132,7 +132,7 @@ public class RefreshTokenClient
|
|||
ClientSecret = "secret",
|
||||
|
||||
RefreshToken = response.RefreshToken
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
response.IsError.ShouldBeFalse();
|
||||
response.ExpiresIn.ShouldBe(3600);
|
||||
|
|
@ -157,7 +157,7 @@ public class RefreshTokenClient
|
|||
Scope = "openid api1 offline_access",
|
||||
UserName = "bob",
|
||||
Password = "bob"
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
response.IsError.ShouldBeFalse();
|
||||
response.ExpiresIn.ShouldBe(3600);
|
||||
|
|
@ -174,7 +174,7 @@ public class RefreshTokenClient
|
|||
ClientSecret = "secret",
|
||||
|
||||
RefreshToken = response.RefreshToken
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
response.IsError.ShouldBeFalse();
|
||||
response.ExpiresIn.ShouldBe(3600);
|
||||
|
|
@ -200,7 +200,7 @@ public class RefreshTokenClient
|
|||
Scope = "openid api1 offline_access",
|
||||
UserName = "bob",
|
||||
Password = "bob"
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
response.IsError.ShouldBeFalse();
|
||||
response.ExpiresIn.ShouldBe(3600);
|
||||
|
|
@ -218,7 +218,7 @@ public class RefreshTokenClient
|
|||
ClientSecret = "secret",
|
||||
|
||||
RefreshToken = response.RefreshToken
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
response.IsError.ShouldBeFalse();
|
||||
response.ExpiresIn.ShouldBe(3600);
|
||||
|
|
@ -234,7 +234,7 @@ public class RefreshTokenClient
|
|||
ClientSecret = "secret",
|
||||
|
||||
RefreshToken = rt1
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
response.IsError.ShouldBeTrue();
|
||||
response.Error.ShouldBe("invalid_grant");
|
||||
|
|
@ -253,7 +253,7 @@ public class RefreshTokenClient
|
|||
Scope = "openid api1 offline_access",
|
||||
UserName = "bob",
|
||||
Password = "bob"
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
response.IsError.ShouldBeFalse();
|
||||
response.ExpiresIn.ShouldBe(3600);
|
||||
|
|
@ -271,7 +271,7 @@ public class RefreshTokenClient
|
|||
ClientSecret = "secret",
|
||||
|
||||
RefreshToken = rt1
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
response.IsError.ShouldBeFalse();
|
||||
}
|
||||
|
|
@ -289,7 +289,7 @@ public class RefreshTokenClient
|
|||
Scope = "openid api1 offline_access",
|
||||
UserName = "bob",
|
||||
Password = "bob"
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
response.IsError.ShouldBeFalse();
|
||||
response.ExpiresIn.ShouldBe(3600);
|
||||
|
|
@ -309,7 +309,7 @@ public class RefreshTokenClient
|
|||
|
||||
Token = rt1,
|
||||
TokenTypeHint = "refresh_token"
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
revocationResponse.IsError.ShouldBe(false);
|
||||
|
||||
|
|
@ -321,7 +321,7 @@ public class RefreshTokenClient
|
|||
ClientSecret = "secret",
|
||||
|
||||
RefreshToken = rt1
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
response.IsError.ShouldBeTrue();
|
||||
response.Error.ShouldBe("invalid_grant");
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ namespace Duende.IdentityServer.IntegrationTests.Clients;
|
|||
public class ResourceOwnerClient
|
||||
{
|
||||
private const string TokenEndpoint = "https://server/connect/token";
|
||||
|
||||
private readonly CancellationToken _ct = TestContext.Current.CancellationToken;
|
||||
private readonly HttpClient _client;
|
||||
|
||||
public ResourceOwnerClient()
|
||||
|
|
@ -46,7 +46,7 @@ public class ResourceOwnerClient
|
|||
Scope = "api1",
|
||||
UserName = "bob",
|
||||
Password = "bob"
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
response.IsError.ShouldBe(false);
|
||||
response.ExpiresIn.ShouldBe(3600);
|
||||
|
|
@ -85,7 +85,7 @@ public class ResourceOwnerClient
|
|||
|
||||
UserName = "bob",
|
||||
Password = "bob"
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
response.IsError.ShouldBe(false);
|
||||
response.ExpiresIn.ShouldBe(3600);
|
||||
|
|
@ -132,7 +132,7 @@ public class ResourceOwnerClient
|
|||
Scope = "openid email api1",
|
||||
UserName = "bob",
|
||||
Password = "bob"
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
response.IsError.ShouldBe(false);
|
||||
response.ExpiresIn.ShouldBe(3600);
|
||||
|
|
@ -174,7 +174,7 @@ public class ResourceOwnerClient
|
|||
Scope = "openid email api1 offline_access",
|
||||
UserName = "bob",
|
||||
Password = "bob"
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
response.IsError.ShouldBe(false);
|
||||
response.ExpiresIn.ShouldBe(3600);
|
||||
|
|
@ -217,7 +217,7 @@ public class ResourceOwnerClient
|
|||
Scope = "api1",
|
||||
UserName = "unknown",
|
||||
Password = "bob"
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
response.IsError.ShouldBe(true);
|
||||
response.ErrorType.ShouldBe(ResponseErrorType.Protocol);
|
||||
|
|
@ -236,7 +236,7 @@ public class ResourceOwnerClient
|
|||
|
||||
Scope = "api1",
|
||||
UserName = "bob_no_password"
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
response.IsError.ShouldBe(false);
|
||||
}
|
||||
|
|
@ -255,7 +255,7 @@ public class ResourceOwnerClient
|
|||
Scope = "api1",
|
||||
UserName = "bob",
|
||||
Password = password
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
response.IsError.ShouldBe(true);
|
||||
response.ErrorType.ShouldBe(ResponseErrorType.Protocol);
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ public class RevocationClient
|
|||
private const string TokenEndpoint = "https://server/connect/token";
|
||||
private const string RevocationEndpoint = "https://server/connect/revocation";
|
||||
private const string IntrospectionEndpoint = "https://server/connect/introspect";
|
||||
|
||||
private readonly CancellationToken _ct = TestContext.Current.CancellationToken;
|
||||
private readonly HttpClient _client;
|
||||
|
||||
public RevocationClient()
|
||||
|
|
@ -35,7 +35,7 @@ public class RevocationClient
|
|||
[Fact]
|
||||
public async Task Revoking_reference_token_should_invalidate_token()
|
||||
{
|
||||
// request acccess token
|
||||
// request access token
|
||||
var response = await _client.RequestPasswordTokenAsync(new PasswordTokenRequest
|
||||
{
|
||||
Address = TokenEndpoint,
|
||||
|
|
@ -45,7 +45,7 @@ public class RevocationClient
|
|||
Scope = "api1",
|
||||
UserName = "bob",
|
||||
Password = "bob"
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
response.IsError.ShouldBeFalse();
|
||||
|
||||
|
|
@ -57,7 +57,7 @@ public class RevocationClient
|
|||
ClientSecret = "secret",
|
||||
|
||||
Token = response.AccessToken
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
introspectionResponse.IsActive.ShouldBe(true);
|
||||
|
||||
|
|
@ -69,7 +69,7 @@ public class RevocationClient
|
|||
ClientSecret = "secret",
|
||||
|
||||
Token = response.AccessToken
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
// introspect - should be inactive
|
||||
introspectionResponse = await _client.IntrospectTokenAsync(new TokenIntrospectionRequest
|
||||
|
|
@ -79,7 +79,7 @@ public class RevocationClient
|
|||
ClientSecret = "secret",
|
||||
|
||||
Token = response.AccessToken
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
introspectionResponse.IsActive.ShouldBe(false);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ public class UserInfoEndpointClient
|
|||
{
|
||||
private const string TokenEndpoint = "https://server/connect/token";
|
||||
private const string UserInfoEndpoint = "https://server/connect/userinfo";
|
||||
|
||||
private readonly CancellationToken _ct = TestContext.Current.CancellationToken;
|
||||
private readonly HttpClient _client;
|
||||
|
||||
public UserInfoEndpointClient()
|
||||
|
|
@ -48,7 +48,7 @@ public class UserInfoEndpointClient
|
|||
Scope = "openid email api1",
|
||||
UserName = "bob",
|
||||
Password = "bob"
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
response.IsError.ShouldBeFalse();
|
||||
|
||||
|
|
@ -56,7 +56,7 @@ public class UserInfoEndpointClient
|
|||
{
|
||||
Address = UserInfoEndpoint,
|
||||
Token = response.AccessToken
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
userInfo.IsError.ShouldBeFalse();
|
||||
userInfo.Claims.Count().ShouldBe(3);
|
||||
|
|
@ -78,7 +78,7 @@ public class UserInfoEndpointClient
|
|||
Scope = "openid address",
|
||||
UserName = "bob",
|
||||
Password = "bob"
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
response.IsError.ShouldBeFalse();
|
||||
|
||||
|
|
@ -86,7 +86,7 @@ public class UserInfoEndpointClient
|
|||
{
|
||||
Address = UserInfoEndpoint,
|
||||
Token = response.AccessToken
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
userInfo.IsError.ShouldBeFalse();
|
||||
userInfo.Claims.First().Value.ShouldBe("{ 'street_address': 'One Hacker Way', 'locality': 'Heidelberg', 'postal_code': 69118, 'country': 'Germany' }");
|
||||
|
|
@ -104,7 +104,7 @@ public class UserInfoEndpointClient
|
|||
Scope = "api1",
|
||||
UserName = "bob",
|
||||
Password = "bob"
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
response.IsError.ShouldBeFalse();
|
||||
|
||||
|
|
@ -112,7 +112,7 @@ public class UserInfoEndpointClient
|
|||
{
|
||||
Address = UserInfoEndpoint,
|
||||
Token = response.AccessToken
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
userInfo.IsError.ShouldBeTrue();
|
||||
userInfo.HttpStatusCode.ShouldBe(HttpStatusCode.Forbidden);
|
||||
|
|
@ -130,7 +130,7 @@ public class UserInfoEndpointClient
|
|||
Scope = "email api1",
|
||||
UserName = "bob",
|
||||
Password = "bob"
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
response.IsError.ShouldBeFalse();
|
||||
|
||||
|
|
@ -138,7 +138,7 @@ public class UserInfoEndpointClient
|
|||
{
|
||||
Address = UserInfoEndpoint,
|
||||
Token = response.AccessToken
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
userInfo.IsError.ShouldBeTrue();
|
||||
userInfo.HttpStatusCode.ShouldBe(HttpStatusCode.Forbidden);
|
||||
|
|
@ -151,7 +151,7 @@ public class UserInfoEndpointClient
|
|||
{
|
||||
Address = UserInfoEndpoint,
|
||||
Token = "invalid"
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
userInfo.IsError.ShouldBeTrue();
|
||||
userInfo.HttpStatusCode.ShouldBe(HttpStatusCode.Unauthorized);
|
||||
|
|
@ -169,7 +169,7 @@ public class UserInfoEndpointClient
|
|||
Scope = "openid email api1 api4.with.roles roles",
|
||||
UserName = "bob",
|
||||
Password = "bob"
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
response.IsError.ShouldBeFalse();
|
||||
|
||||
|
|
@ -192,7 +192,7 @@ public class UserInfoEndpointClient
|
|||
{
|
||||
Address = UserInfoEndpoint,
|
||||
Token = response.AccessToken
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
roles = userInfo.Json?.TryGetStringArray("role").ToList();
|
||||
roles.Count.ShouldBe(2);
|
||||
|
|
|
|||
|
|
@ -11,6 +11,8 @@ namespace Duende.IdentityServer.IntegrationTests.Configuration;
|
|||
|
||||
public class DynamicClientRegistrationTests : ConfigurationIntegrationTestBase
|
||||
{
|
||||
private readonly CancellationToken _ct = TestContext.Current.CancellationToken;
|
||||
|
||||
[Fact]
|
||||
public async Task valid_request_creates_new_client()
|
||||
{
|
||||
|
|
@ -25,9 +27,9 @@ public class DynamicClientRegistrationTests : ConfigurationIntegrationTestBase
|
|||
DefaultMaxAge = 10000,
|
||||
Scope = "api1 openid profile"
|
||||
};
|
||||
var httpResponse = await ConfigurationHost.HttpClient!.PostAsJsonAsync("/connect/dcr", request);
|
||||
var httpResponse = await ConfigurationHost.HttpClient!.PostAsJsonAsync("/connect/dcr", request, _ct);
|
||||
|
||||
var response = await httpResponse.Content.ReadFromJsonAsync<DynamicClientRegistrationResponse>();
|
||||
var response = await httpResponse.Content.ReadFromJsonAsync<DynamicClientRegistrationResponse>(_ct);
|
||||
response.ShouldNotBeNull();
|
||||
var newClient = await IdentityServerHost.GetClientAsync(response!.ClientId); // Not null already asserted
|
||||
newClient.ShouldNotBeNull();
|
||||
|
|
|
|||
|
|
@ -12,10 +12,12 @@ namespace Duende.IdentityServer.IntegrationTests.Configuration;
|
|||
|
||||
public class DynamicClientRegistrationValidationTests : ConfigurationIntegrationTestBase
|
||||
{
|
||||
private readonly CancellationToken _ct = TestContext.Current.CancellationToken;
|
||||
|
||||
[Fact]
|
||||
public async Task http_get_method_should_fail()
|
||||
{
|
||||
var response = await ConfigurationHost.HttpClient!.GetAsync("/connect/dcr");
|
||||
var response = await ConfigurationHost.HttpClient!.GetAsync("/connect/dcr", _ct);
|
||||
response.StatusCode.ShouldBe(HttpStatusCode.MethodNotAllowed);
|
||||
}
|
||||
|
||||
|
|
@ -26,7 +28,7 @@ public class DynamicClientRegistrationValidationTests : ConfigurationIntegration
|
|||
{ "redirect_uris", "https://example.com/callback" },
|
||||
{ "grant_types", "authorization_code" }
|
||||
});
|
||||
var response = await ConfigurationHost.HttpClient!.PostAsync("/connect/dcr", content);
|
||||
var response = await ConfigurationHost.HttpClient!.PostAsync("/connect/dcr", content, _ct);
|
||||
response.StatusCode.ShouldBe(HttpStatusCode.UnsupportedMediaType);
|
||||
}
|
||||
|
||||
|
|
@ -36,10 +38,10 @@ public class DynamicClientRegistrationValidationTests : ConfigurationIntegration
|
|||
var response = await ConfigurationHost.HttpClient!.PostAsJsonAsync("/connect/dcr", new
|
||||
{
|
||||
redirect_uris = new[] { "https://example.com/callback" }
|
||||
});
|
||||
}, _ct);
|
||||
response.StatusCode.ShouldBe(HttpStatusCode.BadRequest);
|
||||
|
||||
var error = await response.Content.ReadFromJsonAsync<DynamicClientRegistrationError>();
|
||||
var error = await response.Content.ReadFromJsonAsync<DynamicClientRegistrationError>(_ct);
|
||||
error?.Error.ShouldBe("invalid_client_metadata");
|
||||
}
|
||||
|
||||
|
|
@ -50,10 +52,10 @@ public class DynamicClientRegistrationValidationTests : ConfigurationIntegration
|
|||
{
|
||||
redirect_uris = new[] { "https://example.com/callback" },
|
||||
grant_types = new[] { "password" }
|
||||
});
|
||||
}, _ct);
|
||||
response.StatusCode.ShouldBe(HttpStatusCode.BadRequest);
|
||||
|
||||
var error = await response.Content.ReadFromJsonAsync<DynamicClientRegistrationError>();
|
||||
var error = await response.Content.ReadFromJsonAsync<DynamicClientRegistrationError>(_ct);
|
||||
error?.Error.ShouldBe("invalid_client_metadata");
|
||||
}
|
||||
|
||||
|
|
@ -64,10 +66,10 @@ public class DynamicClientRegistrationValidationTests : ConfigurationIntegration
|
|||
{
|
||||
redirect_uris = new[] { "https://example.com/callback" },
|
||||
grant_types = new[] { "client_credentials" }
|
||||
});
|
||||
}, _ct);
|
||||
response.StatusCode.ShouldBe(HttpStatusCode.BadRequest);
|
||||
|
||||
var error = await response.Content.ReadFromJsonAsync<DynamicClientRegistrationError>();
|
||||
var error = await response.Content.ReadFromJsonAsync<DynamicClientRegistrationError>(_ct);
|
||||
error?.Error.ShouldBe("invalid_redirect_uri");
|
||||
}
|
||||
|
||||
|
|
@ -77,10 +79,10 @@ public class DynamicClientRegistrationValidationTests : ConfigurationIntegration
|
|||
var response = await ConfigurationHost.HttpClient!.PostAsJsonAsync("/connect/dcr", new
|
||||
{
|
||||
grant_types = new[] { "authorization_code", "client_credentials" }
|
||||
});
|
||||
}, _ct);
|
||||
response.StatusCode.ShouldBe(HttpStatusCode.BadRequest);
|
||||
|
||||
var error = await response.Content.ReadFromJsonAsync<DynamicClientRegistrationError>();
|
||||
var error = await response.Content.ReadFromJsonAsync<DynamicClientRegistrationError>(_ct);
|
||||
error?.Error.ShouldBe("invalid_redirect_uri");
|
||||
}
|
||||
|
||||
|
|
@ -90,10 +92,10 @@ public class DynamicClientRegistrationValidationTests : ConfigurationIntegration
|
|||
var response = await ConfigurationHost.HttpClient!.PostAsJsonAsync("/connect/dcr", new
|
||||
{
|
||||
grant_types = new[] { "client_credentials", "refresh_token" }
|
||||
});
|
||||
}, _ct);
|
||||
response.StatusCode.ShouldBe(HttpStatusCode.BadRequest);
|
||||
|
||||
var error = await response.Content.ReadFromJsonAsync<DynamicClientRegistrationError>();
|
||||
var error = await response.Content.ReadFromJsonAsync<DynamicClientRegistrationError>(_ct);
|
||||
error?.Error.ShouldBe("invalid_client_metadata");
|
||||
}
|
||||
|
||||
|
|
@ -106,11 +108,10 @@ public class DynamicClientRegistrationValidationTests : ConfigurationIntegration
|
|||
GrantTypes = { "client_credentials" },
|
||||
Jwks = new KeySet(Array.Empty<string>()),
|
||||
JwksUri = new Uri("https://example.com")
|
||||
}
|
||||
);
|
||||
}, _ct);
|
||||
response.StatusCode.ShouldBe(HttpStatusCode.BadRequest);
|
||||
|
||||
var error = await response.Content.ReadFromJsonAsync<DynamicClientRegistrationError>();
|
||||
var error = await response.Content.ReadFromJsonAsync<DynamicClientRegistrationError>(_ct);
|
||||
error?.Error.ShouldBe("invalid_client_metadata");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,8 +13,8 @@ namespace Duende.IdentityServer.IntegrationTests.Conformance.Basic;
|
|||
public class ClientAuthenticationTests
|
||||
{
|
||||
private const string Category = "Conformance.Basic.ClientAuthenticationTests";
|
||||
|
||||
private IdentityServerPipeline _pipeline = new IdentityServerPipeline();
|
||||
private readonly CancellationToken _ct = TestContext.Current.CancellationToken;
|
||||
private readonly IdentityServerPipeline _pipeline = new IdentityServerPipeline();
|
||||
|
||||
public ClientAuthenticationTests()
|
||||
{
|
||||
|
|
@ -70,7 +70,7 @@ public class ClientAuthenticationTests
|
|||
scope: "openid",
|
||||
redirectUri: "https://code_pipeline.Client/callback?foo=bar&baz=quux",
|
||||
nonce: nonce);
|
||||
var response = await _pipeline.BrowserClient.GetAsync(url);
|
||||
var response = await _pipeline.BrowserClient.GetAsync(url, _ct);
|
||||
|
||||
var authorization = _pipeline.ParseAuthorizationResponseUrl(response.Headers.Location.ToString());
|
||||
authorization.Code.ShouldNotBeNull();
|
||||
|
|
@ -88,7 +88,7 @@ public class ClientAuthenticationTests
|
|||
|
||||
Code = code,
|
||||
RedirectUri = "https://code_pipeline.Client/callback?foo=bar&baz=quux"
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
tokenResult.IsError.ShouldBeFalse();
|
||||
tokenResult.HttpErrorReason.ShouldBe("OK");
|
||||
|
|
@ -116,7 +116,7 @@ public class ClientAuthenticationTests
|
|||
scope: "openid",
|
||||
redirectUri: "https://code_pipeline.Client/callback?foo=bar&baz=quux",
|
||||
nonce: nonce);
|
||||
var response = await _pipeline.BrowserClient.GetAsync(url);
|
||||
var response = await _pipeline.BrowserClient.GetAsync(url, _ct);
|
||||
|
||||
var authorization = _pipeline.ParseAuthorizationResponseUrl(response.Headers.Location.ToString());
|
||||
authorization.Code.ShouldNotBeNull();
|
||||
|
|
@ -135,7 +135,7 @@ public class ClientAuthenticationTests
|
|||
|
||||
Code = code,
|
||||
RedirectUri = "https://code_pipeline.Client/callback?foo=bar&baz=quux"
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
tokenResult.IsError.ShouldBeFalse();
|
||||
tokenResult.HttpErrorReason.ShouldBe("OK");
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ namespace Duende.IdentityServer.IntegrationTests.Conformance.Basic;
|
|||
|
||||
public class CodeFlowTests
|
||||
{
|
||||
private readonly CancellationToken _ct = TestContext.Current.CancellationToken;
|
||||
private const string Category = "Conformance.Basic.CodeFlowTests";
|
||||
|
||||
private IdentityServerPipeline _pipeline = new IdentityServerPipeline();
|
||||
|
|
@ -72,7 +73,7 @@ public class CodeFlowTests
|
|||
scope: "openid",
|
||||
redirectUri: "https://code_pipeline.Client/callback?foo=bar&baz=quux",
|
||||
nonce: nonce);
|
||||
var response = await _pipeline.BrowserClient.GetAsync(url);
|
||||
var response = await _pipeline.BrowserClient.GetAsync(url, _ct);
|
||||
|
||||
var authorization = _pipeline.ParseAuthorizationResponseUrl(response.Headers.Location.ToString());
|
||||
authorization.Code.ShouldNotBeNull();
|
||||
|
|
@ -90,7 +91,7 @@ public class CodeFlowTests
|
|||
|
||||
Code = code,
|
||||
RedirectUri = "https://code_pipeline.Client/callback?foo=bar&baz=quux"
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
tokenResult.IsError.ShouldBeFalse();
|
||||
tokenResult.HttpErrorReason.ShouldBe("OK");
|
||||
|
|
@ -125,7 +126,7 @@ public class CodeFlowTests
|
|||
redirectUri: "https://code_pipeline.Client/callback?foo=bar&baz=quux",
|
||||
state: "state",
|
||||
nonce: nonce);
|
||||
var response = await _pipeline.BrowserClient.GetAsync(url);
|
||||
var response = await _pipeline.BrowserClient.GetAsync(url, _ct);
|
||||
|
||||
var authorization = _pipeline.ParseAuthorizationResponseUrl(response.Headers.Location.ToString());
|
||||
authorization.Code.ShouldNotBeNull();
|
||||
|
|
@ -143,7 +144,7 @@ public class CodeFlowTests
|
|||
|
||||
Code = code,
|
||||
RedirectUri = "https://code_pipeline.Client/callback?foo=bar&baz=quux"
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
tokenResult.IsError.ShouldBeFalse();
|
||||
tokenResult.HttpErrorReason.ShouldBe("OK");
|
||||
|
|
|
|||
|
|
@ -13,8 +13,8 @@ namespace Duende.IdentityServer.IntegrationTests.Conformance.Basic;
|
|||
public class RedirectUriTests
|
||||
{
|
||||
private const string Category = "Conformance.Basic.RedirectUriTests";
|
||||
|
||||
private IdentityServerPipeline _mockPipeline = new IdentityServerPipeline();
|
||||
private readonly CancellationToken _ct = TestContext.Current.CancellationToken;
|
||||
private readonly IdentityServerPipeline _mockPipeline = new IdentityServerPipeline();
|
||||
|
||||
public RedirectUriTests()
|
||||
{
|
||||
|
|
@ -72,7 +72,7 @@ public class RedirectUriTests
|
|||
redirectUri: "https://bad",
|
||||
state: state,
|
||||
nonce: nonce);
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(url);
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(url, _ct);
|
||||
|
||||
_mockPipeline.ErrorWasCalled.ShouldBeTrue();
|
||||
_mockPipeline.ErrorMessage.Error.ShouldBe("invalid_request");
|
||||
|
|
@ -95,7 +95,7 @@ public class RedirectUriTests
|
|||
redirectUri: null,
|
||||
state: state,
|
||||
nonce: nonce);
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(url);
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(url, _ct);
|
||||
|
||||
_mockPipeline.ErrorWasCalled.ShouldBeTrue();
|
||||
_mockPipeline.ErrorMessage.Error.ShouldBe("invalid_request");
|
||||
|
|
@ -118,7 +118,7 @@ public class RedirectUriTests
|
|||
redirectUri: "https://code_client/callback?foo=bar&baz=quux",
|
||||
state: state,
|
||||
nonce: nonce);
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(url);
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(url, _ct);
|
||||
|
||||
response.StatusCode.ShouldBe(HttpStatusCode.Redirect);
|
||||
response.Headers.Location.ToString().ShouldStartWith("https://code_client/callback?");
|
||||
|
|
@ -146,7 +146,7 @@ public class RedirectUriTests
|
|||
redirectUri: "https://code_client/callback?baz=quux&foo=bar",
|
||||
state: state,
|
||||
nonce: nonce);
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(url);
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(url, _ct);
|
||||
|
||||
_mockPipeline.ErrorWasCalled.ShouldBeTrue();
|
||||
_mockPipeline.ErrorMessage.Error.ShouldBe("invalid_request");
|
||||
|
|
|
|||
|
|
@ -15,8 +15,8 @@ namespace Duende.IdentityServer.IntegrationTests.Conformance.Basic;
|
|||
public class ResponseTypeResponseModeTests
|
||||
{
|
||||
private const string Category = "Conformance.Basic.ResponseTypeResponseModeTests";
|
||||
|
||||
private IdentityServerPipeline _mockPipeline = new IdentityServerPipeline();
|
||||
private readonly CancellationToken _ct = TestContext.Current.CancellationToken;
|
||||
private readonly IdentityServerPipeline _mockPipeline = new IdentityServerPipeline();
|
||||
|
||||
public ResponseTypeResponseModeTests()
|
||||
{
|
||||
|
|
@ -63,7 +63,7 @@ public class ResponseTypeResponseModeTests
|
|||
{
|
||||
await _mockPipeline.LoginAsync("bob");
|
||||
|
||||
var metadata = await _mockPipeline.BackChannelClient.GetAsync(IdentityServerPipeline.DiscoveryEndpoint);
|
||||
var metadata = await _mockPipeline.BackChannelClient.GetAsync(IdentityServerPipeline.DiscoveryEndpoint, _ct);
|
||||
metadata.StatusCode.ShouldBe(HttpStatusCode.OK);
|
||||
|
||||
var state = Guid.NewGuid().ToString();
|
||||
|
|
@ -76,7 +76,7 @@ public class ResponseTypeResponseModeTests
|
|||
redirectUri: "https://code_client/callback",
|
||||
state: state,
|
||||
nonce: nonce);
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(url);
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(url, _ct);
|
||||
response.StatusCode.ShouldBe(HttpStatusCode.Found);
|
||||
|
||||
var authorization = new AuthorizeResponse(response.Headers.Location.ToString());
|
||||
|
|
@ -109,7 +109,7 @@ public class ResponseTypeResponseModeTests
|
|||
var url = request.Create(values);
|
||||
|
||||
_mockPipeline.BrowserClient.AllowAutoRedirect = true;
|
||||
var _ = await _mockPipeline.BrowserClient.GetAsync(url);
|
||||
var _ = await _mockPipeline.BrowserClient.GetAsync(url, _ct);
|
||||
|
||||
_mockPipeline.ErrorMessage.Error.ShouldBe(OidcConstants.AuthorizeErrors.InvalidRequest);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,22 +15,19 @@ namespace Duende.IdentityServer.IntegrationTests.Conformance.Pkce;
|
|||
public class PkceTests
|
||||
{
|
||||
private const string Category = "PKCE";
|
||||
|
||||
private IdentityServerPipeline _pipeline = new IdentityServerPipeline();
|
||||
|
||||
private Client client;
|
||||
|
||||
private const string client_id = "code_client";
|
||||
private const string client_id_optional = "code_client_optional";
|
||||
private const string client_id_plain = "code_plain_client";
|
||||
private const string client_id_pkce = "codewithproofkey_client";
|
||||
private const string client_id_pkce_plain = "codewithproofkey_plain_client";
|
||||
private const string client_secret = "secret";
|
||||
private const string code_verifier = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
|
||||
private const string redirect_uri = "https://code_client/callback";
|
||||
private const string response_type = "code";
|
||||
|
||||
|
||||
private string redirect_uri = "https://code_client/callback";
|
||||
private string code_verifier = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
|
||||
private string client_secret = "secret";
|
||||
private string response_type = "code";
|
||||
private readonly CancellationToken _ct = TestContext.Current.CancellationToken;
|
||||
private Client client;
|
||||
private readonly IdentityServerPipeline _pipeline = new IdentityServerPipeline();
|
||||
|
||||
public PkceTests()
|
||||
{
|
||||
|
|
@ -208,7 +205,7 @@ public class PkceTests
|
|||
Code = code,
|
||||
RedirectUri = redirect_uri,
|
||||
CodeVerifier = code_verifier
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
tokenResponse.IsError.ShouldBeFalse();
|
||||
tokenResponse.TokenType.ShouldBe("Bearer");
|
||||
|
|
@ -248,7 +245,7 @@ public class PkceTests
|
|||
Code = code,
|
||||
RedirectUri = redirect_uri,
|
||||
CodeVerifier = code_verifier
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
tokenResponse.IsError.ShouldBeFalse();
|
||||
tokenResponse.TokenType.ShouldBe("Bearer");
|
||||
|
|
@ -301,7 +298,7 @@ public class PkceTests
|
|||
Code = code,
|
||||
RedirectUri = redirect_uri,
|
||||
CodeVerifier = code_verifier
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
tokenResponse.IsError.ShouldBeTrue();
|
||||
}
|
||||
|
|
@ -317,7 +314,6 @@ public class PkceTests
|
|||
await _pipeline.LoginAsync("bob");
|
||||
|
||||
var nonce = Guid.NewGuid().ToString();
|
||||
var code_challenge = code_verifier;
|
||||
var authorizeResponse = await _pipeline.RequestAuthorizationEndpointAsync(clientId,
|
||||
response_type,
|
||||
IdentityServerConstants.StandardScopes.OpenId,
|
||||
|
|
@ -340,7 +336,6 @@ public class PkceTests
|
|||
await _pipeline.LoginAsync("bob");
|
||||
|
||||
var nonce = Guid.NewGuid().ToString();
|
||||
var code_challenge = code_verifier;
|
||||
var authorizeResponse = await _pipeline.RequestAuthorizationEndpointAsync(clientId,
|
||||
response_type,
|
||||
IdentityServerConstants.StandardScopes.OpenId,
|
||||
|
|
@ -407,7 +402,7 @@ public class PkceTests
|
|||
|
||||
Code = code,
|
||||
RedirectUri = redirect_uri,
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
tokenResponse.IsError.ShouldBeTrue();
|
||||
tokenResponse.Error.ShouldBe(OidcConstants.TokenErrors.InvalidGrant);
|
||||
|
|
@ -444,7 +439,7 @@ public class PkceTests
|
|||
Code = code,
|
||||
RedirectUri = redirect_uri,
|
||||
CodeVerifier = "a"
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
tokenResponse.IsError.ShouldBeTrue();
|
||||
tokenResponse.Error.ShouldBe(OidcConstants.TokenErrors.InvalidGrant);
|
||||
|
|
@ -481,7 +476,7 @@ public class PkceTests
|
|||
Code = code,
|
||||
RedirectUri = redirect_uri,
|
||||
CodeVerifier = new string('a', _pipeline.Options.InputLengthRestrictions.CodeVerifierMaxLength + 1)
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
tokenResponse.IsError.ShouldBeTrue();
|
||||
tokenResponse.Error.ShouldBe(OidcConstants.TokenErrors.InvalidGrant);
|
||||
|
|
@ -518,7 +513,7 @@ public class PkceTests
|
|||
Code = code,
|
||||
RedirectUri = redirect_uri,
|
||||
CodeVerifier = "mismatched_code_verifier"
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
tokenResponse.IsError.ShouldBeTrue();
|
||||
tokenResponse.Error.ShouldBe(OidcConstants.TokenErrors.InvalidGrant);
|
||||
|
|
|
|||
|
|
@ -22,15 +22,14 @@ namespace Duende.IdentityServer.IntegrationTests.Endpoints.Authorize;
|
|||
|
||||
public class AuthorizeTests
|
||||
{
|
||||
private readonly CancellationToken _ct = TestContext.Current.CancellationToken;
|
||||
private const string Category = "Authorize endpoint";
|
||||
|
||||
private IdentityServerPipeline _mockPipeline = new IdentityServerPipeline();
|
||||
|
||||
private Client _client1;
|
||||
private readonly IdentityServerPipeline _mockPipeline = new();
|
||||
private readonly Client _client1;
|
||||
|
||||
public AuthorizeTests()
|
||||
{
|
||||
_mockPipeline.Clients.AddRange(new Client[] {
|
||||
_mockPipeline.Clients.AddRange([
|
||||
_client1 = new Client
|
||||
{
|
||||
ClientId = "client1",
|
||||
|
|
@ -72,9 +71,9 @@ public class AuthorizeTests
|
|||
RequirePkce = false,
|
||||
AllowedScopes = new List<string> { "openid", "profile", "api1", "api2" },
|
||||
RedirectUris = new List<string> { "https://client4/callback" },
|
||||
},
|
||||
}
|
||||
|
||||
});
|
||||
]);
|
||||
|
||||
_mockPipeline.Users.Add(new TestUser
|
||||
{
|
||||
|
|
@ -82,8 +81,8 @@ public class AuthorizeTests
|
|||
Username = "bob",
|
||||
Claims = new Claim[]
|
||||
{
|
||||
new Claim("name", "Bob Loblaw"),
|
||||
new Claim("email", "bob@loblaw.com"),
|
||||
new("name", "Bob Loblaw"),
|
||||
new("email", "bob@loblaw.com"),
|
||||
new Claim("role", "Attorney")
|
||||
}
|
||||
});
|
||||
|
|
@ -134,7 +133,7 @@ public class AuthorizeTests
|
|||
[Trait("Category", Category)]
|
||||
public async Task get_request_should_not_return_404()
|
||||
{
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(IdentityServerPipeline.AuthorizeEndpoint);
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(IdentityServerPipeline.AuthorizeEndpoint, _ct);
|
||||
|
||||
response.StatusCode.ShouldNotBe(HttpStatusCode.NotFound);
|
||||
}
|
||||
|
|
@ -143,7 +142,7 @@ public class AuthorizeTests
|
|||
[Trait("Category", Category)]
|
||||
public async Task post_request_without_form_should_return_415()
|
||||
{
|
||||
var response = await _mockPipeline.BrowserClient.PostAsync(IdentityServerPipeline.AuthorizeEndpoint, new StringContent("foo"));
|
||||
var response = await _mockPipeline.BrowserClient.PostAsync(IdentityServerPipeline.AuthorizeEndpoint, new StringContent("foo"), _ct);
|
||||
|
||||
response.StatusCode.ShouldBe(HttpStatusCode.UnsupportedMediaType);
|
||||
}
|
||||
|
|
@ -154,7 +153,7 @@ public class AuthorizeTests
|
|||
{
|
||||
var response = await _mockPipeline.BrowserClient.PostAsync(IdentityServerPipeline.AuthorizeEndpoint,
|
||||
new FormUrlEncodedContent(
|
||||
new Dictionary<string, string> { }));
|
||||
new Dictionary<string, string> { }), _ct);
|
||||
|
||||
response.StatusCode.ShouldBe(HttpStatusCode.OK);
|
||||
}
|
||||
|
|
@ -163,7 +162,7 @@ public class AuthorizeTests
|
|||
[Trait("Category", Category)]
|
||||
public async Task get_request_should_not_return_500()
|
||||
{
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(IdentityServerPipeline.AuthorizeEndpoint);
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(IdentityServerPipeline.AuthorizeEndpoint, _ct);
|
||||
|
||||
((int)response.StatusCode).ShouldBeLessThan(500);
|
||||
}
|
||||
|
|
@ -179,7 +178,7 @@ public class AuthorizeTests
|
|||
redirectUri: "https://client1/callback",
|
||||
state: "123_state",
|
||||
nonce: "123_nonce");
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(url);
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(url, _ct);
|
||||
|
||||
_mockPipeline.LoginWasCalled.ShouldBeTrue();
|
||||
}
|
||||
|
|
@ -215,7 +214,7 @@ public class AuthorizeTests
|
|||
ui_locales = "ui_locale_value",
|
||||
custom_foo = "foo_value"
|
||||
});
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(url + "&foo=foo1&foo=foo2");
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(url + "&foo=foo1&foo=foo2", _ct);
|
||||
|
||||
_mockPipeline.LoginRequest.ShouldNotBeNull();
|
||||
_mockPipeline.LoginRequest.Client.ClientId.ShouldBe("client1");
|
||||
|
|
@ -243,7 +242,7 @@ public class AuthorizeTests
|
|||
redirectUri: "https://client1/callback",
|
||||
state: "123_state",
|
||||
nonce: "123_nonce");
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(url);
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(url, _ct);
|
||||
|
||||
response.StatusCode.ShouldBe(HttpStatusCode.Redirect);
|
||||
response.Headers.Location.ToString().ShouldStartWith("https://client1/callback");
|
||||
|
|
@ -269,7 +268,7 @@ public class AuthorizeTests
|
|||
redirectUri: "https://client4/callback",
|
||||
state: "123_state",
|
||||
nonce: "123_nonce");
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(url);
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(url, _ct);
|
||||
|
||||
response.StatusCode.ShouldBe(HttpStatusCode.Redirect);
|
||||
response.Headers.Location.ToString().ShouldStartWith("https://client4/callback");
|
||||
|
|
@ -299,7 +298,7 @@ public class AuthorizeTests
|
|||
redirectUri: "https://client1/callback",
|
||||
state: "123_state",
|
||||
nonce: "123_nonce");
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(url);
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(url, _ct);
|
||||
|
||||
response.StatusCode.ShouldBe(HttpStatusCode.Redirect);
|
||||
response.Headers.Location.ToString().ShouldStartWith("https://client1/callback");
|
||||
|
|
@ -330,7 +329,7 @@ public class AuthorizeTests
|
|||
redirectUri: "https://client1/callback",
|
||||
state: "123_state",
|
||||
nonce: "123_nonce");
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(url);
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(url, _ct);
|
||||
|
||||
response.StatusCode.ShouldBe(HttpStatusCode.Redirect);
|
||||
response.Headers.Location.ToString().ShouldStartWith("https://client1/callback");
|
||||
|
|
@ -373,7 +372,7 @@ public class AuthorizeTests
|
|||
redirectUri: "https://client2/callback",
|
||||
state: "123_state",
|
||||
nonce: "123_nonce");
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(url);
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(url, _ct);
|
||||
|
||||
response.StatusCode.ShouldBe(HttpStatusCode.Redirect);
|
||||
response.Headers.Location.ToString().ShouldStartWith("https://client2/callback");
|
||||
|
|
@ -398,7 +397,7 @@ public class AuthorizeTests
|
|||
state: "123_state",
|
||||
nonce: "123_nonce",
|
||||
acrValues: "idp:google");
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(url);
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(url, _ct);
|
||||
|
||||
_mockPipeline.LoginWasCalled.ShouldBeTrue();
|
||||
_mockPipeline.LoginRequest.IdP.ShouldBe("google");
|
||||
|
|
@ -416,7 +415,7 @@ public class AuthorizeTests
|
|||
state: "123_state",
|
||||
nonce: "123_nonce",
|
||||
acrValues: "idp:facebook");
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(url);
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(url, _ct);
|
||||
|
||||
_mockPipeline.LoginWasCalled.ShouldBeTrue();
|
||||
_mockPipeline.LoginRequest.IdP.ShouldBeNull();
|
||||
|
|
@ -435,7 +434,7 @@ public class AuthorizeTests
|
|||
redirectUri: "https://client3/callback",
|
||||
state: "123_state",
|
||||
nonce: "123_nonce");
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(url);
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(url, _ct);
|
||||
|
||||
_mockPipeline.LoginWasCalled.ShouldBeTrue();
|
||||
_mockPipeline.LoginRequest.IdP.ShouldBeNull();
|
||||
|
|
@ -456,7 +455,7 @@ public class AuthorizeTests
|
|||
state: "123_state",
|
||||
nonce: "123_nonce",
|
||||
acrValues: "idp:idp2");
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(url);
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(url, _ct);
|
||||
|
||||
_mockPipeline.LoginWasCalled.ShouldBeTrue();
|
||||
_mockPipeline.LoginRequest.IdP.ShouldBe("idp2");
|
||||
|
|
@ -479,7 +478,7 @@ public class AuthorizeTests
|
|||
state: "123_state",
|
||||
nonce: "123_nonce",
|
||||
acrValues: "tenant:t2");
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(url);
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(url, _ct);
|
||||
|
||||
_mockPipeline.LoginWasCalled.ShouldBeTrue();
|
||||
_mockPipeline.LoginRequest.Tenant.ShouldBe("t2");
|
||||
|
|
@ -501,7 +500,7 @@ public class AuthorizeTests
|
|||
state: "123_state",
|
||||
nonce: "123_nonce",
|
||||
acrValues: "tenant:t2");
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(url);
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(url, _ct);
|
||||
|
||||
_mockPipeline.LoginWasCalled.ShouldBeFalse();
|
||||
}
|
||||
|
|
@ -519,7 +518,7 @@ public class AuthorizeTests
|
|||
redirectUri: "https://invalid",
|
||||
state: "123_state",
|
||||
nonce: "123_nonce");
|
||||
await _mockPipeline.BrowserClient.GetAsync(url);
|
||||
await _mockPipeline.BrowserClient.GetAsync(url, _ct);
|
||||
|
||||
_mockPipeline.ErrorWasCalled.ShouldBeTrue();
|
||||
_mockPipeline.ErrorMessage.ClientId.ShouldBeNull();
|
||||
|
|
@ -538,7 +537,7 @@ public class AuthorizeTests
|
|||
redirectUri: "https://invalid",
|
||||
state: "123_state",
|
||||
nonce: "123_nonce");
|
||||
await _mockPipeline.BrowserClient.GetAsync(url);
|
||||
await _mockPipeline.BrowserClient.GetAsync(url, _ct);
|
||||
|
||||
_mockPipeline.ErrorWasCalled.ShouldBeTrue();
|
||||
_mockPipeline.ErrorMessage.ClientId.ShouldBe("client1");
|
||||
|
|
@ -557,7 +556,7 @@ public class AuthorizeTests
|
|||
redirectUri: "https://invalid",
|
||||
state: "123_state",
|
||||
nonce: "123_nonce");
|
||||
await _mockPipeline.BrowserClient.GetAsync(url);
|
||||
await _mockPipeline.BrowserClient.GetAsync(url, _ct);
|
||||
|
||||
_mockPipeline.ErrorWasCalled.ShouldBeTrue();
|
||||
_mockPipeline.ErrorMessage.Error.ShouldBe(OidcConstants.AuthorizeErrors.InvalidRequest);
|
||||
|
|
@ -577,7 +576,7 @@ public class AuthorizeTests
|
|||
redirectUri: "https://invalid",
|
||||
state: "123_state",
|
||||
nonce: "123_nonce");
|
||||
await _mockPipeline.BrowserClient.GetAsync(url);
|
||||
await _mockPipeline.BrowserClient.GetAsync(url, _ct);
|
||||
|
||||
_mockPipeline.ErrorWasCalled.ShouldBeTrue();
|
||||
_mockPipeline.ErrorMessage.RedirectUri.ShouldBeNull();
|
||||
|
|
@ -597,7 +596,7 @@ public class AuthorizeTests
|
|||
redirectUri: "https://client1/callback",
|
||||
state: "123_state",
|
||||
nonce: "123_nonce");
|
||||
await _mockPipeline.BrowserClient.GetAsync(url);
|
||||
await _mockPipeline.BrowserClient.GetAsync(url, _ct);
|
||||
|
||||
_mockPipeline.ErrorWasCalled.ShouldBeTrue();
|
||||
_mockPipeline.ErrorMessage.Error.ShouldBe(OidcConstants.AuthorizeErrors.UnauthorizedClient);
|
||||
|
|
@ -616,7 +615,7 @@ public class AuthorizeTests
|
|||
redirectUri: "https://client1/callback",
|
||||
state: "123_state",
|
||||
nonce: "123_nonce");
|
||||
await _mockPipeline.BrowserClient.GetAsync(url);
|
||||
await _mockPipeline.BrowserClient.GetAsync(url, _ct);
|
||||
|
||||
_mockPipeline.ErrorWasCalled.ShouldBeTrue();
|
||||
_mockPipeline.ErrorMessage.RedirectUri.ShouldBeNull();
|
||||
|
|
@ -636,7 +635,7 @@ public class AuthorizeTests
|
|||
//redirectUri: "https://client1/callback",
|
||||
state: "123_state",
|
||||
nonce: "123_nonce");
|
||||
await _mockPipeline.BrowserClient.GetAsync(url);
|
||||
await _mockPipeline.BrowserClient.GetAsync(url, _ct);
|
||||
|
||||
_mockPipeline.ErrorWasCalled.ShouldBeTrue();
|
||||
_mockPipeline.ErrorMessage.Error.ShouldBe(OidcConstants.AuthorizeErrors.UnauthorizedClient);
|
||||
|
|
@ -656,7 +655,7 @@ public class AuthorizeTests
|
|||
//redirectUri: "https://client1/callback",
|
||||
state: "123_state",
|
||||
nonce: "123_nonce");
|
||||
await _mockPipeline.BrowserClient.GetAsync(url);
|
||||
await _mockPipeline.BrowserClient.GetAsync(url, _ct);
|
||||
|
||||
_mockPipeline.ErrorWasCalled.ShouldBeTrue();
|
||||
_mockPipeline.ErrorMessage.RedirectUri.ShouldBeNull();
|
||||
|
|
@ -676,7 +675,7 @@ public class AuthorizeTests
|
|||
redirectUri: "invalid-uri",
|
||||
state: "123_state",
|
||||
nonce: "123_nonce");
|
||||
await _mockPipeline.BrowserClient.GetAsync(url);
|
||||
await _mockPipeline.BrowserClient.GetAsync(url, _ct);
|
||||
|
||||
_mockPipeline.ErrorWasCalled.ShouldBeTrue();
|
||||
_mockPipeline.ErrorMessage.Error.ShouldBe(OidcConstants.AuthorizeErrors.UnauthorizedClient);
|
||||
|
|
@ -698,7 +697,7 @@ public class AuthorizeTests
|
|||
redirectUri: "https://client1/callback",
|
||||
state: "123_state",
|
||||
nonce: "123_nonce");
|
||||
await _mockPipeline.BrowserClient.GetAsync(url);
|
||||
await _mockPipeline.BrowserClient.GetAsync(url, _ct);
|
||||
|
||||
_mockPipeline.ErrorWasCalled.ShouldBeTrue();
|
||||
_mockPipeline.ErrorMessage.Error.ShouldBe(OidcConstants.AuthorizeErrors.UnauthorizedClient);
|
||||
|
|
@ -719,7 +718,7 @@ public class AuthorizeTests
|
|||
redirectUri: "https://client1/callback",
|
||||
state: "123_state",
|
||||
nonce: "123_nonce");
|
||||
await _mockPipeline.BrowserClient.GetAsync(url);
|
||||
await _mockPipeline.BrowserClient.GetAsync(url, _ct);
|
||||
|
||||
_mockPipeline.ErrorWasCalled.ShouldBeTrue();
|
||||
_mockPipeline.ErrorMessage.RedirectUri.ShouldBeNull();
|
||||
|
|
@ -741,7 +740,7 @@ public class AuthorizeTests
|
|||
redirectUri: "https://client1/callback",
|
||||
state: "123_state",
|
||||
nonce: "123_nonce");
|
||||
await _mockPipeline.BrowserClient.GetAsync(url);
|
||||
await _mockPipeline.BrowserClient.GetAsync(url, _ct);
|
||||
|
||||
_mockPipeline.ErrorWasCalled.ShouldBeTrue();
|
||||
_mockPipeline.ErrorMessage.Error.ShouldBe(OidcConstants.AuthorizeErrors.UnauthorizedClient);
|
||||
|
|
@ -763,7 +762,7 @@ public class AuthorizeTests
|
|||
redirectUri: "https://client1/callback",
|
||||
state: "123_state",
|
||||
nonce: "123_nonce");
|
||||
await _mockPipeline.BrowserClient.GetAsync(url);
|
||||
await _mockPipeline.BrowserClient.GetAsync(url, _ct);
|
||||
|
||||
_mockPipeline.ErrorWasCalled.ShouldBeTrue();
|
||||
_mockPipeline.ErrorMessage.RedirectUri.ShouldBeNull();
|
||||
|
|
@ -783,7 +782,7 @@ public class AuthorizeTests
|
|||
redirectUri: "https://client1/callback",
|
||||
state: "123_state",
|
||||
nonce: "123_nonce");
|
||||
await _mockPipeline.BrowserClient.GetAsync(url);
|
||||
await _mockPipeline.BrowserClient.GetAsync(url, _ct);
|
||||
|
||||
_mockPipeline.ErrorWasCalled.ShouldBeTrue();
|
||||
_mockPipeline.ErrorMessage.Error.ShouldBe(OidcConstants.AuthorizeErrors.UnsupportedResponseType);
|
||||
|
|
@ -802,7 +801,7 @@ public class AuthorizeTests
|
|||
redirectUri: "https://client1/callback",
|
||||
state: "123_state",
|
||||
nonce: "123_nonce");
|
||||
await _mockPipeline.BrowserClient.GetAsync(url);
|
||||
await _mockPipeline.BrowserClient.GetAsync(url, _ct);
|
||||
|
||||
_mockPipeline.ErrorWasCalled.ShouldBeTrue();
|
||||
_mockPipeline.ErrorMessage.RedirectUri.ShouldBeNull();
|
||||
|
|
@ -823,7 +822,7 @@ public class AuthorizeTests
|
|||
redirectUri: "https://client1/callback",
|
||||
state: "123_state",
|
||||
nonce: "123_nonce");
|
||||
await _mockPipeline.BrowserClient.GetAsync(url);
|
||||
await _mockPipeline.BrowserClient.GetAsync(url, _ct);
|
||||
|
||||
_mockPipeline.ErrorWasCalled.ShouldBeTrue();
|
||||
_mockPipeline.ErrorMessage.Error.ShouldBe(OidcConstants.AuthorizeErrors.InvalidRequest);
|
||||
|
|
@ -844,7 +843,7 @@ public class AuthorizeTests
|
|||
redirectUri: "https://client1/callback",
|
||||
state: "123_state",
|
||||
nonce: "123_nonce");
|
||||
await _mockPipeline.BrowserClient.GetAsync(url);
|
||||
await _mockPipeline.BrowserClient.GetAsync(url, _ct);
|
||||
|
||||
_mockPipeline.ErrorWasCalled.ShouldBeTrue();
|
||||
_mockPipeline.ErrorMessage.RedirectUri.ShouldBeNull();
|
||||
|
|
@ -865,7 +864,7 @@ public class AuthorizeTests
|
|||
redirectUri: "https://client1/callback",
|
||||
state: "123_state",
|
||||
nonce: "123_nonce");
|
||||
await _mockPipeline.BrowserClient.GetAsync(url);
|
||||
await _mockPipeline.BrowserClient.GetAsync(url, _ct);
|
||||
|
||||
_mockPipeline.ErrorWasCalled.ShouldBeTrue();
|
||||
_mockPipeline.ErrorMessage.Error.ShouldBe(OidcConstants.AuthorizeErrors.UnsupportedResponseType);
|
||||
|
|
@ -886,7 +885,7 @@ public class AuthorizeTests
|
|||
redirectUri: "https://client1/callback",
|
||||
state: "123_state",
|
||||
nonce: "123_nonce");
|
||||
await _mockPipeline.BrowserClient.GetAsync(url);
|
||||
await _mockPipeline.BrowserClient.GetAsync(url, _ct);
|
||||
|
||||
_mockPipeline.ErrorWasCalled.ShouldBeTrue();
|
||||
_mockPipeline.ErrorMessage.RedirectUri.ShouldBeNull();
|
||||
|
|
@ -906,7 +905,7 @@ public class AuthorizeTests
|
|||
redirectUri: "https://client1/callback",
|
||||
state: "123_state",
|
||||
nonce: "123_nonce");
|
||||
await _mockPipeline.BrowserClient.GetAsync(url);
|
||||
await _mockPipeline.BrowserClient.GetAsync(url, _ct);
|
||||
|
||||
_mockPipeline.ErrorWasCalled.ShouldBeTrue();
|
||||
_mockPipeline.ErrorMessage.Error.ShouldBe(OidcConstants.AuthorizeErrors.InvalidRequest);
|
||||
|
|
@ -926,7 +925,7 @@ public class AuthorizeTests
|
|||
redirectUri: "https://client1/callback",
|
||||
state: "123_state",
|
||||
nonce: "123_nonce");
|
||||
await _mockPipeline.BrowserClient.GetAsync(url);
|
||||
await _mockPipeline.BrowserClient.GetAsync(url, _ct);
|
||||
|
||||
_mockPipeline.ErrorWasCalled.ShouldBeTrue();
|
||||
_mockPipeline.ErrorMessage.RedirectUri.ShouldBeNull();
|
||||
|
|
@ -947,7 +946,7 @@ public class AuthorizeTests
|
|||
redirectUri: "https://client1/callback",
|
||||
state: "123_state",
|
||||
nonce: "123_nonce");
|
||||
await _mockPipeline.BrowserClient.GetAsync(url);
|
||||
await _mockPipeline.BrowserClient.GetAsync(url, _ct);
|
||||
|
||||
_mockPipeline.ErrorWasCalled.ShouldBeTrue();
|
||||
_mockPipeline.ErrorMessage.RedirectUri.ShouldBeNull();
|
||||
|
|
@ -967,7 +966,7 @@ public class AuthorizeTests
|
|||
redirectUri: "https://client1/callback",
|
||||
state: "123_state",
|
||||
nonce: "123_nonce");
|
||||
await _mockPipeline.BrowserClient.GetAsync(url);
|
||||
await _mockPipeline.BrowserClient.GetAsync(url, _ct);
|
||||
|
||||
_mockPipeline.ErrorWasCalled.ShouldBeTrue();
|
||||
_mockPipeline.ErrorMessage.Error.ShouldBe(OidcConstants.AuthorizeErrors.InvalidRequest);
|
||||
|
|
@ -989,7 +988,7 @@ public class AuthorizeTests
|
|||
redirectUri: "https://client1/callback",
|
||||
state: "123_state",
|
||||
nonce: "123_nonce");
|
||||
await _mockPipeline.BrowserClient.GetAsync(url);
|
||||
await _mockPipeline.BrowserClient.GetAsync(url, _ct);
|
||||
|
||||
_mockPipeline.ErrorWasCalled.ShouldBeTrue();
|
||||
_mockPipeline.ErrorMessage.Error.ShouldBe(OidcConstants.AuthorizeErrors.InvalidRequest);
|
||||
|
|
@ -1012,7 +1011,7 @@ public class AuthorizeTests
|
|||
redirectUri: "https://client1/callback",
|
||||
state: "123_state",
|
||||
nonce: "123_nonce");
|
||||
await _mockPipeline.BrowserClient.GetAsync(url);
|
||||
await _mockPipeline.BrowserClient.GetAsync(url, _ct);
|
||||
|
||||
_mockPipeline.ErrorWasCalled.ShouldBeTrue();
|
||||
_mockPipeline.ErrorMessage.Error.ShouldBe(OidcConstants.AuthorizeErrors.InvalidScope);
|
||||
|
|
@ -1035,7 +1034,7 @@ public class AuthorizeTests
|
|||
state: "123_state"
|
||||
//nonce: "123_nonce"
|
||||
);
|
||||
await _mockPipeline.BrowserClient.GetAsync(url);
|
||||
await _mockPipeline.BrowserClient.GetAsync(url, _ct);
|
||||
|
||||
_mockPipeline.ErrorWasCalled.ShouldBeTrue();
|
||||
_mockPipeline.ErrorMessage.Error.ShouldBe(OidcConstants.AuthorizeErrors.InvalidRequest);
|
||||
|
|
@ -1057,7 +1056,7 @@ public class AuthorizeTests
|
|||
redirectUri: "https://client1/callback",
|
||||
state: "123_state",
|
||||
nonce: new string('x', 500));
|
||||
await _mockPipeline.BrowserClient.GetAsync(url);
|
||||
await _mockPipeline.BrowserClient.GetAsync(url, _ct);
|
||||
|
||||
_mockPipeline.ErrorWasCalled.ShouldBeTrue();
|
||||
_mockPipeline.ErrorMessage.Error.ShouldBe(OidcConstants.AuthorizeErrors.InvalidRequest);
|
||||
|
|
@ -1080,7 +1079,7 @@ public class AuthorizeTests
|
|||
state: "123_state",
|
||||
nonce: "123_nonce",
|
||||
extra: new { ui_locales = new string('x', 500) });
|
||||
await _mockPipeline.BrowserClient.GetAsync(url);
|
||||
await _mockPipeline.BrowserClient.GetAsync(url, _ct);
|
||||
|
||||
_mockPipeline.ErrorWasCalled.ShouldBeTrue();
|
||||
_mockPipeline.ErrorMessage.Error.ShouldBe(OidcConstants.AuthorizeErrors.InvalidRequest);
|
||||
|
|
@ -1103,7 +1102,7 @@ public class AuthorizeTests
|
|||
state: "123_state",
|
||||
nonce: "123_nonce",
|
||||
extra: new { max_age = "invalid" });
|
||||
await _mockPipeline.BrowserClient.GetAsync(url);
|
||||
await _mockPipeline.BrowserClient.GetAsync(url, _ct);
|
||||
|
||||
_mockPipeline.ErrorWasCalled.ShouldBeTrue();
|
||||
_mockPipeline.ErrorMessage.Error.ShouldBe(OidcConstants.AuthorizeErrors.InvalidRequest);
|
||||
|
|
@ -1126,7 +1125,7 @@ public class AuthorizeTests
|
|||
state: "123_state",
|
||||
nonce: "123_nonce",
|
||||
extra: new { max_age = "-10" });
|
||||
await _mockPipeline.BrowserClient.GetAsync(url);
|
||||
await _mockPipeline.BrowserClient.GetAsync(url, _ct);
|
||||
|
||||
_mockPipeline.ErrorWasCalled.ShouldBeTrue();
|
||||
_mockPipeline.ErrorMessage.Error.ShouldBe(OidcConstants.AuthorizeErrors.InvalidRequest);
|
||||
|
|
@ -1149,7 +1148,7 @@ public class AuthorizeTests
|
|||
state: "123_state",
|
||||
nonce: "123_nonce",
|
||||
loginHint: new string('x', 500));
|
||||
await _mockPipeline.BrowserClient.GetAsync(url);
|
||||
await _mockPipeline.BrowserClient.GetAsync(url, _ct);
|
||||
|
||||
_mockPipeline.ErrorWasCalled.ShouldBeTrue();
|
||||
_mockPipeline.ErrorMessage.Error.ShouldBe(OidcConstants.AuthorizeErrors.InvalidRequest);
|
||||
|
|
@ -1172,7 +1171,7 @@ public class AuthorizeTests
|
|||
state: "123_state",
|
||||
nonce: "123_nonce",
|
||||
acrValues: new string('x', 500));
|
||||
await _mockPipeline.BrowserClient.GetAsync(url);
|
||||
await _mockPipeline.BrowserClient.GetAsync(url, _ct);
|
||||
|
||||
_mockPipeline.ErrorWasCalled.ShouldBeTrue();
|
||||
_mockPipeline.ErrorMessage.Error.ShouldBe(OidcConstants.AuthorizeErrors.InvalidRequest);
|
||||
|
|
@ -1200,7 +1199,7 @@ public class AuthorizeTests
|
|||
state: "123_state",
|
||||
nonce: "123_nonce");
|
||||
|
||||
Func<Task> a = () => _mockPipeline.BrowserClient.GetAsync(url);
|
||||
Func<Task> a = () => _mockPipeline.BrowserClient.GetAsync(url, _ct);
|
||||
await a.ShouldThrowAsync<Exception>();
|
||||
}
|
||||
|
||||
|
|
@ -1219,7 +1218,7 @@ public class AuthorizeTests
|
|||
nonce: "123_nonce",
|
||||
acrValues: new string('x', 500),
|
||||
extra: new { ui_locales = "fr-FR" });
|
||||
await _mockPipeline.BrowserClient.GetAsync(url);
|
||||
await _mockPipeline.BrowserClient.GetAsync(url, _ct);
|
||||
|
||||
_mockPipeline.ErrorWasCalled.ShouldBeTrue();
|
||||
_mockPipeline.ErrorMessage.UiLocales.ShouldBe("fr-FR");
|
||||
|
|
@ -1240,7 +1239,7 @@ public class AuthorizeTests
|
|||
nonce: "123_nonce",
|
||||
acrValues: new string('x', 500),
|
||||
extra: new { display = "popup" });
|
||||
await _mockPipeline.BrowserClient.GetAsync(url);
|
||||
await _mockPipeline.BrowserClient.GetAsync(url, _ct);
|
||||
|
||||
_mockPipeline.ErrorWasCalled.ShouldBeTrue();
|
||||
_mockPipeline.ErrorMessage.DisplayMode.ShouldBe("popup");
|
||||
|
|
@ -1259,7 +1258,7 @@ public class AuthorizeTests
|
|||
nonce: "123_nonce");
|
||||
url = url.Replace(IdentityServerPipeline.BaseUrl, "https://грант.рф");
|
||||
|
||||
var result = await _mockPipeline.BackChannelClient.GetAsync(url);
|
||||
var result = await _mockPipeline.BackChannelClient.GetAsync(url, _ct);
|
||||
result.Headers.Location.Authority.ShouldBe("xn--80af5akm.xn--p1ai");
|
||||
}
|
||||
|
||||
|
|
@ -1276,7 +1275,7 @@ public class AuthorizeTests
|
|||
state: "123_state",
|
||||
nonce: "123_nonce");
|
||||
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(url);
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(url, _ct);
|
||||
_mockPipeline.LoginWasCalled.ShouldBeTrue();
|
||||
}
|
||||
|
||||
|
|
@ -1295,7 +1294,7 @@ public class AuthorizeTests
|
|||
nonce: "123_nonce",
|
||||
extra: new { prompt = "login" }
|
||||
);
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(url);
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(url, _ct);
|
||||
|
||||
_mockPipeline.LoginWasCalled.ShouldBeTrue();
|
||||
_mockPipeline.LoginRequest.PromptModes.ShouldContain("login");
|
||||
|
|
@ -1316,7 +1315,7 @@ public class AuthorizeTests
|
|||
nonce: "123_nonce",
|
||||
extra: new { max_age = "0" }
|
||||
);
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(url);
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(url, _ct);
|
||||
|
||||
_mockPipeline.LoginWasCalled.ShouldBeTrue();
|
||||
}
|
||||
|
|
@ -1337,11 +1336,11 @@ public class AuthorizeTests
|
|||
extra: new { prompt = "login" }
|
||||
);
|
||||
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(url);
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(url, _ct);
|
||||
|
||||
// this simulates the login page returning to the returnUrl which is the authorize callback page
|
||||
_mockPipeline.BrowserClient.AllowAutoRedirect = false;
|
||||
response = await _mockPipeline.BrowserClient.GetAsync(IdentityServerPipeline.BaseUrl + _mockPipeline.LoginReturnUrl);
|
||||
response = await _mockPipeline.BrowserClient.GetAsync(IdentityServerPipeline.BaseUrl + _mockPipeline.LoginReturnUrl, _ct);
|
||||
response.StatusCode.ShouldBe(HttpStatusCode.Redirect);
|
||||
response.Headers.Location.ToString().ShouldStartWith("https://client1/callback");
|
||||
response.Headers.Location.ToString().ShouldContain("id_token=");
|
||||
|
|
@ -1363,11 +1362,11 @@ public class AuthorizeTests
|
|||
extra: new { max_age = "0" }
|
||||
);
|
||||
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(url);
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(url, _ct);
|
||||
|
||||
// this simulates the login page returning to the returnUrl which is the authorize callback page
|
||||
_mockPipeline.BrowserClient.AllowAutoRedirect = false;
|
||||
response = await _mockPipeline.BrowserClient.GetAsync(IdentityServerPipeline.BaseUrl + _mockPipeline.LoginReturnUrl);
|
||||
response = await _mockPipeline.BrowserClient.GetAsync(IdentityServerPipeline.BaseUrl + _mockPipeline.LoginReturnUrl, _ct);
|
||||
response.StatusCode.ShouldBe(HttpStatusCode.Redirect);
|
||||
response.Headers.Location.ToString().ShouldStartWith("https://client1/callback");
|
||||
response.Headers.Location.ToString().ShouldContain("id_token=");
|
||||
|
|
@ -1386,7 +1385,7 @@ public class AuthorizeTests
|
|||
nonce: "123_nonce",
|
||||
extra: new { prompt = "unknown" }
|
||||
);
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(url);
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(url, _ct);
|
||||
|
||||
_mockPipeline.ErrorWasCalled.ShouldBeTrue();
|
||||
}
|
||||
|
|
@ -1404,7 +1403,7 @@ public class AuthorizeTests
|
|||
nonce: "123_nonce",
|
||||
extra: new { prompt = "create" }
|
||||
);
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(url);
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(url, _ct);
|
||||
|
||||
_mockPipeline.ErrorWasCalled.ShouldBeTrue();
|
||||
}
|
||||
|
|
@ -1433,7 +1432,7 @@ public class AuthorizeTests
|
|||
nonce: "123_nonce",
|
||||
extra: new { prompt = "create" }
|
||||
);
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(url);
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(url, _ct);
|
||||
|
||||
_mockPipeline.CreateAccountWasCalled.ShouldBeTrue();
|
||||
_mockPipeline.CreateAccountRequest.PromptModes.ShouldContain("create");
|
||||
|
|
@ -1463,7 +1462,7 @@ public class AuthorizeTests
|
|||
nonce: "123_nonce",
|
||||
extra: new { prompt = "create login" }
|
||||
);
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(url);
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(url, _ct);
|
||||
|
||||
_mockPipeline.ErrorWasCalled.ShouldBeTrue();
|
||||
}
|
||||
|
|
@ -1512,7 +1511,7 @@ public class AuthorizeTests
|
|||
ui_locales = "ui_locale_value",
|
||||
custom_foo = "foo_value"
|
||||
});
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(url + "&foo=bar");
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(url + "&foo=bar", _ct);
|
||||
|
||||
_mockPipeline.CustomWasCalled.ShouldBeTrue();
|
||||
|
||||
|
|
@ -1546,7 +1545,7 @@ public class AuthorizeTests
|
|||
|
||||
_mockPipeline.BrowserClient.AllowAutoRedirect = false;
|
||||
|
||||
Func<Task> a = () => _mockPipeline.BrowserClient.GetAsync(url);
|
||||
Func<Task> a = () => _mockPipeline.BrowserClient.GetAsync(url, _ct);
|
||||
await a.ShouldThrowAsync<Exception>();
|
||||
}
|
||||
|
||||
|
|
@ -1577,7 +1576,7 @@ public class AuthorizeTests
|
|||
|
||||
_mockPipeline.BrowserClient.AllowAutoRedirect = false;
|
||||
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(url);
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(url, _ct);
|
||||
response.Headers.Location.GetLeftPart(UriPartial.Path).ShouldBe("https://server/custom");
|
||||
mockAuthzInteractionService.Request.PromptModes.ShouldContain("custom-prompt");
|
||||
mockAuthzInteractionService.Request.PromptModes.Count().ShouldBe(1);
|
||||
|
|
@ -1599,7 +1598,7 @@ public class AuthorizeTests
|
|||
ui_locales = "nb-NO"
|
||||
});
|
||||
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(url);
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(url, _ct);
|
||||
|
||||
_mockPipeline.LoginWasCalled.ShouldBeTrue();
|
||||
|
||||
|
|
@ -1626,7 +1625,7 @@ public class AuthorizeTests
|
|||
ui_locales = "nb-NO"
|
||||
});
|
||||
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(url);
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(url, _ct);
|
||||
|
||||
_mockPipeline.ConsentWasCalled.ShouldBeTrue();
|
||||
|
||||
|
|
@ -1663,7 +1662,7 @@ public class AuthorizeTests
|
|||
ui_locales = "nb-NO"
|
||||
});
|
||||
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(url);
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(url, _ct);
|
||||
|
||||
_mockPipeline.CreateAccountWasCalled.ShouldBeTrue();
|
||||
|
||||
|
|
@ -1687,7 +1686,7 @@ public class AuthorizeTests
|
|||
ui_locales = "nb-NO"
|
||||
});
|
||||
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(url);
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(url, _ct);
|
||||
|
||||
_mockPipeline.ErrorWasCalled.ShouldBeTrue();
|
||||
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ namespace Duende.IdentityServer.IntegrationTests.Endpoints.Authorize;
|
|||
|
||||
public class ConsentTests
|
||||
{
|
||||
private readonly CancellationToken _ct = TestContext.Current.CancellationToken;
|
||||
private const string Category = "Authorize and consent tests";
|
||||
|
||||
private IdentityServerPipeline _mockPipeline = new IdentityServerPipeline();
|
||||
|
|
@ -110,7 +111,7 @@ public class ConsentTests
|
|||
state: "123_state",
|
||||
nonce: "123_nonce"
|
||||
);
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(url);
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(url, _ct);
|
||||
|
||||
_mockPipeline.ConsentWasCalled.ShouldBeTrue();
|
||||
}
|
||||
|
|
@ -149,7 +150,7 @@ public class ConsentTests
|
|||
custom_foo = "foo_value"
|
||||
}
|
||||
);
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(url);
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(url, _ct);
|
||||
|
||||
_mockPipeline.ConsentRequest.ShouldNotBeNull();
|
||||
_mockPipeline.ConsentRequest.Client.ClientId.ShouldBe("client2");
|
||||
|
|
@ -193,7 +194,7 @@ public class ConsentTests
|
|||
redirectUri: "https://client2/callback",
|
||||
state: "123_state",
|
||||
nonce: "123_nonce");
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(url);
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(url, _ct);
|
||||
|
||||
response.StatusCode.ShouldBe(HttpStatusCode.Redirect);
|
||||
response.Headers.Location.ToString().ShouldStartWith("https://client2/callback");
|
||||
|
|
@ -225,12 +226,12 @@ public class ConsentTests
|
|||
redirectUri: "https://client2/callback",
|
||||
state: "123_state",
|
||||
nonce: "123_nonce");
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(url);
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(url, _ct);
|
||||
|
||||
response.StatusCode.ShouldBe(HttpStatusCode.Redirect);
|
||||
response.Headers.Location.ToString().ShouldStartWith("https://server/consent");
|
||||
|
||||
response = await _mockPipeline.BrowserClient.GetAsync(response.Headers.Location.ToString());
|
||||
response = await _mockPipeline.BrowserClient.GetAsync(response.Headers.Location.ToString(), _ct);
|
||||
|
||||
response.StatusCode.ShouldBe(HttpStatusCode.Redirect);
|
||||
response.Headers.Location.ToString().ShouldStartWith("/connect/authorize/callback");
|
||||
|
|
@ -238,7 +239,7 @@ public class ConsentTests
|
|||
var modifiedAuthorizeCallback = "https://server" + response.Headers.Location;
|
||||
modifiedAuthorizeCallback = modifiedAuthorizeCallback.Replace("api2", "api1%20api2");
|
||||
|
||||
response = await _mockPipeline.BrowserClient.GetAsync(modifiedAuthorizeCallback);
|
||||
response = await _mockPipeline.BrowserClient.GetAsync(modifiedAuthorizeCallback, _ct);
|
||||
response.StatusCode.ShouldBe(HttpStatusCode.Redirect);
|
||||
response.Headers.Location.ToString().ShouldStartWith("https://server/consent");
|
||||
}
|
||||
|
|
@ -262,7 +263,7 @@ public class ConsentTests
|
|||
redirectUri: "https://client2/callback",
|
||||
state: "123_state",
|
||||
nonce: "123_nonce");
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(url);
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(url, _ct);
|
||||
response.StatusCode.ShouldBe(HttpStatusCode.Redirect);
|
||||
response.Headers.Location.ToString().ShouldStartWith("https://client2/callback");
|
||||
|
||||
|
|
@ -304,7 +305,7 @@ public class ConsentTests
|
|||
redirectUri: "https://client2/callback",
|
||||
state: "123_state",
|
||||
nonce: "123_nonce");
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(url);
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(url, _ct);
|
||||
|
||||
response.StatusCode.ShouldBe(HttpStatusCode.Redirect);
|
||||
response.Headers.Location.ToString().ShouldStartWith("https://client2/callback");
|
||||
|
|
@ -347,7 +348,7 @@ public class ConsentTests
|
|||
redirectUri: "https://client2/callback",
|
||||
state: "123_state",
|
||||
nonce: "123_nonce");
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(url);
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(url, _ct);
|
||||
|
||||
response.StatusCode.ShouldBe(HttpStatusCode.Redirect);
|
||||
response.Headers.Location.ToString().ShouldStartWith("https://client2/callback");
|
||||
|
|
@ -407,7 +408,7 @@ public class ConsentTests
|
|||
nonce: "123_nonce"
|
||||
);
|
||||
_mockPipeline.BrowserClient.AllowAutoRedirect = false;
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(url);
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(url, _ct);
|
||||
|
||||
// The existing legacy consent should apply - user isn't show consent screen
|
||||
response.StatusCode.ShouldBe(HttpStatusCode.Redirect);
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
// Copyright (c) Duende Software. All rights reserved.
|
||||
// See LICENSE in the project root for license information.
|
||||
|
||||
|
||||
using System.IdentityModel.Tokens.Jwt;
|
||||
using System.Net;
|
||||
using System.Net.Http.Headers;
|
||||
|
|
@ -24,7 +23,7 @@ namespace Duende.IdentityServer.IntegrationTests.Endpoints.Authorize;
|
|||
public class JwtRequestAuthorizeTests
|
||||
{
|
||||
private const string Category = "Authorize endpoint with JWT requests";
|
||||
|
||||
private readonly CancellationToken _ct = TestContext.Current.CancellationToken;
|
||||
private readonly IdentityServerPipeline _mockPipeline = new IdentityServerPipeline();
|
||||
private readonly Client _client;
|
||||
|
||||
|
|
@ -209,7 +208,7 @@ public class JwtRequestAuthorizeTests
|
|||
nonce: "123nonce",
|
||||
redirectUri: "https://client/callback");
|
||||
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(url);
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(url, _ct);
|
||||
|
||||
_mockPipeline.ErrorMessage.Error.ShouldBe("invalid_request");
|
||||
_mockPipeline.ErrorMessage.ErrorDescription.ShouldBe("Client must use request object, but no request or request_uri parameter present");
|
||||
|
|
@ -245,7 +244,7 @@ public class JwtRequestAuthorizeTests
|
|||
{
|
||||
request = requestJwt
|
||||
});
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(url);
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(url, _ct);
|
||||
|
||||
_mockPipeline.LoginRequest.ShouldNotBeNull();
|
||||
_mockPipeline.LoginRequest.Client.ClientId.ShouldBe(_client.ClientId);
|
||||
|
|
@ -293,7 +292,7 @@ public class JwtRequestAuthorizeTests
|
|||
{
|
||||
request = requestJwt
|
||||
});
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(url);
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(url, _ct);
|
||||
|
||||
_mockPipeline.LoginRequest.ShouldNotBeNull();
|
||||
_mockPipeline.LoginRequest.Client.ClientId.ShouldBe(_client.ClientId);
|
||||
|
|
@ -340,7 +339,7 @@ public class JwtRequestAuthorizeTests
|
|||
{
|
||||
request = requestJwt
|
||||
});
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(url);
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(url, _ct);
|
||||
|
||||
_mockPipeline.LoginRequest.ShouldNotBeNull();
|
||||
_mockPipeline.LoginRequest.Client.ClientId.ShouldBe(_client.ClientId);
|
||||
|
|
@ -393,7 +392,7 @@ public class JwtRequestAuthorizeTests
|
|||
var url = _mockPipeline.CreateAuthorizeUrl(
|
||||
clientId: _client.ClientId,
|
||||
requestUri: parResponse.RootElement.GetProperty("request_uri").GetString());
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(url);
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(url, _ct);
|
||||
|
||||
_mockPipeline.LoginRequest.ShouldNotBeNull();
|
||||
_mockPipeline.LoginRequest.Client.ClientId.ShouldBe(_client.ClientId);
|
||||
|
|
@ -452,7 +451,7 @@ public class JwtRequestAuthorizeTests
|
|||
{
|
||||
request = requestJwt
|
||||
});
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(url);
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(url, _ct);
|
||||
|
||||
_mockPipeline.LoginRequest.ShouldNotBeNull();
|
||||
_mockPipeline.LoginRequest.Client.ClientId.ShouldBe(_client.ClientId);
|
||||
|
|
@ -505,7 +504,7 @@ public class JwtRequestAuthorizeTests
|
|||
{
|
||||
request = requestJwt
|
||||
});
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(url);
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(url, _ct);
|
||||
|
||||
_mockPipeline.LoginRequest.ShouldNotBeNull();
|
||||
_mockPipeline.LoginRequest.Client.ClientId.ShouldBe(_client.ClientId);
|
||||
|
|
@ -554,7 +553,7 @@ public class JwtRequestAuthorizeTests
|
|||
{
|
||||
request = requestJwt
|
||||
});
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(url);
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(url, _ct);
|
||||
|
||||
_mockPipeline.ErrorMessage.Error.ShouldBe("invalid_request_object");
|
||||
_mockPipeline.LoginRequest.ShouldBeNull();
|
||||
|
|
@ -597,7 +596,7 @@ public class JwtRequestAuthorizeTests
|
|||
{
|
||||
request = requestJwt
|
||||
});
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(url);
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(url, _ct);
|
||||
|
||||
_mockPipeline.LoginRequest.ShouldNotBeNull();
|
||||
|
||||
|
|
@ -646,7 +645,7 @@ public class JwtRequestAuthorizeTests
|
|||
{
|
||||
request = requestJwt
|
||||
});
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(url);
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(url, _ct);
|
||||
|
||||
_mockPipeline.ErrorMessage.Error.ShouldBe("invalid_request");
|
||||
_mockPipeline.ErrorMessage.ErrorDescription.ShouldBe("Invalid client_id");
|
||||
|
|
@ -681,7 +680,7 @@ public class JwtRequestAuthorizeTests
|
|||
{
|
||||
request = requestJwt
|
||||
});
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(url);
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(url, _ct);
|
||||
|
||||
_mockPipeline.ErrorMessage.Error.ShouldBe("invalid_request_object");
|
||||
_mockPipeline.ErrorMessage.ErrorDescription.ShouldBe("Invalid JWT request");
|
||||
|
|
@ -718,7 +717,7 @@ public class JwtRequestAuthorizeTests
|
|||
request = requestJwt
|
||||
});
|
||||
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(url);
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(url, _ct);
|
||||
|
||||
_mockPipeline.ErrorMessage.Error.ShouldBe("invalid_request_object");
|
||||
_mockPipeline.ErrorMessage.ErrorDescription.ShouldBe("Invalid JWT request");
|
||||
|
|
@ -755,7 +754,7 @@ public class JwtRequestAuthorizeTests
|
|||
request = requestJwt
|
||||
});
|
||||
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(url);
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(url, _ct);
|
||||
|
||||
_mockPipeline.ErrorMessage.Error.ShouldBe("invalid_request_object");
|
||||
_mockPipeline.ErrorMessage.ErrorDescription.ShouldBe("Invalid JWT request");
|
||||
|
|
@ -792,7 +791,7 @@ public class JwtRequestAuthorizeTests
|
|||
request = requestJwt
|
||||
});
|
||||
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(url);
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(url, _ct);
|
||||
|
||||
_mockPipeline.ErrorMessage.Error.ShouldBe("invalid_request_object");
|
||||
_mockPipeline.ErrorMessage.ErrorDescription.ShouldBe("Invalid JWT request");
|
||||
|
|
@ -829,7 +828,7 @@ public class JwtRequestAuthorizeTests
|
|||
request = requestJwt
|
||||
});
|
||||
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(url);
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(url, _ct);
|
||||
|
||||
_mockPipeline.ErrorMessage.Error.ShouldBe("invalid_request_object");
|
||||
_mockPipeline.ErrorMessage.ErrorDescription.ShouldBe("Invalid JWT request");
|
||||
|
|
@ -865,7 +864,7 @@ public class JwtRequestAuthorizeTests
|
|||
request = requestJwt
|
||||
});
|
||||
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(url);
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(url, _ct);
|
||||
|
||||
_mockPipeline.ErrorMessage.Error.ShouldBe("invalid_request");
|
||||
_mockPipeline.ErrorMessage.ErrorDescription.ShouldBe("Invalid JWT request");
|
||||
|
|
@ -902,7 +901,7 @@ public class JwtRequestAuthorizeTests
|
|||
request = requestJwt
|
||||
});
|
||||
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(url);
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(url, _ct);
|
||||
|
||||
_mockPipeline.ErrorMessage.Error.ShouldBe("invalid_request");
|
||||
_mockPipeline.ErrorMessage.ErrorDescription.ShouldBe("Invalid JWT request");
|
||||
|
|
@ -939,7 +938,7 @@ public class JwtRequestAuthorizeTests
|
|||
{
|
||||
request = requestJwt
|
||||
});
|
||||
_ = await _mockPipeline.BrowserClient.GetAsync(url);
|
||||
_ = await _mockPipeline.BrowserClient.GetAsync(url, _ct);
|
||||
|
||||
_mockPipeline.ErrorMessage.Error.ShouldBe("invalid_request_object");
|
||||
_mockPipeline.ErrorMessage.ErrorDescription.ShouldBe("Invalid JWT request");
|
||||
|
|
@ -984,7 +983,7 @@ public class JwtRequestAuthorizeTests
|
|||
{
|
||||
request_uri = "http://client_jwt"
|
||||
});
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(url);
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(url, _ct);
|
||||
_mockPipeline.ErrorWasCalled.ShouldBeTrue();
|
||||
|
||||
_mockPipeline.JwtRequestMessageHandler.InvokeWasCalled.ShouldBeFalse();
|
||||
|
|
@ -1030,7 +1029,7 @@ public class JwtRequestAuthorizeTests
|
|||
{
|
||||
request_uri = "http://client_jwt"
|
||||
});
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(url);
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(url, _ct);
|
||||
|
||||
_mockPipeline.LoginRequest.ShouldNotBeNull();
|
||||
_mockPipeline.LoginRequest.Client.ClientId.ShouldBe(_client.ClientId);
|
||||
|
|
@ -1099,7 +1098,7 @@ public class JwtRequestAuthorizeTests
|
|||
{
|
||||
request_uri = "http://client_jwt"
|
||||
});
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(url);
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(url, _ct);
|
||||
|
||||
_mockPipeline.LoginRequest.ShouldNotBeNull();
|
||||
_mockPipeline.LoginRequest.Client.ClientId.ShouldBe(_client.ClientId);
|
||||
|
|
@ -1160,7 +1159,7 @@ public class JwtRequestAuthorizeTests
|
|||
{
|
||||
request_uri = "http://client_jwt"
|
||||
});
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(url);
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(url, _ct);
|
||||
|
||||
_mockPipeline.LoginRequest.ShouldNotBeNull();
|
||||
_mockPipeline.LoginRequest.Client.ClientId.ShouldBe(_client.ClientId);
|
||||
|
|
@ -1215,7 +1214,7 @@ public class JwtRequestAuthorizeTests
|
|||
{
|
||||
request_uri = "http://client_jwt"
|
||||
});
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(url);
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(url, _ct);
|
||||
|
||||
_mockPipeline.ErrorMessage.Error.ShouldBe("invalid_request_uri");
|
||||
_mockPipeline.LoginRequest.ShouldBeNull();
|
||||
|
|
@ -1237,7 +1236,7 @@ public class JwtRequestAuthorizeTests
|
|||
{
|
||||
request_uri = "http://client_jwt"
|
||||
});
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(url);
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(url, _ct);
|
||||
|
||||
_mockPipeline.ErrorWasCalled.ShouldBeTrue();
|
||||
_mockPipeline.LoginRequest.ShouldBeNull();
|
||||
|
|
@ -1260,7 +1259,7 @@ public class JwtRequestAuthorizeTests
|
|||
{
|
||||
request_uri = "http://client_jwt"
|
||||
});
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(url);
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(url, _ct);
|
||||
|
||||
_mockPipeline.ErrorWasCalled.ShouldBeTrue();
|
||||
_mockPipeline.LoginRequest.ShouldBeNull();
|
||||
|
|
@ -1281,7 +1280,7 @@ public class JwtRequestAuthorizeTests
|
|||
{
|
||||
request_uri = "http://" + new string('x', 512)
|
||||
});
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(url);
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(url, _ct);
|
||||
_mockPipeline.ErrorWasCalled.ShouldBeTrue();
|
||||
_mockPipeline.LoginRequest.ShouldBeNull();
|
||||
|
||||
|
|
@ -1322,7 +1321,7 @@ public class JwtRequestAuthorizeTests
|
|||
request = requestJwt,
|
||||
request_uri = "http://client_jwt"
|
||||
});
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(url);
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(url, _ct);
|
||||
_mockPipeline.ErrorWasCalled.ShouldBeTrue();
|
||||
_mockPipeline.LoginRequest.ShouldBeNull();
|
||||
|
||||
|
|
@ -1368,11 +1367,11 @@ public class JwtRequestAuthorizeTests
|
|||
{
|
||||
request = requestJwt
|
||||
});
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(url);
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(url, _ct);
|
||||
|
||||
// this simulates the login page returning to the returnUrl which is the authorize callback page
|
||||
_mockPipeline.BrowserClient.AllowAutoRedirect = false;
|
||||
response = await _mockPipeline.BrowserClient.GetAsync(IdentityServerPipeline.BaseUrl + _mockPipeline.LoginReturnUrl);
|
||||
response = await _mockPipeline.BrowserClient.GetAsync(IdentityServerPipeline.BaseUrl + _mockPipeline.LoginReturnUrl, _ct);
|
||||
|
||||
response.StatusCode.ShouldBe(HttpStatusCode.Found);
|
||||
response.Headers.Location!.ToString().ShouldSatisfyAllConditions(
|
||||
|
|
@ -1428,7 +1427,7 @@ public class JwtRequestAuthorizeTests
|
|||
};
|
||||
_mockPipeline.BrowserClient.StopRedirectingAfter = 2;
|
||||
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(url);
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(url, _ct);
|
||||
|
||||
|
||||
response.StatusCode.ShouldBe(HttpStatusCode.Redirect);
|
||||
|
|
|
|||
|
|
@ -18,9 +18,10 @@ namespace Duende.IdentityServer.IntegrationTests.Endpoints.Authorize;
|
|||
|
||||
public class PushedAuthorizationTests
|
||||
{
|
||||
private readonly CancellationToken _ct = TestContext.Current.CancellationToken;
|
||||
private readonly IdentityServerPipeline _mockPipeline = new();
|
||||
private Client _client;
|
||||
private string clientSecret = Guid.NewGuid().ToString();
|
||||
private readonly string clientSecret = Guid.NewGuid().ToString();
|
||||
private Client _client2;
|
||||
|
||||
private WilsonJsonWebKey _privateKey;
|
||||
|
|
@ -58,7 +59,7 @@ public class PushedAuthorizationTests
|
|||
var authorizeUrl = _mockPipeline.CreateAuthorizeUrl(
|
||||
clientId: "client1",
|
||||
requestUri: parJson.RootElement.GetProperty("request_uri").GetString());
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(authorizeUrl);
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(authorizeUrl, _ct);
|
||||
|
||||
response.StatusCode.ShouldBe(HttpStatusCode.Found);
|
||||
response.Headers.Location!.AbsoluteUri.ShouldMatch($"{expectedCallback}.*");
|
||||
|
|
@ -89,7 +90,7 @@ public class PushedAuthorizationTests
|
|||
var authorizeUrl = _mockPipeline.CreateAuthorizeUrl(
|
||||
clientId: "client2",
|
||||
requestUri: parJson.RootElement.GetProperty("request_uri").GetString());
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(authorizeUrl);
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(authorizeUrl, _ct);
|
||||
|
||||
response.StatusCode.ShouldBe(HttpStatusCode.Found);
|
||||
response.Headers.Location!.AbsoluteUri.ShouldMatch($"{expectedCallback}.*");
|
||||
|
|
@ -141,7 +142,7 @@ public class PushedAuthorizationTests
|
|||
redirectUri: "https://client1/callback",
|
||||
nonce: "123_nonce");
|
||||
_mockPipeline.BrowserClient.AllowAutoRedirect = false;
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(url);
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(url, _ct);
|
||||
|
||||
// We expect to be redirected to the error page, as this is an interactive
|
||||
// call to authorize
|
||||
|
|
@ -163,7 +164,7 @@ public class PushedAuthorizationTests
|
|||
redirectUri: "https://client1/callback",
|
||||
nonce: "123_nonce");
|
||||
_mockPipeline.BrowserClient.AllowAutoRedirect = false;
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(url);
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(url, _ct);
|
||||
|
||||
// We expect to be redirected to the error page, as this is an interactive
|
||||
// call to authorize
|
||||
|
|
@ -191,7 +192,7 @@ public class PushedAuthorizationTests
|
|||
// call to authorize. We don't want to follow redirects. Instead we'll just
|
||||
// check for a 302 to the error page
|
||||
_mockPipeline.BrowserClient.AllowAutoRedirect = false;
|
||||
var authorizeResponse = await _mockPipeline.BrowserClient.GetAsync(authorizeUrl);
|
||||
var authorizeResponse = await _mockPipeline.BrowserClient.GetAsync(authorizeUrl, _ct);
|
||||
|
||||
authorizeResponse.StatusCode.ShouldBe(HttpStatusCode.Found);
|
||||
authorizeResponse.Headers.Location!.ToString().ShouldMatch(".*/error.*");
|
||||
|
|
@ -213,8 +214,8 @@ public class PushedAuthorizationTests
|
|||
requestUri: parJson.RootElement.GetProperty("request_uri").GetString());
|
||||
|
||||
_mockPipeline.BrowserClient.AllowAutoRedirect = false;
|
||||
var firstAuthorizeResponse = await _mockPipeline.BrowserClient.GetAsync(authorizeUrl);
|
||||
var secondAuthorizeResponse = await _mockPipeline.BrowserClient.GetAsync(authorizeUrl);
|
||||
var firstAuthorizeResponse = await _mockPipeline.BrowserClient.GetAsync(authorizeUrl, _ct);
|
||||
var secondAuthorizeResponse = await _mockPipeline.BrowserClient.GetAsync(authorizeUrl, _ct);
|
||||
|
||||
secondAuthorizeResponse.StatusCode.ShouldBe(HttpStatusCode.Found);
|
||||
secondAuthorizeResponse.Headers.Location!.ToString().ShouldMatch(".*/error.*");
|
||||
|
|
@ -268,7 +269,7 @@ public class PushedAuthorizationTests
|
|||
var authorizeUrl = _mockPipeline.CreateAuthorizeUrl(
|
||||
clientId: "client1",
|
||||
requestUri: parJson.RootElement.GetProperty("request_uri").GetString());
|
||||
var authorizeResponse = await _mockPipeline.BrowserClient.GetAsync(authorizeUrl);
|
||||
var authorizeResponse = await _mockPipeline.BrowserClient.GetAsync(authorizeUrl, _ct);
|
||||
|
||||
// Verify that authorize redirects to login
|
||||
authorizeResponse.StatusCode.ShouldBe(HttpStatusCode.Found);
|
||||
|
|
@ -277,14 +278,14 @@ public class PushedAuthorizationTests
|
|||
authorizeResponse.Headers.Location.ToString().ToLower().ShouldMatch($"{expectedLocation.ToLower()}*");
|
||||
|
||||
// Verify that the UI prompts the user at this point
|
||||
var uiResponse = await _mockPipeline.BrowserClient.GetAsync(authorizeResponse.Headers.Location);
|
||||
var uiResponse = await _mockPipeline.BrowserClient.GetAsync(authorizeResponse.Headers.Location, _ct);
|
||||
uiResponse.StatusCode.ShouldBe(HttpStatusCode.OK);
|
||||
|
||||
// Now login and return to the return url we were given
|
||||
var returnPath = isPromptCreate ? _mockPipeline.CreateAccountReturnUrl : _mockPipeline.LoginReturnUrl;
|
||||
var returnUrl = new Uri(new Uri(IdentityServerPipeline.BaseUrl), returnPath);
|
||||
await _mockPipeline.LoginAsync("bob");
|
||||
var authorizeCallbackResponse = await _mockPipeline.BrowserClient.GetAsync(returnUrl);
|
||||
var authorizeCallbackResponse = await _mockPipeline.BrowserClient.GetAsync(returnUrl, _ct);
|
||||
|
||||
// The authorize callback should continue back to the application (the prompt parameter is processed so we don't go back to the UI)
|
||||
authorizeCallbackResponse.StatusCode.ShouldBe(HttpStatusCode.Found);
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ namespace Duende.IdentityServer.IntegrationTests.Endpoints.Authorize;
|
|||
|
||||
public class ResourceTests
|
||||
{
|
||||
private readonly CancellationToken _ct = TestContext.Current.CancellationToken;
|
||||
private const string Category = "Authorize endpoint";
|
||||
|
||||
private IdentityServerPipeline _mockPipeline = new IdentityServerPipeline();
|
||||
|
|
@ -151,7 +152,7 @@ public class ResourceTests
|
|||
url += "&resource=urn:resource1";
|
||||
url += "&resource=urn:resource3";
|
||||
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(url);
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(url, _ct);
|
||||
var code = GetCode(response);
|
||||
|
||||
var tokenResponse = await _mockPipeline.BackChannelClient.RequestAuthorizationCodeTokenAsync(new AuthorizationCodeTokenRequest
|
||||
|
|
@ -161,7 +162,7 @@ public class ResourceTests
|
|||
ClientSecret = "secret",
|
||||
Code = code,
|
||||
RedirectUri = "https://client1/callback"
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
{
|
||||
var claims = ParseAccessTokenClaims(tokenResponse);
|
||||
|
|
@ -186,7 +187,7 @@ public class ResourceTests
|
|||
|
||||
url += "&resource= ";
|
||||
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(url);
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(url, _ct);
|
||||
var code = GetCode(response);
|
||||
|
||||
var tokenResponse = await _mockPipeline.BackChannelClient.RequestAuthorizationCodeTokenAsync(new AuthorizationCodeTokenRequest
|
||||
|
|
@ -200,7 +201,7 @@ public class ResourceTests
|
|||
{
|
||||
{ "resource", " " }
|
||||
}
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
{
|
||||
var claims = ParseAccessTokenClaims(tokenResponse);
|
||||
|
|
@ -226,7 +227,7 @@ public class ResourceTests
|
|||
url += "&resource=urn:resource1";
|
||||
url += "&resource=urn:resource3";
|
||||
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(url);
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(url, _ct);
|
||||
var code = GetCode(response);
|
||||
|
||||
var tokenResponse = await _mockPipeline.BackChannelClient.RequestAuthorizationCodeTokenAsync(new AuthorizationCodeTokenRequest
|
||||
|
|
@ -240,7 +241,7 @@ public class ResourceTests
|
|||
{
|
||||
{ "resource", " " }
|
||||
}
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
{
|
||||
var claims = ParseAccessTokenClaims(tokenResponse);
|
||||
|
|
@ -266,7 +267,7 @@ public class ResourceTests
|
|||
url += "&resource=urn:resource1";
|
||||
url += "&resource=urn:resource3";
|
||||
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(url);
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(url, _ct);
|
||||
var code = GetCode(response);
|
||||
|
||||
var tokenResponse = await _mockPipeline.BackChannelClient.RequestAuthorizationCodeTokenAsync(new AuthorizationCodeTokenRequest
|
||||
|
|
@ -280,7 +281,7 @@ public class ResourceTests
|
|||
{
|
||||
{ "resource", "urn:resource1" }
|
||||
}
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
{
|
||||
var claims = ParseAccessTokenClaims(tokenResponse);
|
||||
|
|
@ -306,7 +307,7 @@ public class ResourceTests
|
|||
url += "&resource=urn:resource1";
|
||||
url += "&resource=urn:resource3";
|
||||
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(url);
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(url, _ct);
|
||||
var code = GetCode(response);
|
||||
|
||||
var tokenResponse = await _mockPipeline.BackChannelClient.RequestAuthorizationCodeTokenAsync(new AuthorizationCodeTokenRequest
|
||||
|
|
@ -316,7 +317,7 @@ public class ResourceTests
|
|||
ClientSecret = "secret",
|
||||
Code = code,
|
||||
RedirectUri = "https://client1/callback"
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
tokenResponse = await _mockPipeline.BackChannelClient.RequestRefreshTokenAsync(new RefreshTokenRequest
|
||||
{
|
||||
|
|
@ -328,7 +329,7 @@ public class ResourceTests
|
|||
{
|
||||
{ "resource", "urn:resource1" }
|
||||
}
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
{
|
||||
var claims = ParseAccessTokenClaims(tokenResponse);
|
||||
|
|
@ -354,7 +355,7 @@ public class ResourceTests
|
|||
url += "&resource=urn:resource1";
|
||||
url += "&resource=urn:resource3";
|
||||
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(url);
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(url, _ct);
|
||||
var code = GetCode(response);
|
||||
|
||||
var tokenResponse = await _mockPipeline.BackChannelClient.RequestAuthorizationCodeTokenAsync(new AuthorizationCodeTokenRequest
|
||||
|
|
@ -364,7 +365,7 @@ public class ResourceTests
|
|||
ClientSecret = "secret",
|
||||
Code = code,
|
||||
RedirectUri = "https://client1/callback"
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
tokenResponse = await _mockPipeline.BackChannelClient.RequestRefreshTokenAsync(new RefreshTokenRequest
|
||||
{
|
||||
|
|
@ -372,7 +373,7 @@ public class ResourceTests
|
|||
ClientId = "client1",
|
||||
ClientSecret = "secret",
|
||||
RefreshToken = tokenResponse.RefreshToken,
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
{
|
||||
var claims = ParseAccessTokenClaims(tokenResponse);
|
||||
|
|
@ -397,7 +398,7 @@ public class ResourceTests
|
|||
|
||||
url += "&resource=urn:resource1";
|
||||
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(url);
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(url, _ct);
|
||||
var code = GetCode(response);
|
||||
|
||||
var tokenResponse = await _mockPipeline.BackChannelClient.RequestAuthorizationCodeTokenAsync(new AuthorizationCodeTokenRequest
|
||||
|
|
@ -411,7 +412,7 @@ public class ResourceTests
|
|||
{
|
||||
{ "resource", "urn:resource1" }
|
||||
}
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
{
|
||||
var claims = ParseAccessTokenClaims(tokenResponse);
|
||||
|
|
@ -436,7 +437,7 @@ public class ResourceTests
|
|||
|
||||
url += "&resource=urn:resource1";
|
||||
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(url);
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(url, _ct);
|
||||
var code = GetCode(response);
|
||||
|
||||
var tokenResponse = await _mockPipeline.BackChannelClient.RequestAuthorizationCodeTokenAsync(new AuthorizationCodeTokenRequest
|
||||
|
|
@ -450,7 +451,7 @@ public class ResourceTests
|
|||
{
|
||||
// no resource param
|
||||
}
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
{
|
||||
var claims = ParseAccessTokenClaims(tokenResponse);
|
||||
|
|
@ -475,7 +476,7 @@ public class ResourceTests
|
|||
|
||||
url += "&resource=urn:resource3";
|
||||
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(url);
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(url, _ct);
|
||||
var code = GetCode(response);
|
||||
|
||||
var tokenResponse = await _mockPipeline.BackChannelClient.RequestAuthorizationCodeTokenAsync(new AuthorizationCodeTokenRequest
|
||||
|
|
@ -489,7 +490,7 @@ public class ResourceTests
|
|||
{
|
||||
// no resource param
|
||||
}
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
{
|
||||
var claims = ParseAccessTokenClaims(tokenResponse);
|
||||
|
|
@ -507,7 +508,7 @@ public class ResourceTests
|
|||
{
|
||||
{ "resource", "urn:resource3" }
|
||||
}
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
{
|
||||
var claims = ParseAccessTokenClaims(tokenResponse);
|
||||
|
|
@ -532,7 +533,7 @@ public class ResourceTests
|
|||
|
||||
url += "&resource=urn:resource3";
|
||||
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(url);
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(url, _ct);
|
||||
var code = GetCode(response);
|
||||
|
||||
var tokenResponse = await _mockPipeline.BackChannelClient.RequestAuthorizationCodeTokenAsync(new AuthorizationCodeTokenRequest
|
||||
|
|
@ -546,7 +547,7 @@ public class ResourceTests
|
|||
{
|
||||
{ "resource", "urn:resource3" }
|
||||
}
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
{
|
||||
var claims = ParseAccessTokenClaims(tokenResponse);
|
||||
|
|
@ -571,7 +572,7 @@ public class ResourceTests
|
|||
url += "&resource=urn:resource1";
|
||||
url += "&resource=urn:resource3";
|
||||
|
||||
await _mockPipeline.BrowserClient.GetAsync(url);
|
||||
await _mockPipeline.BrowserClient.GetAsync(url, _ct);
|
||||
_mockPipeline.ErrorWasCalled.ShouldBeTrue();
|
||||
_mockPipeline.ErrorMessage.Error.ShouldBe("invalid_target");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,10 +13,9 @@ namespace Duende.IdentityServer.IntegrationTests.Endpoints.Authorize;
|
|||
public class RestrictAccessTokenViaBrowserTests
|
||||
{
|
||||
private const string Category = "RestrictAccessTokenViaBrowserTests";
|
||||
|
||||
private IdentityServerPipeline _mockPipeline = new IdentityServerPipeline();
|
||||
|
||||
private ClaimsPrincipal _user = new IdentityServerUser("bob").CreatePrincipal();
|
||||
private readonly CancellationToken _ct = TestContext.Current.CancellationToken;
|
||||
private readonly IdentityServerPipeline _mockPipeline = new IdentityServerPipeline();
|
||||
private readonly ClaimsPrincipal _user = new IdentityServerUser("bob").CreatePrincipal();
|
||||
|
||||
public RestrictAccessTokenViaBrowserTests()
|
||||
{
|
||||
|
|
@ -92,7 +91,7 @@ public class RestrictAccessTokenViaBrowserTests
|
|||
"id_token", "openid", "https://client1/callback", "state", "nonce");
|
||||
|
||||
_mockPipeline.BrowserClient.AllowAutoRedirect = false;
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(url);
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(url, _ct);
|
||||
|
||||
response.StatusCode.ShouldBe(HttpStatusCode.Found);
|
||||
response.Headers.Location.AbsoluteUri.ShouldStartWith("https://client1/callback");
|
||||
|
|
@ -111,7 +110,7 @@ public class RestrictAccessTokenViaBrowserTests
|
|||
"id_token token", "openid", "https://client1/callback", "state", "nonce");
|
||||
|
||||
_mockPipeline.BrowserClient.AllowAutoRedirect = false;
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(url);
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(url, _ct);
|
||||
|
||||
response.StatusCode.ShouldBe(HttpStatusCode.Found);
|
||||
response.Headers.Location.AbsoluteUri.ShouldStartWith("https://client1/callback");
|
||||
|
|
@ -130,7 +129,7 @@ public class RestrictAccessTokenViaBrowserTests
|
|||
"id_token", "openid", "https://client2/callback", "state", "nonce");
|
||||
|
||||
_mockPipeline.BrowserClient.AllowAutoRedirect = false;
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(url);
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(url, _ct);
|
||||
|
||||
response.StatusCode.ShouldBe(HttpStatusCode.Found);
|
||||
response.Headers.Location.AbsoluteUri.ShouldStartWith("https://client2/callback");
|
||||
|
|
@ -149,7 +148,7 @@ public class RestrictAccessTokenViaBrowserTests
|
|||
"id_token token", "openid", "https://client2/callback", "state", "nonce");
|
||||
|
||||
_mockPipeline.BrowserClient.AllowAutoRedirect = true;
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(url);
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(url, _ct);
|
||||
_mockPipeline.ErrorWasCalled.ShouldBeTrue();
|
||||
}
|
||||
|
||||
|
|
@ -163,7 +162,7 @@ public class RestrictAccessTokenViaBrowserTests
|
|||
"code id_token", "openid", "https://client3/callback", "state", "nonce");
|
||||
|
||||
_mockPipeline.BrowserClient.AllowAutoRedirect = false;
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(url);
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(url, _ct);
|
||||
|
||||
response.StatusCode.ShouldBe(HttpStatusCode.Found);
|
||||
response.Headers.Location.AbsoluteUri.ShouldStartWith("https://client3/callback");
|
||||
|
|
@ -183,7 +182,7 @@ public class RestrictAccessTokenViaBrowserTests
|
|||
"code id_token token", "openid", "https://client3/callback", "state", "nonce");
|
||||
|
||||
_mockPipeline.BrowserClient.AllowAutoRedirect = false;
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(url);
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(url, _ct);
|
||||
|
||||
response.StatusCode.ShouldBe(HttpStatusCode.Found);
|
||||
response.Headers.Location.AbsoluteUri.ShouldStartWith("https://client3/callback");
|
||||
|
|
@ -204,7 +203,7 @@ public class RestrictAccessTokenViaBrowserTests
|
|||
"code id_token", "openid", "https://client4/callback", "state", "nonce");
|
||||
|
||||
_mockPipeline.BrowserClient.AllowAutoRedirect = false;
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(url);
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(url, _ct);
|
||||
|
||||
response.StatusCode.ShouldBe(HttpStatusCode.Found);
|
||||
response.Headers.Location.AbsoluteUri.ShouldStartWith("https://client4/callback");
|
||||
|
|
@ -224,7 +223,7 @@ public class RestrictAccessTokenViaBrowserTests
|
|||
"code id_token token", "openid", "https://client4/callback", "state", "nonce");
|
||||
|
||||
_mockPipeline.BrowserClient.AllowAutoRedirect = true;
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(url);
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(url, _ct);
|
||||
_mockPipeline.ErrorWasCalled.ShouldBeTrue();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,8 +12,8 @@ namespace Duende.IdentityServer.IntegrationTests.Endpoints.Authorize;
|
|||
public class SessionIdTests
|
||||
{
|
||||
private const string Category = "SessionIdTests";
|
||||
|
||||
private IdentityServerPipeline _mockPipeline = new IdentityServerPipeline();
|
||||
private readonly CancellationToken _ct = TestContext.Current.CancellationToken;
|
||||
private readonly IdentityServerPipeline _mockPipeline = new IdentityServerPipeline();
|
||||
|
||||
public SessionIdTests()
|
||||
{
|
||||
|
|
@ -84,7 +84,7 @@ public class SessionIdTests
|
|||
|
||||
_mockPipeline.RemoveSessionCookie();
|
||||
|
||||
await _mockPipeline.BrowserClient.GetAsync(IdentityServerPipeline.DiscoveryEndpoint);
|
||||
await _mockPipeline.BrowserClient.GetAsync(IdentityServerPipeline.DiscoveryEndpoint, _ct);
|
||||
|
||||
var sid2 = _mockPipeline.GetSessionCookie().Value;
|
||||
sid2.ShouldBe(sid1);
|
||||
|
|
|
|||
|
|
@ -9,17 +9,17 @@ namespace Duende.IdentityServer.IntegrationTests.Endpoints.CheckSession;
|
|||
|
||||
public class CheckSessionTests
|
||||
{
|
||||
private readonly CancellationToken _ct = TestContext.Current.CancellationToken;
|
||||
private readonly IdentityServerPipeline _mockPipeline = new IdentityServerPipeline();
|
||||
private const string Category = "Check session endpoint";
|
||||
|
||||
private IdentityServerPipeline _mockPipeline = new IdentityServerPipeline();
|
||||
|
||||
public CheckSessionTests() => _mockPipeline.Initialize();
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", Category)]
|
||||
public async Task get_request_should_not_return_404()
|
||||
{
|
||||
var response = await _mockPipeline.BackChannelClient.GetAsync(IdentityServerPipeline.CheckSessionEndpoint);
|
||||
var response = await _mockPipeline.BackChannelClient.GetAsync(IdentityServerPipeline.CheckSessionEndpoint, _ct);
|
||||
|
||||
response.StatusCode.ShouldNotBe(HttpStatusCode.NotFound);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ namespace Duende.IdentityServer.IntegrationTests.Endpoints.Ciba;
|
|||
|
||||
public class CibaTests
|
||||
{
|
||||
private readonly CancellationToken _ct = TestContext.Current.CancellationToken;
|
||||
private const string Category = "Backchannel Authentication (CIBA) endpoint";
|
||||
|
||||
private IdentityServerPipeline _mockPipeline = new();
|
||||
|
|
@ -158,7 +159,7 @@ public class CibaTests
|
|||
[Trait("Category", Category)]
|
||||
public async Task get_request_should_return_error()
|
||||
{
|
||||
var response = await _mockPipeline.BackChannelClient.GetAsync(IdentityServerPipeline.BackchannelAuthenticationEndpoint);
|
||||
var response = await _mockPipeline.BackChannelClient.GetAsync(IdentityServerPipeline.BackchannelAuthenticationEndpoint, _ct);
|
||||
|
||||
response.StatusCode.ShouldBe(HttpStatusCode.BadRequest);
|
||||
}
|
||||
|
|
@ -169,7 +170,8 @@ public class CibaTests
|
|||
{
|
||||
var response = await _mockPipeline.BackChannelClient.PostAsync(
|
||||
IdentityServerPipeline.BackchannelAuthenticationEndpoint,
|
||||
new StringContent("invalid"));
|
||||
new StringContent("invalid"),
|
||||
_ct);
|
||||
|
||||
response.StatusCode.ShouldBe(HttpStatusCode.BadRequest);
|
||||
}
|
||||
|
|
@ -193,7 +195,8 @@ public class CibaTests
|
|||
|
||||
var response = await _mockPipeline.BackChannelClient.PostAsync(
|
||||
IdentityServerPipeline.BackchannelAuthenticationEndpoint,
|
||||
new FormUrlEncodedContent(body));
|
||||
new FormUrlEncodedContent(body),
|
||||
_ct);
|
||||
|
||||
response.StatusCode.ShouldBe(HttpStatusCode.OK);
|
||||
|
||||
|
|
@ -233,7 +236,8 @@ public class CibaTests
|
|||
|
||||
var response = await _mockPipeline.BackChannelClient.PostAsync(
|
||||
IdentityServerPipeline.BackchannelAuthenticationEndpoint,
|
||||
new FormUrlEncodedContent(body));
|
||||
new FormUrlEncodedContent(body),
|
||||
_ct);
|
||||
|
||||
// The custom validator was invoked with the request parameters and mapped the custom input
|
||||
var validatedRequest = _mockCustomBackchannelAuthenticationValidator.Context.ValidationResult.ValidatedRequest;
|
||||
|
|
@ -272,11 +276,12 @@ public class CibaTests
|
|||
|
||||
var response = await _mockPipeline.BackChannelClient.PostAsync(
|
||||
IdentityServerPipeline.BackchannelAuthenticationEndpoint,
|
||||
new FormUrlEncodedContent(body));
|
||||
new FormUrlEncodedContent(body),
|
||||
_ct);
|
||||
|
||||
// Custom request properties are not included automatically in the response to the client
|
||||
response.StatusCode.ShouldBe(HttpStatusCode.OK);
|
||||
var responseContent = await response.Content.ReadAsStringAsync();
|
||||
var responseContent = await response.Content.ReadAsStringAsync(_ct);
|
||||
var json = JsonSerializer.Deserialize<Dictionary<string, JsonElement>>(responseContent);
|
||||
json.ShouldNotBeNull();
|
||||
json.ShouldNotContainKey("complex");
|
||||
|
|
@ -306,11 +311,12 @@ public class CibaTests
|
|||
|
||||
var response = await _mockPipeline.BackChannelClient.PostAsync(
|
||||
IdentityServerPipeline.BackchannelAuthenticationEndpoint,
|
||||
new FormUrlEncodedContent(body));
|
||||
new FormUrlEncodedContent(body),
|
||||
_ct);
|
||||
|
||||
response.StatusCode.ShouldBe(HttpStatusCode.OK);
|
||||
|
||||
var json = await response.Content.ReadAsStringAsync();
|
||||
var json = await response.Content.ReadAsStringAsync(_ct);
|
||||
var values = JsonSerializer.Deserialize<Dictionary<string, object>>(json);
|
||||
|
||||
values.ContainsKey("auth_req_id").ShouldBeTrue();
|
||||
|
|
@ -341,11 +347,12 @@ public class CibaTests
|
|||
|
||||
var response = await _mockPipeline.BackChannelClient.PostAsync(
|
||||
IdentityServerPipeline.BackchannelAuthenticationEndpoint,
|
||||
new FormUrlEncodedContent(body));
|
||||
new FormUrlEncodedContent(body),
|
||||
_ct);
|
||||
|
||||
response.StatusCode.ShouldBe(HttpStatusCode.OK);
|
||||
|
||||
var json = await response.Content.ReadAsStringAsync();
|
||||
var json = await response.Content.ReadAsStringAsync(_ct);
|
||||
var values = JsonSerializer.Deserialize<Dictionary<string, object>>(json);
|
||||
|
||||
values.ContainsKey("auth_req_id").ShouldBeTrue();
|
||||
|
|
@ -373,11 +380,12 @@ public class CibaTests
|
|||
|
||||
var response = await _mockPipeline.BackChannelClient.PostAsync(
|
||||
IdentityServerPipeline.BackchannelAuthenticationEndpoint,
|
||||
new FormUrlEncodedContent(body));
|
||||
new FormUrlEncodedContent(body),
|
||||
_ct);
|
||||
|
||||
response.StatusCode.ShouldBe(HttpStatusCode.BadRequest);
|
||||
|
||||
var json = await response.Content.ReadAsStringAsync();
|
||||
var json = await response.Content.ReadAsStringAsync(_ct);
|
||||
var values = JsonSerializer.Deserialize<Dictionary<string, object>>(json);
|
||||
|
||||
values.ContainsKey("error").ShouldBeTrue();
|
||||
|
|
@ -407,11 +415,12 @@ public class CibaTests
|
|||
|
||||
var response = await _mockPipeline.BackChannelClient.PostAsync(
|
||||
IdentityServerPipeline.BackchannelAuthenticationEndpoint,
|
||||
new FormUrlEncodedContent(body));
|
||||
new FormUrlEncodedContent(body),
|
||||
_ct);
|
||||
|
||||
response.StatusCode.ShouldBe(HttpStatusCode.BadRequest);
|
||||
|
||||
var json = await response.Content.ReadAsStringAsync();
|
||||
var json = await response.Content.ReadAsStringAsync(_ct);
|
||||
var values = JsonSerializer.Deserialize<Dictionary<string, object>>(json);
|
||||
|
||||
values.ContainsKey("error").ShouldBeTrue();
|
||||
|
|
@ -441,11 +450,12 @@ public class CibaTests
|
|||
|
||||
var response = await _mockPipeline.BackChannelClient.PostAsync(
|
||||
IdentityServerPipeline.BackchannelAuthenticationEndpoint,
|
||||
new FormUrlEncodedContent(body));
|
||||
new FormUrlEncodedContent(body),
|
||||
_ct);
|
||||
|
||||
response.StatusCode.ShouldBe(HttpStatusCode.BadRequest);
|
||||
|
||||
var json = await response.Content.ReadAsStringAsync();
|
||||
var json = await response.Content.ReadAsStringAsync(_ct);
|
||||
var values = JsonSerializer.Deserialize<Dictionary<string, object>>(json);
|
||||
|
||||
values.ContainsKey("error").ShouldBeTrue();
|
||||
|
|
@ -474,11 +484,12 @@ public class CibaTests
|
|||
|
||||
var response = await _mockPipeline.BackChannelClient.PostAsync(
|
||||
IdentityServerPipeline.BackchannelAuthenticationEndpoint,
|
||||
new FormUrlEncodedContent(body));
|
||||
new FormUrlEncodedContent(body),
|
||||
_ct);
|
||||
|
||||
response.StatusCode.ShouldBe(HttpStatusCode.BadRequest);
|
||||
|
||||
var json = await response.Content.ReadAsStringAsync();
|
||||
var json = await response.Content.ReadAsStringAsync(_ct);
|
||||
var values = JsonSerializer.Deserialize<Dictionary<string, object>>(json);
|
||||
|
||||
values.ContainsKey("error").ShouldBeTrue();
|
||||
|
|
@ -509,11 +520,12 @@ public class CibaTests
|
|||
|
||||
var response = await _mockPipeline.BackChannelClient.PostAsync(
|
||||
IdentityServerPipeline.BackchannelAuthenticationEndpoint,
|
||||
new FormUrlEncodedContent(body));
|
||||
new FormUrlEncodedContent(body),
|
||||
_ct);
|
||||
|
||||
response.StatusCode.ShouldBe(HttpStatusCode.BadRequest);
|
||||
|
||||
var json = await response.Content.ReadAsStringAsync();
|
||||
var json = await response.Content.ReadAsStringAsync(_ct);
|
||||
var values = JsonSerializer.Deserialize<Dictionary<string, object>>(json);
|
||||
|
||||
values.ContainsKey("error").ShouldBeTrue();
|
||||
|
|
@ -544,11 +556,12 @@ public class CibaTests
|
|||
|
||||
var response = await _mockPipeline.BackChannelClient.PostAsync(
|
||||
IdentityServerPipeline.BackchannelAuthenticationEndpoint,
|
||||
new FormUrlEncodedContent(body));
|
||||
new FormUrlEncodedContent(body),
|
||||
_ct);
|
||||
|
||||
response.StatusCode.ShouldBe(HttpStatusCode.BadRequest);
|
||||
|
||||
var json = await response.Content.ReadAsStringAsync();
|
||||
var json = await response.Content.ReadAsStringAsync(_ct);
|
||||
var values = JsonSerializer.Deserialize<Dictionary<string, object>>(json);
|
||||
|
||||
values.ContainsKey("error").ShouldBeTrue();
|
||||
|
|
@ -581,11 +594,12 @@ public class CibaTests
|
|||
|
||||
var response = await _mockPipeline.BackChannelClient.PostAsync(
|
||||
IdentityServerPipeline.BackchannelAuthenticationEndpoint,
|
||||
new FormUrlEncodedContent(body));
|
||||
new FormUrlEncodedContent(body),
|
||||
_ct);
|
||||
|
||||
response.StatusCode.ShouldBe(HttpStatusCode.BadRequest);
|
||||
|
||||
var json = await response.Content.ReadAsStringAsync();
|
||||
var json = await response.Content.ReadAsStringAsync(_ct);
|
||||
var values = JsonSerializer.Deserialize<Dictionary<string, object>>(json);
|
||||
|
||||
values.ContainsKey("error").ShouldBeTrue();
|
||||
|
|
@ -619,11 +633,11 @@ public class CibaTests
|
|||
|
||||
var response = await _mockPipeline.BackChannelClient.PostAsync(
|
||||
IdentityServerPipeline.BackchannelAuthenticationEndpoint,
|
||||
new FormUrlEncodedContent(body));
|
||||
new FormUrlEncodedContent(body), _ct);
|
||||
|
||||
response.StatusCode.ShouldBe(HttpStatusCode.BadRequest);
|
||||
|
||||
var json = await response.Content.ReadAsStringAsync();
|
||||
var json = await response.Content.ReadAsStringAsync(_ct);
|
||||
var values = JsonSerializer.Deserialize<Dictionary<string, object>>(json);
|
||||
|
||||
values.ContainsKey("error").ShouldBeTrue();
|
||||
|
|
@ -654,11 +668,12 @@ public class CibaTests
|
|||
|
||||
var response = await _mockPipeline.BackChannelClient.PostAsync(
|
||||
IdentityServerPipeline.BackchannelAuthenticationEndpoint,
|
||||
new FormUrlEncodedContent(body));
|
||||
new FormUrlEncodedContent(body),
|
||||
_ct);
|
||||
|
||||
response.StatusCode.ShouldBe(HttpStatusCode.BadRequest);
|
||||
|
||||
var json = await response.Content.ReadAsStringAsync();
|
||||
var json = await response.Content.ReadAsStringAsync(_ct);
|
||||
var values = JsonSerializer.Deserialize<Dictionary<string, object>>(json);
|
||||
|
||||
values.ContainsKey("error").ShouldBeTrue();
|
||||
|
|
@ -689,11 +704,12 @@ public class CibaTests
|
|||
|
||||
var response = await _mockPipeline.BackChannelClient.PostAsync(
|
||||
IdentityServerPipeline.BackchannelAuthenticationEndpoint,
|
||||
new FormUrlEncodedContent(body));
|
||||
new FormUrlEncodedContent(body),
|
||||
_ct);
|
||||
|
||||
response.StatusCode.ShouldBe(HttpStatusCode.BadRequest);
|
||||
|
||||
var json = await response.Content.ReadAsStringAsync();
|
||||
var json = await response.Content.ReadAsStringAsync(_ct);
|
||||
var values = JsonSerializer.Deserialize<Dictionary<string, object>>(json);
|
||||
|
||||
values.ContainsKey("error").ShouldBeTrue();
|
||||
|
|
@ -724,7 +740,8 @@ public class CibaTests
|
|||
|
||||
var response = await _mockPipeline.BackChannelClient.PostAsync(
|
||||
IdentityServerPipeline.BackchannelAuthenticationEndpoint,
|
||||
new FormUrlEncodedContent(body));
|
||||
new FormUrlEncodedContent(body),
|
||||
_ct);
|
||||
|
||||
response.StatusCode.ShouldBe(HttpStatusCode.OK);
|
||||
}
|
||||
|
|
@ -749,7 +766,8 @@ public class CibaTests
|
|||
|
||||
var response = await _mockPipeline.BackChannelClient.PostAsync(
|
||||
IdentityServerPipeline.BackchannelAuthenticationEndpoint,
|
||||
new FormUrlEncodedContent(body));
|
||||
new FormUrlEncodedContent(body),
|
||||
_ct);
|
||||
|
||||
response.StatusCode.ShouldBe(HttpStatusCode.OK);
|
||||
|
||||
|
|
@ -780,11 +798,12 @@ public class CibaTests
|
|||
|
||||
var response = await _mockPipeline.BackChannelClient.PostAsync(
|
||||
IdentityServerPipeline.BackchannelAuthenticationEndpoint,
|
||||
new FormUrlEncodedContent(body));
|
||||
new FormUrlEncodedContent(body),
|
||||
_ct);
|
||||
|
||||
response.StatusCode.ShouldBe(HttpStatusCode.Unauthorized);
|
||||
|
||||
var json = await response.Content.ReadAsStringAsync();
|
||||
var json = await response.Content.ReadAsStringAsync(_ct);
|
||||
var values = JsonSerializer.Deserialize<Dictionary<string, object>>(json);
|
||||
|
||||
values.ContainsKey("error").ShouldBeTrue();
|
||||
|
|
@ -811,11 +830,12 @@ public class CibaTests
|
|||
|
||||
var response = await _mockPipeline.BackChannelClient.PostAsync(
|
||||
IdentityServerPipeline.BackchannelAuthenticationEndpoint,
|
||||
new FormUrlEncodedContent(body));
|
||||
new FormUrlEncodedContent(body),
|
||||
_ct);
|
||||
|
||||
response.StatusCode.ShouldBe(HttpStatusCode.BadRequest);
|
||||
|
||||
var json = await response.Content.ReadAsStringAsync();
|
||||
var json = await response.Content.ReadAsStringAsync(_ct);
|
||||
var values = JsonSerializer.Deserialize<Dictionary<string, object>>(json);
|
||||
|
||||
values.ContainsKey("error").ShouldBeTrue();
|
||||
|
|
@ -846,11 +866,12 @@ public class CibaTests
|
|||
|
||||
var response = await _mockPipeline.BackChannelClient.PostAsync(
|
||||
IdentityServerPipeline.BackchannelAuthenticationEndpoint,
|
||||
new FormUrlEncodedContent(body));
|
||||
new FormUrlEncodedContent(body),
|
||||
_ct);
|
||||
|
||||
response.StatusCode.ShouldBe(code);
|
||||
|
||||
var json = await response.Content.ReadAsStringAsync();
|
||||
var json = await response.Content.ReadAsStringAsync(_ct);
|
||||
var values = JsonSerializer.Deserialize<Dictionary<string, object>>(json);
|
||||
|
||||
values.ContainsKey("error").ShouldBeTrue();
|
||||
|
|
@ -875,11 +896,12 @@ public class CibaTests
|
|||
|
||||
var response = await _mockPipeline.BackChannelClient.PostAsync(
|
||||
IdentityServerPipeline.BackchannelAuthenticationEndpoint,
|
||||
new FormUrlEncodedContent(body));
|
||||
new FormUrlEncodedContent(body),
|
||||
_ct);
|
||||
|
||||
response.StatusCode.ShouldBe(HttpStatusCode.BadRequest);
|
||||
|
||||
var json = await response.Content.ReadAsStringAsync();
|
||||
var json = await response.Content.ReadAsStringAsync(_ct);
|
||||
var values = JsonSerializer.Deserialize<Dictionary<string, object>>(json);
|
||||
|
||||
values.ContainsKey("error").ShouldBeTrue();
|
||||
|
|
@ -906,11 +928,12 @@ public class CibaTests
|
|||
|
||||
var response = await _mockPipeline.BackChannelClient.PostAsync(
|
||||
IdentityServerPipeline.BackchannelAuthenticationEndpoint,
|
||||
new FormUrlEncodedContent(body));
|
||||
new FormUrlEncodedContent(body),
|
||||
_ct);
|
||||
|
||||
response.StatusCode.ShouldBe(HttpStatusCode.BadRequest);
|
||||
|
||||
var json = await response.Content.ReadAsStringAsync();
|
||||
var json = await response.Content.ReadAsStringAsync(_ct);
|
||||
var values = JsonSerializer.Deserialize<Dictionary<string, object>>(json);
|
||||
|
||||
values.ContainsKey("error").ShouldBeTrue();
|
||||
|
|
@ -934,11 +957,12 @@ public class CibaTests
|
|||
|
||||
var response = await _mockPipeline.BackChannelClient.PostAsync(
|
||||
IdentityServerPipeline.BackchannelAuthenticationEndpoint,
|
||||
new FormUrlEncodedContent(body));
|
||||
new FormUrlEncodedContent(body),
|
||||
_ct);
|
||||
|
||||
response.StatusCode.ShouldBe(HttpStatusCode.BadRequest);
|
||||
|
||||
var json = await response.Content.ReadAsStringAsync();
|
||||
var json = await response.Content.ReadAsStringAsync(_ct);
|
||||
var values = JsonSerializer.Deserialize<Dictionary<string, object>>(json);
|
||||
|
||||
values.ContainsKey("error").ShouldBeTrue();
|
||||
|
|
@ -964,11 +988,12 @@ public class CibaTests
|
|||
|
||||
var response = await _mockPipeline.BackChannelClient.PostAsync(
|
||||
IdentityServerPipeline.BackchannelAuthenticationEndpoint,
|
||||
new FormUrlEncodedContent(body));
|
||||
new FormUrlEncodedContent(body),
|
||||
_ct);
|
||||
|
||||
response.StatusCode.ShouldBe(HttpStatusCode.BadRequest);
|
||||
|
||||
var json = await response.Content.ReadAsStringAsync();
|
||||
var json = await response.Content.ReadAsStringAsync(_ct);
|
||||
var values = JsonSerializer.Deserialize<Dictionary<string, object>>(json);
|
||||
|
||||
values.ContainsKey("error").ShouldBeTrue();
|
||||
|
|
@ -993,11 +1018,12 @@ public class CibaTests
|
|||
|
||||
var response = await _mockPipeline.BackChannelClient.PostAsync(
|
||||
IdentityServerPipeline.BackchannelAuthenticationEndpoint,
|
||||
new FormUrlEncodedContent(body));
|
||||
new FormUrlEncodedContent(body),
|
||||
_ct);
|
||||
|
||||
response.StatusCode.ShouldBe(HttpStatusCode.BadRequest);
|
||||
|
||||
var json = await response.Content.ReadAsStringAsync();
|
||||
var json = await response.Content.ReadAsStringAsync(_ct);
|
||||
var values = JsonSerializer.Deserialize<Dictionary<string, object>>(json);
|
||||
|
||||
values.ContainsKey("error").ShouldBeTrue();
|
||||
|
|
@ -1023,11 +1049,12 @@ public class CibaTests
|
|||
|
||||
var response = await _mockPipeline.BackChannelClient.PostAsync(
|
||||
IdentityServerPipeline.BackchannelAuthenticationEndpoint,
|
||||
new FormUrlEncodedContent(body));
|
||||
new FormUrlEncodedContent(body),
|
||||
_ct);
|
||||
|
||||
response.StatusCode.ShouldBe(HttpStatusCode.BadRequest);
|
||||
|
||||
var json = await response.Content.ReadAsStringAsync();
|
||||
var json = await response.Content.ReadAsStringAsync(_ct);
|
||||
var values = JsonSerializer.Deserialize<Dictionary<string, object>>(json);
|
||||
|
||||
values.ContainsKey("error").ShouldBeTrue();
|
||||
|
|
@ -1053,11 +1080,12 @@ public class CibaTests
|
|||
|
||||
var response = await _mockPipeline.BackChannelClient.PostAsync(
|
||||
IdentityServerPipeline.BackchannelAuthenticationEndpoint,
|
||||
new FormUrlEncodedContent(body));
|
||||
new FormUrlEncodedContent(body),
|
||||
_ct);
|
||||
|
||||
response.StatusCode.ShouldBe(HttpStatusCode.BadRequest);
|
||||
|
||||
var json = await response.Content.ReadAsStringAsync();
|
||||
var json = await response.Content.ReadAsStringAsync(_ct);
|
||||
var values = JsonSerializer.Deserialize<Dictionary<string, object>>(json);
|
||||
|
||||
values.ContainsKey("error").ShouldBeTrue();
|
||||
|
|
@ -1083,11 +1111,12 @@ public class CibaTests
|
|||
|
||||
var response = await _mockPipeline.BackChannelClient.PostAsync(
|
||||
IdentityServerPipeline.BackchannelAuthenticationEndpoint,
|
||||
new FormUrlEncodedContent(body));
|
||||
new FormUrlEncodedContent(body),
|
||||
_ct);
|
||||
|
||||
response.StatusCode.ShouldBe(HttpStatusCode.BadRequest);
|
||||
|
||||
var json = await response.Content.ReadAsStringAsync();
|
||||
var json = await response.Content.ReadAsStringAsync(_ct);
|
||||
var values = JsonSerializer.Deserialize<Dictionary<string, object>>(json);
|
||||
|
||||
values.ContainsKey("error").ShouldBeTrue();
|
||||
|
|
@ -1118,11 +1147,12 @@ public class CibaTests
|
|||
|
||||
var response = await _mockPipeline.BackChannelClient.PostAsync(
|
||||
IdentityServerPipeline.BackchannelAuthenticationEndpoint,
|
||||
new FormUrlEncodedContent(body));
|
||||
new FormUrlEncodedContent(body),
|
||||
_ct);
|
||||
|
||||
response.StatusCode.ShouldBe(HttpStatusCode.BadRequest);
|
||||
|
||||
var json = await response.Content.ReadAsStringAsync();
|
||||
var json = await response.Content.ReadAsStringAsync(_ct);
|
||||
var values = JsonSerializer.Deserialize<Dictionary<string, object>>(json);
|
||||
|
||||
values.ContainsKey("error").ShouldBeTrue();
|
||||
|
|
@ -1148,11 +1178,12 @@ public class CibaTests
|
|||
|
||||
var response = await _mockPipeline.BackChannelClient.PostAsync(
|
||||
IdentityServerPipeline.BackchannelAuthenticationEndpoint,
|
||||
new FormUrlEncodedContent(body));
|
||||
new FormUrlEncodedContent(body),
|
||||
_ct);
|
||||
|
||||
response.StatusCode.ShouldBe(HttpStatusCode.BadRequest);
|
||||
|
||||
var json = await response.Content.ReadAsStringAsync();
|
||||
var json = await response.Content.ReadAsStringAsync(_ct);
|
||||
var values = JsonSerializer.Deserialize<Dictionary<string, object>>(json);
|
||||
|
||||
values.ContainsKey("error").ShouldBeTrue();
|
||||
|
|
@ -1180,11 +1211,12 @@ public class CibaTests
|
|||
|
||||
var response = await _mockPipeline.BackChannelClient.PostAsync(
|
||||
IdentityServerPipeline.BackchannelAuthenticationEndpoint,
|
||||
new FormUrlEncodedContent(body));
|
||||
new FormUrlEncodedContent(body),
|
||||
_ct);
|
||||
|
||||
response.StatusCode.ShouldBe(HttpStatusCode.BadRequest);
|
||||
|
||||
var json = await response.Content.ReadAsStringAsync();
|
||||
var json = await response.Content.ReadAsStringAsync(_ct);
|
||||
var values = JsonSerializer.Deserialize<Dictionary<string, object>>(json);
|
||||
|
||||
values.ContainsKey("error").ShouldBeTrue();
|
||||
|
|
@ -1212,7 +1244,8 @@ public class CibaTests
|
|||
|
||||
var response = await _mockPipeline.BackChannelClient.PostAsync(
|
||||
IdentityServerPipeline.BackchannelAuthenticationEndpoint,
|
||||
new FormUrlEncodedContent(body));
|
||||
new FormUrlEncodedContent(body),
|
||||
_ct);
|
||||
|
||||
response.StatusCode.ShouldBe(HttpStatusCode.OK);
|
||||
}
|
||||
|
|
@ -1236,11 +1269,12 @@ public class CibaTests
|
|||
|
||||
var response = await _mockPipeline.BackChannelClient.PostAsync(
|
||||
IdentityServerPipeline.BackchannelAuthenticationEndpoint,
|
||||
new FormUrlEncodedContent(body));
|
||||
new FormUrlEncodedContent(body),
|
||||
_ct);
|
||||
|
||||
response.StatusCode.ShouldBe(HttpStatusCode.BadRequest);
|
||||
|
||||
var json = await response.Content.ReadAsStringAsync();
|
||||
var json = await response.Content.ReadAsStringAsync(_ct);
|
||||
var values = JsonSerializer.Deserialize<Dictionary<string, object>>(json);
|
||||
|
||||
values.ContainsKey("error").ShouldBeTrue();
|
||||
|
|
@ -1268,7 +1302,8 @@ public class CibaTests
|
|||
|
||||
var response = await _mockPipeline.BackChannelClient.PostAsync(
|
||||
IdentityServerPipeline.BackchannelAuthenticationEndpoint,
|
||||
new FormUrlEncodedContent(body));
|
||||
new FormUrlEncodedContent(body),
|
||||
_ct);
|
||||
|
||||
response.StatusCode.ShouldBe(HttpStatusCode.OK);
|
||||
|
||||
|
|
@ -1295,11 +1330,12 @@ public class CibaTests
|
|||
|
||||
var response = await _mockPipeline.BackChannelClient.PostAsync(
|
||||
IdentityServerPipeline.BackchannelAuthenticationEndpoint,
|
||||
new FormUrlEncodedContent(body));
|
||||
new FormUrlEncodedContent(body),
|
||||
_ct);
|
||||
|
||||
response.StatusCode.ShouldBe(HttpStatusCode.BadRequest);
|
||||
|
||||
var json = await response.Content.ReadAsStringAsync();
|
||||
var json = await response.Content.ReadAsStringAsync(_ct);
|
||||
var values = JsonSerializer.Deserialize<Dictionary<string, object>>(json);
|
||||
|
||||
values.ContainsKey("error").ShouldBeTrue();
|
||||
|
|
@ -1321,11 +1357,12 @@ public class CibaTests
|
|||
|
||||
var response = await _mockPipeline.BackChannelClient.PostAsync(
|
||||
IdentityServerPipeline.BackchannelAuthenticationEndpoint,
|
||||
new FormUrlEncodedContent(body));
|
||||
new FormUrlEncodedContent(body),
|
||||
_ct);
|
||||
|
||||
response.StatusCode.ShouldBe(HttpStatusCode.BadRequest);
|
||||
|
||||
var json = await response.Content.ReadAsStringAsync();
|
||||
var json = await response.Content.ReadAsStringAsync(_ct);
|
||||
var values = JsonSerializer.Deserialize<Dictionary<string, object>>(json);
|
||||
|
||||
values.ContainsKey("error").ShouldBeTrue();
|
||||
|
|
@ -1347,11 +1384,11 @@ public class CibaTests
|
|||
|
||||
var response = await _mockPipeline.BackChannelClient.PostAsync(
|
||||
IdentityServerPipeline.BackchannelAuthenticationEndpoint,
|
||||
new FormUrlEncodedContent(body));
|
||||
new FormUrlEncodedContent(body), _ct);
|
||||
|
||||
response.StatusCode.ShouldBe(HttpStatusCode.BadRequest);
|
||||
|
||||
var json = await response.Content.ReadAsStringAsync();
|
||||
var json = await response.Content.ReadAsStringAsync(_ct);
|
||||
var values = JsonSerializer.Deserialize<Dictionary<string, object>>(json);
|
||||
|
||||
values.ContainsKey("error").ShouldBeTrue();
|
||||
|
|
@ -1376,11 +1413,12 @@ public class CibaTests
|
|||
|
||||
var response = await _mockPipeline.BackChannelClient.PostAsync(
|
||||
IdentityServerPipeline.BackchannelAuthenticationEndpoint,
|
||||
new FormUrlEncodedContent(body));
|
||||
new FormUrlEncodedContent(body),
|
||||
_ct);
|
||||
|
||||
response.StatusCode.ShouldBe(HttpStatusCode.BadRequest);
|
||||
|
||||
var json = await response.Content.ReadAsStringAsync();
|
||||
var json = await response.Content.ReadAsStringAsync(_ct);
|
||||
var values = JsonSerializer.Deserialize<Dictionary<string, object>>(json);
|
||||
|
||||
values.ContainsKey("error").ShouldBeTrue();
|
||||
|
|
@ -1405,11 +1443,12 @@ public class CibaTests
|
|||
|
||||
var response = await _mockPipeline.BackChannelClient.PostAsync(
|
||||
IdentityServerPipeline.BackchannelAuthenticationEndpoint,
|
||||
new FormUrlEncodedContent(body));
|
||||
new FormUrlEncodedContent(body),
|
||||
_ct);
|
||||
|
||||
response.StatusCode.ShouldBe(HttpStatusCode.BadRequest);
|
||||
|
||||
var json = await response.Content.ReadAsStringAsync();
|
||||
var json = await response.Content.ReadAsStringAsync(_ct);
|
||||
var values = JsonSerializer.Deserialize<Dictionary<string, object>>(json);
|
||||
|
||||
values.ContainsKey("error").ShouldBeTrue();
|
||||
|
|
@ -1434,11 +1473,12 @@ public class CibaTests
|
|||
|
||||
var response = await _mockPipeline.BackChannelClient.PostAsync(
|
||||
IdentityServerPipeline.BackchannelAuthenticationEndpoint,
|
||||
new FormUrlEncodedContent(body));
|
||||
new FormUrlEncodedContent(body),
|
||||
_ct);
|
||||
|
||||
response.StatusCode.ShouldBe(HttpStatusCode.BadRequest);
|
||||
|
||||
var json = await response.Content.ReadAsStringAsync();
|
||||
var json = await response.Content.ReadAsStringAsync(_ct);
|
||||
var values = JsonSerializer.Deserialize<Dictionary<string, object>>(json);
|
||||
|
||||
values.ContainsKey("error").ShouldBeTrue();
|
||||
|
|
@ -1463,11 +1503,12 @@ public class CibaTests
|
|||
|
||||
var response = await _mockPipeline.BackChannelClient.PostAsync(
|
||||
IdentityServerPipeline.BackchannelAuthenticationEndpoint,
|
||||
new FormUrlEncodedContent(body));
|
||||
new FormUrlEncodedContent(body),
|
||||
_ct);
|
||||
|
||||
response.StatusCode.ShouldBe(HttpStatusCode.BadRequest);
|
||||
|
||||
var json = await response.Content.ReadAsStringAsync();
|
||||
var json = await response.Content.ReadAsStringAsync(_ct);
|
||||
var values = JsonSerializer.Deserialize<Dictionary<string, object>>(json);
|
||||
|
||||
values.ContainsKey("error").ShouldBeTrue();
|
||||
|
|
@ -1492,11 +1533,12 @@ public class CibaTests
|
|||
|
||||
var response = await _mockPipeline.BackChannelClient.PostAsync(
|
||||
IdentityServerPipeline.BackchannelAuthenticationEndpoint,
|
||||
new FormUrlEncodedContent(body));
|
||||
new FormUrlEncodedContent(body),
|
||||
_ct);
|
||||
|
||||
response.StatusCode.ShouldBe(HttpStatusCode.BadRequest);
|
||||
|
||||
var json = await response.Content.ReadAsStringAsync();
|
||||
var json = await response.Content.ReadAsStringAsync(_ct);
|
||||
var values = JsonSerializer.Deserialize<Dictionary<string, object>>(json);
|
||||
|
||||
values.ContainsKey("error").ShouldBeTrue();
|
||||
|
|
@ -1529,7 +1571,8 @@ public class CibaTests
|
|||
|
||||
var response = await _mockPipeline.BackChannelClient.PostAsync(
|
||||
IdentityServerPipeline.BackchannelAuthenticationEndpoint,
|
||||
new FormUrlEncodedContent(body));
|
||||
new FormUrlEncodedContent(body),
|
||||
_ct);
|
||||
|
||||
response.StatusCode.ShouldBe(HttpStatusCode.OK);
|
||||
|
||||
|
|
@ -1556,7 +1599,8 @@ public class CibaTests
|
|||
|
||||
var response = await _mockPipeline.BackChannelClient.PostAsync(
|
||||
IdentityServerPipeline.BackchannelAuthenticationEndpoint,
|
||||
new FormUrlEncodedContent(body));
|
||||
new FormUrlEncodedContent(body),
|
||||
_ct);
|
||||
|
||||
response.StatusCode.ShouldBe(HttpStatusCode.OK);
|
||||
|
||||
|
|
@ -1583,11 +1627,12 @@ public class CibaTests
|
|||
|
||||
var response = await _mockPipeline.BackChannelClient.PostAsync(
|
||||
IdentityServerPipeline.BackchannelAuthenticationEndpoint,
|
||||
new FormUrlEncodedContent(body));
|
||||
new FormUrlEncodedContent(body),
|
||||
_ct);
|
||||
|
||||
response.StatusCode.ShouldBe(HttpStatusCode.BadRequest);
|
||||
|
||||
var json = await response.Content.ReadAsStringAsync();
|
||||
var json = await response.Content.ReadAsStringAsync(_ct);
|
||||
var values = JsonSerializer.Deserialize<Dictionary<string, object>>(json);
|
||||
|
||||
values.ContainsKey("error").ShouldBeTrue();
|
||||
|
|
@ -1612,15 +1657,15 @@ public class CibaTests
|
|||
|
||||
var response = await _mockPipeline.BackChannelClient.PostAsync(
|
||||
IdentityServerPipeline.BackchannelAuthenticationEndpoint,
|
||||
new FormUrlEncodedContent(body));
|
||||
new FormUrlEncodedContent(body),
|
||||
_ct);
|
||||
|
||||
response.StatusCode.ShouldBe(HttpStatusCode.BadRequest);
|
||||
|
||||
var json = await response.Content.ReadAsStringAsync();
|
||||
var json = await response.Content.ReadAsStringAsync(_ct);
|
||||
var values = JsonSerializer.Deserialize<Dictionary<string, object>>(json);
|
||||
|
||||
values.ContainsKey("error").ShouldBeTrue();
|
||||
values["error"].ToString().ShouldBe("invalid_binding_message");
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ namespace Duende.IdentityServer.IntegrationTests.Endpoints.DeviceAuthorization;
|
|||
|
||||
public class DeviceAuthorizationTests
|
||||
{
|
||||
private readonly CancellationToken _ct = TestContext.Current.CancellationToken;
|
||||
private const string Category = "Device authorization endpoint";
|
||||
|
||||
private IdentityServerPipeline _mockPipeline = new IdentityServerPipeline();
|
||||
|
|
@ -38,10 +39,10 @@ public class DeviceAuthorizationTests
|
|||
[Trait("Category", Category)]
|
||||
public async Task get_should_return_InvalidRequest()
|
||||
{
|
||||
var response = await _mockPipeline.BackChannelClient.GetAsync(IdentityServerPipeline.DeviceAuthorization);
|
||||
var response = await _mockPipeline.BackChannelClient.GetAsync(IdentityServerPipeline.DeviceAuthorization, _ct);
|
||||
response.StatusCode.ShouldBe(HttpStatusCode.BadRequest);
|
||||
|
||||
var resultDto = ParseJsonBody<ErrorResultDto>(await response.Content.ReadAsStreamAsync());
|
||||
var resultDto = ParseJsonBody<ErrorResultDto>(await response.Content.ReadAsStreamAsync(_ct));
|
||||
|
||||
resultDto.ShouldNotBeNull();
|
||||
resultDto.error.ShouldBe(OidcConstants.TokenErrors.InvalidRequest);
|
||||
|
|
@ -56,11 +57,11 @@ public class DeviceAuthorizationTests
|
|||
{"client_id", Guid.NewGuid().ToString()}
|
||||
};
|
||||
var response = await _mockPipeline.BackChannelClient.PostAsync(IdentityServerPipeline.DeviceAuthorization,
|
||||
new StringContent(@"{""client_id"": ""client1""}", Encoding.UTF8, "application/json"));
|
||||
new StringContent(@"{""client_id"": ""client1""}", Encoding.UTF8, "application/json"), _ct);
|
||||
|
||||
response.StatusCode.ShouldBe(HttpStatusCode.BadRequest);
|
||||
|
||||
var resultDto = ParseJsonBody<ErrorResultDto>(await response.Content.ReadAsStreamAsync());
|
||||
var resultDto = ParseJsonBody<ErrorResultDto>(await response.Content.ReadAsStreamAsync(_ct));
|
||||
|
||||
resultDto.ShouldNotBeNull();
|
||||
resultDto.error.ShouldBe(OidcConstants.TokenErrors.InvalidRequest);
|
||||
|
|
@ -71,11 +72,11 @@ public class DeviceAuthorizationTests
|
|||
public async Task empty_request_should_return_InvalidRequest()
|
||||
{
|
||||
var response = await _mockPipeline.BackChannelClient.PostAsync(IdentityServerPipeline.DeviceAuthorization,
|
||||
new FormUrlEncodedContent(new Dictionary<string, string>()));
|
||||
new FormUrlEncodedContent(new Dictionary<string, string>()), _ct);
|
||||
|
||||
response.StatusCode.ShouldBe(HttpStatusCode.BadRequest);
|
||||
|
||||
var resultDto = ParseJsonBody<ErrorResultDto>(await response.Content.ReadAsStreamAsync());
|
||||
var resultDto = ParseJsonBody<ErrorResultDto>(await response.Content.ReadAsStreamAsync(_ct));
|
||||
|
||||
resultDto.ShouldNotBeNull();
|
||||
resultDto.error.ShouldBe(OidcConstants.TokenErrors.InvalidRequest);
|
||||
|
|
@ -89,11 +90,11 @@ public class DeviceAuthorizationTests
|
|||
{
|
||||
{"client_id", "client1"}
|
||||
};
|
||||
var response = await _mockPipeline.BackChannelClient.PostAsync(IdentityServerPipeline.DeviceAuthorization, new FormUrlEncodedContent(form));
|
||||
var response = await _mockPipeline.BackChannelClient.PostAsync(IdentityServerPipeline.DeviceAuthorization, new FormUrlEncodedContent(form), _ct);
|
||||
|
||||
response.StatusCode.ShouldBe(HttpStatusCode.BadRequest);
|
||||
|
||||
var resultDto = ParseJsonBody<ErrorResultDto>(await response.Content.ReadAsStreamAsync());
|
||||
var resultDto = ParseJsonBody<ErrorResultDto>(await response.Content.ReadAsStreamAsync(_ct));
|
||||
|
||||
resultDto.ShouldNotBeNull();
|
||||
resultDto.error.ShouldBe(OidcConstants.TokenErrors.InvalidClient);
|
||||
|
|
@ -108,12 +109,12 @@ public class DeviceAuthorizationTests
|
|||
{"client_id", "client1"},
|
||||
{"client_secret", "secret" }
|
||||
};
|
||||
var response = await _mockPipeline.BackChannelClient.PostAsync(IdentityServerPipeline.DeviceAuthorization, new FormUrlEncodedContent(form));
|
||||
var response = await _mockPipeline.BackChannelClient.PostAsync(IdentityServerPipeline.DeviceAuthorization, new FormUrlEncodedContent(form), _ct);
|
||||
|
||||
response.StatusCode.ShouldBe(HttpStatusCode.OK);
|
||||
response.Content.Headers.ContentType.MediaType.ShouldBe("application/json");
|
||||
|
||||
var resultDto = ParseJsonBody<ResultDto>(await response.Content.ReadAsStreamAsync());
|
||||
var resultDto = ParseJsonBody<ResultDto>(await response.Content.ReadAsStreamAsync(_ct));
|
||||
|
||||
resultDto.ShouldNotBeNull();
|
||||
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ namespace Duende.IdentityServer.IntegrationTests.Endpoints.Discovery;
|
|||
|
||||
public class DiscoveryEndpointTests
|
||||
{
|
||||
private readonly CancellationToken _ct = TestContext.Current.CancellationToken;
|
||||
private const string Category = "Discovery endpoint";
|
||||
|
||||
[Fact]
|
||||
|
|
@ -27,9 +28,9 @@ public class DiscoveryEndpointTests
|
|||
var pipeline = new IdentityServerPipeline();
|
||||
pipeline.Initialize("/ROOT");
|
||||
|
||||
var result = await pipeline.BackChannelClient.GetAsync("HTTPS://SERVER/ROOT/.WELL-KNOWN/OPENID-CONFIGURATION");
|
||||
var result = await pipeline.BackChannelClient.GetAsync("HTTPS://SERVER/ROOT/.WELL-KNOWN/OPENID-CONFIGURATION", _ct);
|
||||
|
||||
var json = await result.Content.ReadAsStringAsync();
|
||||
var json = await result.Content.ReadAsStringAsync(_ct);
|
||||
var data = JsonSerializer.Deserialize<Dictionary<string, JsonElement>>(json);
|
||||
data["issuer"].GetString().ShouldBe("https://server/root");
|
||||
}
|
||||
|
|
@ -43,9 +44,9 @@ public class DiscoveryEndpointTests
|
|||
|
||||
pipeline.Options.LowerCaseIssuerUri = false;
|
||||
|
||||
var result = await pipeline.BackChannelClient.GetAsync("HTTPS://SERVER/ROOT/.WELL-KNOWN/OPENID-CONFIGURATION");
|
||||
var result = await pipeline.BackChannelClient.GetAsync("HTTPS://SERVER/ROOT/.WELL-KNOWN/OPENID-CONFIGURATION", _ct);
|
||||
|
||||
var json = await result.Content.ReadAsStringAsync();
|
||||
var json = await result.Content.ReadAsStringAsync(_ct);
|
||||
var data = JsonSerializer.Deserialize<Dictionary<string, JsonElement>>(json);
|
||||
data["issuer"].GetString().ShouldBe("https://server/ROOT");
|
||||
}
|
||||
|
|
@ -68,7 +69,7 @@ public class DiscoveryEndpointTests
|
|||
};
|
||||
pipeline.Initialize();
|
||||
|
||||
var result = await pipeline.BackChannelClient.GetDiscoveryDocumentAsync("https://server/.well-known/openid-configuration");
|
||||
var result = await pipeline.BackChannelClient.GetDiscoveryDocumentAsync("https://server/.well-known/openid-configuration", _ct);
|
||||
|
||||
var algorithmsSupported = result.TryGetStringArray("id_token_signing_alg_values_supported");
|
||||
|
||||
|
|
@ -110,9 +111,9 @@ public class DiscoveryEndpointTests
|
|||
|
||||
pipeline.Initialize("/ROOT");
|
||||
|
||||
var result = await pipeline.BackChannelClient.GetAsync("https://server/root/.well-known/openid-configuration/jwks");
|
||||
var result = await pipeline.BackChannelClient.GetAsync("https://server/root/.well-known/openid-configuration/jwks", _ct);
|
||||
|
||||
var json = await result.Content.ReadAsStringAsync();
|
||||
var json = await result.Content.ReadAsStringAsync(_ct);
|
||||
var data = JsonSerializer.Deserialize<Dictionary<string, JsonElement>>(json);
|
||||
|
||||
var keys = data["keys"].EnumerateArray().ToList();
|
||||
|
|
@ -130,9 +131,9 @@ public class DiscoveryEndpointTests
|
|||
var pipeline = new IdentityServerPipeline();
|
||||
pipeline.Initialize("/ROOT");
|
||||
|
||||
var result = await pipeline.BackChannelClient.GetAsync("https://server/root/.well-known/openid-configuration/jwks");
|
||||
var result = await pipeline.BackChannelClient.GetAsync("https://server/root/.well-known/openid-configuration/jwks", _ct);
|
||||
|
||||
var json = await result.Content.ReadAsStringAsync();
|
||||
var json = await result.Content.ReadAsStringAsync(_ct);
|
||||
var data = JsonSerializer.Deserialize<Dictionary<string, JsonElement>>(json);
|
||||
|
||||
var keys = data["keys"];
|
||||
|
|
@ -159,9 +160,9 @@ public class DiscoveryEndpointTests
|
|||
};
|
||||
pipeline.Initialize("/ROOT");
|
||||
|
||||
var result = await pipeline.BackChannelClient.GetAsync("https://server/root/.well-known/openid-configuration/jwks");
|
||||
var result = await pipeline.BackChannelClient.GetAsync("https://server/root/.well-known/openid-configuration/jwks", _ct);
|
||||
|
||||
var json = await result.Content.ReadAsStringAsync();
|
||||
var json = await result.Content.ReadAsStringAsync(_ct);
|
||||
var jwks = new JsonWebKeySet(json);
|
||||
var parsedKeys = jwks.GetSigningKeys();
|
||||
|
||||
|
|
@ -185,9 +186,9 @@ public class DiscoveryEndpointTests
|
|||
};
|
||||
pipeline.Initialize("/ROOT");
|
||||
|
||||
var result = await pipeline.BackChannelClient.GetAsync("https://server/root/.well-known/openid-configuration/jwks");
|
||||
var result = await pipeline.BackChannelClient.GetAsync("https://server/root/.well-known/openid-configuration/jwks", _ct);
|
||||
|
||||
var json = await result.Content.ReadAsStringAsync();
|
||||
var json = await result.Content.ReadAsStringAsync(_ct);
|
||||
var jwks = new JsonWebKeySet(json);
|
||||
|
||||
jwks.Keys.ShouldContain(x => x.KeyId == ecdsaKey.KeyId && x.Alg == "ES256");
|
||||
|
|
@ -211,7 +212,7 @@ public class DiscoveryEndpointTests
|
|||
RequireHttps = false,
|
||||
RequireKeySet = false
|
||||
}
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
result.Issuer.ShouldBe("https://грант.рф");
|
||||
}
|
||||
|
|
@ -224,9 +225,9 @@ public class DiscoveryEndpointTests
|
|||
var pipeline = new IdentityServerPipeline();
|
||||
pipeline.Initialize();
|
||||
|
||||
var result = await pipeline.BackChannelClient.GetAsync("https://server/.well-known/openid-configuration");
|
||||
var result = await pipeline.BackChannelClient.GetAsync("https://server/.well-known/openid-configuration", _ct);
|
||||
|
||||
var json = await result.Content.ReadAsStringAsync();
|
||||
var json = await result.Content.ReadAsStringAsync(_ct);
|
||||
var data = JsonSerializer.Deserialize<Dictionary<string, JsonElement>>(json);
|
||||
var prompts = data["prompt_values_supported"].EnumerateArray()
|
||||
.Select(x => x.GetString()).ToList();
|
||||
|
|
@ -248,9 +249,9 @@ public class DiscoveryEndpointTests
|
|||
pipeline.Initialize();
|
||||
|
||||
|
||||
var result = await pipeline.BackChannelClient.GetAsync("https://server/.well-known/openid-configuration");
|
||||
var result = await pipeline.BackChannelClient.GetAsync("https://server/.well-known/openid-configuration", _ct);
|
||||
|
||||
var json = await result.Content.ReadAsStringAsync();
|
||||
var json = await result.Content.ReadAsStringAsync(_ct);
|
||||
var data = JsonSerializer.Deserialize<Dictionary<string, JsonElement>>(json);
|
||||
var prompts = data["prompt_values_supported"].EnumerateArray()
|
||||
.Select(x => x.GetString()).ToList();
|
||||
|
|
@ -265,9 +266,9 @@ public class DiscoveryEndpointTests
|
|||
pipeline.Initialize();
|
||||
pipeline.Options.Endpoints.EnableAuthorizeEndpoint = false;
|
||||
|
||||
var result = await pipeline.BackChannelClient.GetAsync("https://server/.well-known/openid-configuration");
|
||||
var result = await pipeline.BackChannelClient.GetAsync("https://server/.well-known/openid-configuration", _ct);
|
||||
|
||||
var json = await result.Content.ReadAsStringAsync();
|
||||
var json = await result.Content.ReadAsStringAsync(_ct);
|
||||
var data = JsonSerializer.Deserialize<Dictionary<string, JsonElement>>(json);
|
||||
data.ContainsKey("prompt_values_supported").ShouldBeFalse();
|
||||
}
|
||||
|
|
@ -284,7 +285,7 @@ public class DiscoveryEndpointTests
|
|||
pipeline.Options.Preview.DiscoveryDocumentCacheDuration = TimeSpan.FromSeconds(1);
|
||||
|
||||
// cache
|
||||
_ = await pipeline.BackChannelClient.GetAsync("https://server/root/.well-known/openid-configuration");
|
||||
_ = await pipeline.BackChannelClient.GetAsync("https://server/root/.well-known/openid-configuration", _ct);
|
||||
|
||||
// add new entry
|
||||
pipeline.Options.Discovery.CustomEntries = new() {
|
||||
|
|
@ -292,9 +293,9 @@ public class DiscoveryEndpointTests
|
|||
};
|
||||
|
||||
// get cached document
|
||||
var result = await pipeline.BackChannelClient.GetAsync("https://server/root/.well-known/openid-configuration");
|
||||
var result = await pipeline.BackChannelClient.GetAsync("https://server/root/.well-known/openid-configuration", _ct);
|
||||
|
||||
var json = await result.Content.ReadAsStringAsync();
|
||||
var json = await result.Content.ReadAsStringAsync(_ct);
|
||||
var data = JsonSerializer.Deserialize<Dictionary<string, JsonElement>>(json);
|
||||
|
||||
// we got a result back
|
||||
|
|
@ -332,7 +333,7 @@ public class DiscoveryEndpointTests
|
|||
pipeline.Options.Preview.EnableDiscoveryDocumentCache = enableCache;
|
||||
pipeline.Options.Discovery.CustomEntries.Add("foo", "bar");
|
||||
|
||||
var result = await pipeline.BackChannelClient.GetDiscoveryDocumentAsync("https://server/.well-known/openid-configuration");
|
||||
var result = await pipeline.BackChannelClient.GetDiscoveryDocumentAsync("https://server/.well-known/openid-configuration", _ct);
|
||||
|
||||
result.TryGetString("foo").ShouldBe("bar");
|
||||
}
|
||||
|
|
@ -351,7 +352,7 @@ public class DiscoveryEndpointTests
|
|||
pipeline.Initialize();
|
||||
pipeline.Options.Preview.EnableDiscoveryDocumentCache = enableCache;
|
||||
|
||||
var result = await pipeline.BackChannelClient.GetDiscoveryDocumentAsync("https://server/.well-known/openid-configuration");
|
||||
var result = await pipeline.BackChannelClient.GetDiscoveryDocumentAsync("https://server/.well-known/openid-configuration", _ct);
|
||||
|
||||
if (enableCache)
|
||||
{
|
||||
|
|
@ -373,7 +374,7 @@ public class DiscoveryEndpointTests
|
|||
pipeline.Options.MutualTls.Enabled = true;
|
||||
|
||||
|
||||
var result = await pipeline.BackChannelClient.GetDiscoveryDocumentAsync("https://server/.well-known/openid-configuration");
|
||||
var result = await pipeline.BackChannelClient.GetDiscoveryDocumentAsync("https://server/.well-known/openid-configuration", _ct);
|
||||
result.MtlsEndpointAliases.PushedAuthorizationRequestEndpoint.ShouldNotBeNull();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ namespace Duende.IdentityServer.IntegrationTests.Endpoints.Discovery;
|
|||
|
||||
public class DiscoveryEndpointTests_dpop_signing_alg_values_supported
|
||||
{
|
||||
private readonly CancellationToken _ct = TestContext.Current.CancellationToken;
|
||||
private const string Category = "Discovery endpoint - dpop_signing_alg_values_supported";
|
||||
|
||||
[Fact]
|
||||
|
|
@ -30,7 +31,7 @@ public class DiscoveryEndpointTests_dpop_signing_alg_values_supported
|
|||
|
||||
var result =
|
||||
await pipeline.BackChannelClient.GetDiscoveryDocumentAsync(
|
||||
"https://server/.well-known/openid-configuration");
|
||||
"https://server/.well-known/openid-configuration", _ct);
|
||||
|
||||
var supportedAlgorithmsFromResponse =
|
||||
result.TryGetStringArray(OidcConstants.Discovery.DPoPSigningAlgorithmsSupported);
|
||||
|
|
@ -43,9 +44,9 @@ public class DiscoveryEndpointTests_dpop_signing_alg_values_supported
|
|||
var pipeline = new IdentityServerPipeline();
|
||||
pipeline.Initialize();
|
||||
|
||||
var result =
|
||||
await pipeline.BackChannelClient.GetDiscoveryDocumentAsync(
|
||||
"https://server/.well-known/openid-configuration");
|
||||
var result = await pipeline.BackChannelClient.GetDiscoveryDocumentAsync(
|
||||
"https://server/.well-known/openid-configuration",
|
||||
_ct);
|
||||
var algorithmsSupported = result.TryGetStringArray("dpop_signing_alg_values_supported");
|
||||
|
||||
algorithmsSupported.Count().ShouldBe(9);
|
||||
|
|
@ -71,8 +72,8 @@ public class DiscoveryEndpointTests_dpop_signing_alg_values_supported
|
|||
pipeline.Options.DPoP.SupportedDPoPSigningAlgorithms = algorithms;
|
||||
|
||||
var result = await pipeline.BackChannelClient
|
||||
.GetAsync("https://server/.well-known/openid-configuration");
|
||||
var json = await result.Content.ReadAsStringAsync();
|
||||
.GetAsync("https://server/.well-known/openid-configuration", _ct);
|
||||
var json = await result.Content.ReadAsStringAsync(_ct);
|
||||
var data = JsonSerializer.Deserialize<Dictionary<string, JsonElement>>(json);
|
||||
|
||||
data.ShouldNotContainKey(OidcConstants.Discovery.DPoPSigningAlgorithmsSupported);
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ namespace Duende.IdentityServer.IntegrationTests.Endpoints.Discovery;
|
|||
|
||||
public class DiscoveryEndpointTests_token_endpoint_auth_signing_alg_values_supported
|
||||
{
|
||||
private readonly CancellationToken _ct = TestContext.Current.CancellationToken;
|
||||
private const string Category = "Discovery endpoint - token_endpoint_auth_signing_alg_values_supported";
|
||||
|
||||
[Fact]
|
||||
|
|
@ -29,7 +30,7 @@ public class DiscoveryEndpointTests_token_endpoint_auth_signing_alg_values_suppo
|
|||
];
|
||||
|
||||
var disco = await pipeline.BackChannelClient
|
||||
.GetDiscoveryDocumentAsync("https://server/.well-known/openid-configuration");
|
||||
.GetDiscoveryDocumentAsync("https://server/.well-known/openid-configuration", _ct);
|
||||
disco.IsError.ShouldBeFalse();
|
||||
|
||||
var algorithmsSupported = disco.TokenEndpointAuthenticationSigningAlgorithmsSupported;
|
||||
|
|
@ -48,9 +49,9 @@ public class DiscoveryEndpointTests_token_endpoint_auth_signing_alg_values_suppo
|
|||
svcs.AddIdentityServerBuilder().AddJwtBearerClientAuthentication();
|
||||
pipeline.Initialize();
|
||||
|
||||
var result =
|
||||
await pipeline.BackChannelClient.GetDiscoveryDocumentAsync(
|
||||
"https://server/.well-known/openid-configuration");
|
||||
var result = await pipeline.BackChannelClient.GetDiscoveryDocumentAsync(
|
||||
"https://server/.well-known/openid-configuration",
|
||||
_ct);
|
||||
|
||||
result.IsError.ShouldBeFalse();
|
||||
var algorithmsSupported = result.TokenEndpointAuthenticationSigningAlgorithmsSupported;
|
||||
|
|
@ -77,7 +78,7 @@ public class DiscoveryEndpointTests_token_endpoint_auth_signing_alg_values_suppo
|
|||
pipeline.Options.SupportedClientAssertionSigningAlgorithms = [SecurityAlgorithms.RsaSha256];
|
||||
|
||||
var disco = await pipeline.BackChannelClient
|
||||
.GetDiscoveryDocumentAsync("https://server/.well-known/openid-configuration");
|
||||
.GetDiscoveryDocumentAsync("https://server/.well-known/openid-configuration", _ct);
|
||||
|
||||
// Verify assumptions
|
||||
disco.IsError.ShouldBeFalse();
|
||||
|
|
@ -102,8 +103,8 @@ public class DiscoveryEndpointTests_token_endpoint_auth_signing_alg_values_suppo
|
|||
pipeline.Options.SupportedClientAssertionSigningAlgorithms = algorithms;
|
||||
|
||||
var result = await pipeline.BackChannelClient
|
||||
.GetAsync("https://server/.well-known/openid-configuration");
|
||||
var json = await result.Content.ReadAsStringAsync();
|
||||
.GetAsync("https://server/.well-known/openid-configuration", _ct);
|
||||
var json = await result.Content.ReadAsStringAsync(_ct);
|
||||
var data = JsonSerializer.Deserialize<Dictionary<string, JsonElement>>(json);
|
||||
|
||||
data.ShouldNotContainKey(OidcConstants.Discovery.TokenEndpointAuthSigningAlgorithmsSupported);
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ namespace Duende.IdentityServer.IntegrationTests.Endpoints.Discovery;
|
|||
|
||||
public class DiscoveryEndpoint_request_object_auth_signing_algs_supported_Tests
|
||||
{
|
||||
private readonly CancellationToken _ct = TestContext.Current.CancellationToken;
|
||||
private const string Category = "Discovery endpoint - request_object_signing_algs_supported";
|
||||
|
||||
[Fact]
|
||||
|
|
@ -25,9 +26,8 @@ public class DiscoveryEndpoint_request_object_auth_signing_algs_supported_Tests
|
|||
SecurityAlgorithms.EcdsaSha256
|
||||
];
|
||||
|
||||
var result =
|
||||
await pipeline.BackChannelClient.GetDiscoveryDocumentAsync(
|
||||
"https://server/.well-known/openid-configuration");
|
||||
var result = await pipeline.BackChannelClient
|
||||
.GetDiscoveryDocumentAsync("https://server/.well-known/openid-configuration", _ct);
|
||||
var algorithmsSupported = result.TryGetStringArray("request_object_signing_alg_values_supported");
|
||||
|
||||
algorithmsSupported.Count().ShouldBe(2);
|
||||
|
|
@ -46,8 +46,8 @@ public class DiscoveryEndpoint_request_object_auth_signing_algs_supported_Tests
|
|||
pipeline.Options.SupportedRequestObjectSigningAlgorithms = algorithms;
|
||||
|
||||
var result = await pipeline.BackChannelClient
|
||||
.GetAsync("https://server/.well-known/openid-configuration");
|
||||
var json = await result.Content.ReadAsStringAsync();
|
||||
.GetAsync("https://server/.well-known/openid-configuration", _ct);
|
||||
var json = await result.Content.ReadAsStringAsync(_ct);
|
||||
var data = JsonSerializer.Deserialize<Dictionary<string, JsonElement>>(json);
|
||||
|
||||
data.ShouldNotContainKey("request_object_signing_alg_values_supported");
|
||||
|
|
@ -62,7 +62,7 @@ public class DiscoveryEndpoint_request_object_auth_signing_algs_supported_Tests
|
|||
|
||||
var result =
|
||||
await pipeline.BackChannelClient.GetDiscoveryDocumentAsync(
|
||||
"https://server/.well-known/openid-configuration");
|
||||
"https://server/.well-known/openid-configuration", _ct);
|
||||
var algorithmsSupported = result.TryGetStringArray("request_object_signing_alg_values_supported");
|
||||
|
||||
algorithmsSupported.ShouldBe([
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ namespace Duende.IdentityServer.IntegrationTests.Endpoints.EndSession;
|
|||
public class EndSessionTests
|
||||
{
|
||||
private const string Category = "End session endpoint";
|
||||
|
||||
private readonly CancellationToken _ct = TestContext.Current.CancellationToken;
|
||||
private IdentityServerPipeline _mockPipeline = new IdentityServerPipeline();
|
||||
private Client _wsfedClient;
|
||||
|
||||
|
|
@ -116,7 +116,7 @@ public class EndSessionTests
|
|||
[Trait("Category", Category)]
|
||||
public async Task get_request_should_not_return_404()
|
||||
{
|
||||
var response = await _mockPipeline.BackChannelClient.GetAsync(IdentityServerPipeline.EndSessionEndpoint);
|
||||
var response = await _mockPipeline.BackChannelClient.GetAsync(IdentityServerPipeline.EndSessionEndpoint, _ct);
|
||||
|
||||
response.StatusCode.ShouldNotBe(HttpStatusCode.NotFound);
|
||||
}
|
||||
|
|
@ -125,7 +125,7 @@ public class EndSessionTests
|
|||
[Trait("Category", Category)]
|
||||
public async Task signout_request_should_redirect_to_logout_page()
|
||||
{
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(IdentityServerPipeline.EndSessionEndpoint);
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(IdentityServerPipeline.EndSessionEndpoint, _ct);
|
||||
|
||||
_mockPipeline.LogoutWasCalled.ShouldBeTrue();
|
||||
}
|
||||
|
|
@ -148,13 +148,12 @@ public class EndSessionTests
|
|||
nonce: "123_nonce");
|
||||
|
||||
_mockPipeline.BrowserClient.AllowAutoRedirect = false;
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(url);
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(url, _ct);
|
||||
var authorization = new Duende.IdentityModel.Client.AuthorizeResponse(response.Headers.Location.ToString());
|
||||
var id_token = authorization.IdentityToken;
|
||||
|
||||
response = await _mockPipeline.BrowserClient.GetAsync(IdentityServerPipeline.EndSessionEndpoint +
|
||||
"?id_token_hint=" + id_token +
|
||||
"&post_logout_redirect_uri=https://client1/signout-callback");
|
||||
response = await _mockPipeline.BrowserClient
|
||||
.GetAsync(IdentityServerPipeline.EndSessionEndpoint + "?id_token_hint=" + id_token + "&post_logout_redirect_uri=https://client1/signout-callback", _ct);
|
||||
|
||||
response.StatusCode.ShouldBe(HttpStatusCode.Redirect);
|
||||
response.Headers.Location.ToString().ShouldStartWith("https://server/logout?id=");
|
||||
|
|
@ -179,7 +178,7 @@ public class EndSessionTests
|
|||
var response = await _mockPipeline.BrowserClient.GetAsync(IdentityServerPipeline.EndSessionEndpoint +
|
||||
"?id_token_hint=" + id_token +
|
||||
"&post_logout_redirect_uri=https://client2/signout-callback2" +
|
||||
"&ui_locales=fr-FR fr-CA");
|
||||
"&ui_locales=fr-FR fr-CA", _ct);
|
||||
|
||||
_mockPipeline.LogoutWasCalled.ShouldBeTrue();
|
||||
_mockPipeline.LogoutRequest.ShouldNotBeNull();
|
||||
|
|
@ -212,7 +211,7 @@ public class EndSessionTests
|
|||
var response = await _mockPipeline.BrowserClient.GetAsync(IdentityServerPipeline.EndSessionEndpoint +
|
||||
"?id_token_hint=" + id_token +
|
||||
"&post_logout_redirect_uri=https://client2/signout-callback2" +
|
||||
"&ui_locales=" + new string('x', 101));
|
||||
"&ui_locales=" + new string('x', 101), _ct);
|
||||
|
||||
_mockPipeline.LogoutWasCalled.ShouldBeTrue();
|
||||
_mockPipeline.LogoutRequest.ShouldNotBeNull();
|
||||
|
|
@ -240,7 +239,7 @@ public class EndSessionTests
|
|||
var response = await _mockPipeline.BrowserClient.GetAsync(IdentityServerPipeline.EndSessionEndpoint +
|
||||
"?id_token_hint=" + id_token +
|
||||
"&post_logout_redirect_uri=https://client2/signout-callback2" +
|
||||
"&ui_locales=nb-NO");
|
||||
"&ui_locales=nb-NO", _ct);
|
||||
|
||||
_mockPipeline.LogoutWasCalled.ShouldBeTrue();
|
||||
var cookie = _mockPipeline.BrowserClient.GetCookie("http://server", CookieRequestCultureProvider.DefaultCookieName);
|
||||
|
|
@ -268,7 +267,7 @@ public class EndSessionTests
|
|||
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(IdentityServerPipeline.EndSessionEndpoint +
|
||||
"?id_token_hint=" + id_token +
|
||||
"&post_logout_redirect_uri=https://client2/signout-callback2");
|
||||
"&post_logout_redirect_uri=https://client2/signout-callback2", _ct);
|
||||
|
||||
_mockPipeline.LogoutWasCalled.ShouldBeTrue();
|
||||
_mockPipeline.LogoutRequest.ShouldNotBeNull();
|
||||
|
|
@ -292,7 +291,7 @@ public class EndSessionTests
|
|||
nonce: "123_nonce");
|
||||
|
||||
_mockPipeline.BrowserClient.AllowAutoRedirect = false;
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(url);
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(url, _ct);
|
||||
var authorization = new Duende.IdentityModel.Client.AuthorizeResponse(response.Headers.Location.ToString());
|
||||
var id_token = authorization.IdentityToken;
|
||||
|
||||
|
|
@ -302,7 +301,7 @@ public class EndSessionTests
|
|||
values.Add(new KeyValuePair<string, string>("id_token_hint", id_token));
|
||||
values.Add(new KeyValuePair<string, string>("post_logout_redirect_uri", "https://client1/signout-callback"));
|
||||
var content = new FormUrlEncodedContent(values);
|
||||
response = await _mockPipeline.BrowserClient.PostAsync(IdentityServerPipeline.EndSessionEndpoint, content);
|
||||
response = await _mockPipeline.BrowserClient.PostAsync(IdentityServerPipeline.EndSessionEndpoint, content, _ct);
|
||||
|
||||
_mockPipeline.LogoutWasCalled.ShouldBeTrue();
|
||||
_mockPipeline.LogoutRequest.ShouldNotBeNull();
|
||||
|
|
@ -319,7 +318,7 @@ public class EndSessionTests
|
|||
[Trait("Category", Category)]
|
||||
public async Task signout_callback_without_params_should_return_400()
|
||||
{
|
||||
var response = await _mockPipeline.BackChannelClient.GetAsync(IdentityServerPipeline.EndSessionCallbackEndpoint);
|
||||
var response = await _mockPipeline.BackChannelClient.GetAsync(IdentityServerPipeline.EndSessionCallbackEndpoint, _ct);
|
||||
|
||||
response.StatusCode.ShouldBe(HttpStatusCode.BadRequest);
|
||||
}
|
||||
|
|
@ -339,7 +338,7 @@ public class EndSessionTests
|
|||
nonce: "123_nonce");
|
||||
|
||||
_mockPipeline.BrowserClient.AllowAutoRedirect = false;
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(url);
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(url, _ct);
|
||||
|
||||
var authorization = new Duende.IdentityModel.Client.AuthorizeResponse(response.Headers.Location.ToString());
|
||||
var id_token = authorization.IdentityToken;
|
||||
|
|
@ -347,11 +346,11 @@ public class EndSessionTests
|
|||
_mockPipeline.BrowserClient.AllowAutoRedirect = true;
|
||||
response = await _mockPipeline.BrowserClient.GetAsync(IdentityServerPipeline.EndSessionEndpoint +
|
||||
"?id_token_hint=" + id_token +
|
||||
"&post_logout_redirect_uri=https://client1/signout-callback-not-valid");
|
||||
"&post_logout_redirect_uri=https://client1/signout-callback-not-valid", _ct);
|
||||
|
||||
var signoutFrameUrl = _mockPipeline.LogoutRequest.SignOutIFrameUrl;
|
||||
|
||||
response = await _mockPipeline.BrowserClient.GetAsync(signoutFrameUrl);
|
||||
response = await _mockPipeline.BrowserClient.GetAsync(signoutFrameUrl, _ct);
|
||||
|
||||
_mockPipeline.LogoutRequest.ClientId.ShouldNotBeNull();
|
||||
_mockPipeline.LogoutRequest.PostLogoutRedirectUri.ShouldBeNull();
|
||||
|
|
@ -372,7 +371,7 @@ public class EndSessionTests
|
|||
nonce: "123_nonce");
|
||||
|
||||
_mockPipeline.BrowserClient.AllowAutoRedirect = false;
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(url);
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(url, _ct);
|
||||
|
||||
var authorization = new Duende.IdentityModel.Client.AuthorizeResponse(response.Headers.Location.ToString());
|
||||
var id_token = authorization.IdentityToken;
|
||||
|
|
@ -382,7 +381,7 @@ public class EndSessionTests
|
|||
_mockPipeline.BrowserClient.AllowAutoRedirect = true;
|
||||
response = await _mockPipeline.BrowserClient.GetAsync(IdentityServerPipeline.EndSessionEndpoint +
|
||||
"?id_token_hint=" + id_token +
|
||||
"&post_logout_redirect_uri=https://client1/signout-callback");
|
||||
"&post_logout_redirect_uri=https://client1/signout-callback", _ct);
|
||||
|
||||
_mockPipeline.LogoutRequest.ClientId.ShouldBeNull();
|
||||
_mockPipeline.LogoutRequest.PostLogoutRedirectUri.ShouldBeNull();
|
||||
|
|
@ -403,14 +402,14 @@ public class EndSessionTests
|
|||
nonce: "123_nonce");
|
||||
|
||||
_mockPipeline.BrowserClient.AllowAutoRedirect = false;
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(url);
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(url, _ct);
|
||||
|
||||
_mockPipeline.BrowserClient.AllowAutoRedirect = true;
|
||||
response = await _mockPipeline.BrowserClient.GetAsync(IdentityServerPipeline.EndSessionEndpoint);
|
||||
response = await _mockPipeline.BrowserClient.GetAsync(IdentityServerPipeline.EndSessionEndpoint, _ct);
|
||||
|
||||
var signoutFrameUrl = _mockPipeline.LogoutRequest.SignOutIFrameUrl;
|
||||
|
||||
response = await _mockPipeline.BrowserClient.GetAsync(signoutFrameUrl);
|
||||
response = await _mockPipeline.BrowserClient.GetAsync(signoutFrameUrl, _ct);
|
||||
response.StatusCode.ShouldBe(HttpStatusCode.OK);
|
||||
response.Content.Headers.ContentType.MediaType.ShouldBe("text/html");
|
||||
}
|
||||
|
|
@ -430,7 +429,7 @@ public class EndSessionTests
|
|||
redirectUri: "https://client1/callback",
|
||||
state: "123_state",
|
||||
nonce: "123_nonce");
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(url);
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(url, _ct);
|
||||
|
||||
var url2 = _mockPipeline.CreateAuthorizeUrl(
|
||||
clientId: "client2",
|
||||
|
|
@ -439,15 +438,15 @@ public class EndSessionTests
|
|||
redirectUri: "https://client2/callback",
|
||||
state: "123_state",
|
||||
nonce: "123_nonce");
|
||||
var response2 = await _mockPipeline.BrowserClient.GetAsync(url2);
|
||||
var response2 = await _mockPipeline.BrowserClient.GetAsync(url2, _ct);
|
||||
|
||||
_mockPipeline.BrowserClient.AllowAutoRedirect = true;
|
||||
response = await _mockPipeline.BrowserClient.GetAsync(IdentityServerPipeline.EndSessionEndpoint);
|
||||
response = await _mockPipeline.BrowserClient.GetAsync(IdentityServerPipeline.EndSessionEndpoint, _ct);
|
||||
|
||||
var signoutFrameUrl = _mockPipeline.LogoutRequest.SignOutIFrameUrl;
|
||||
|
||||
response = await _mockPipeline.BrowserClient.GetAsync(signoutFrameUrl);
|
||||
var html = await response.Content.ReadAsStringAsync();
|
||||
response = await _mockPipeline.BrowserClient.GetAsync(signoutFrameUrl, _ct);
|
||||
var html = await response.Content.ReadAsStringAsync(_ct);
|
||||
html.ShouldContain(HtmlEncoder.Default.Encode("https://client1/signout?sid=" + sid + "&iss=" + UrlEncoder.Default.Encode("https://server")));
|
||||
html.ShouldContain(HtmlEncoder.Default.Encode("https://client2/signout?sid=" + sid + "&iss=" + UrlEncoder.Default.Encode("https://server")));
|
||||
}
|
||||
|
|
@ -467,10 +466,10 @@ public class EndSessionTests
|
|||
redirectUri: "https://client4/callback",
|
||||
state: "123_state",
|
||||
nonce: "123_nonce");
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(url);
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(url, _ct);
|
||||
|
||||
_mockPipeline.BrowserClient.AllowAutoRedirect = true;
|
||||
response = await _mockPipeline.BrowserClient.GetAsync(IdentityServerPipeline.EndSessionEndpoint);
|
||||
response = await _mockPipeline.BrowserClient.GetAsync(IdentityServerPipeline.EndSessionEndpoint, _ct);
|
||||
|
||||
var signoutFrameUrl = _mockPipeline.LogoutRequest.SignOutIFrameUrl;
|
||||
|
||||
|
|
@ -478,8 +477,8 @@ public class EndSessionTests
|
|||
// at signout to use ws-fed so we can test the iframe params
|
||||
_wsfedClient.ProtocolType = IdentityServerConstants.ProtocolTypes.WsFederation;
|
||||
|
||||
response = await _mockPipeline.BrowserClient.GetAsync(signoutFrameUrl);
|
||||
var html = await response.Content.ReadAsStringAsync();
|
||||
response = await _mockPipeline.BrowserClient.GetAsync(signoutFrameUrl, _ct);
|
||||
var html = await response.Content.ReadAsStringAsync(_ct);
|
||||
html.ShouldContain("https://client4/signout?wa=wsignoutcleanup1.0");
|
||||
}
|
||||
|
||||
|
|
@ -497,13 +496,13 @@ public class EndSessionTests
|
|||
redirectUri: "https://client1/callback",
|
||||
state: "123_state",
|
||||
nonce: "123_nonce");
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(url);
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(url, _ct);
|
||||
var authorization = new Duende.IdentityModel.Client.AuthorizeResponse(response.Headers.Location.ToString());
|
||||
var id_token = authorization.IdentityToken;
|
||||
|
||||
_mockPipeline.BrowserClient.AllowAutoRedirect = true;
|
||||
response = await _mockPipeline.BrowserClient.GetAsync(IdentityServerPipeline.EndSessionEndpoint +
|
||||
"?id_token_hint=" + id_token);
|
||||
"?id_token_hint=" + id_token, _ct);
|
||||
|
||||
_mockPipeline.LogoutRequest.PostLogoutRedirectUri.ShouldBeNull();
|
||||
}
|
||||
|
|
@ -522,13 +521,13 @@ public class EndSessionTests
|
|||
redirectUri: "https://client2/callback",
|
||||
state: "123_state",
|
||||
nonce: "123_nonce");
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(url);
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(url, _ct);
|
||||
var authorization = new Duende.IdentityModel.Client.AuthorizeResponse(response.Headers.Location.ToString());
|
||||
var id_token = authorization.IdentityToken;
|
||||
|
||||
_mockPipeline.BrowserClient.AllowAutoRedirect = true;
|
||||
response = await _mockPipeline.BrowserClient.GetAsync(IdentityServerPipeline.EndSessionEndpoint +
|
||||
"?id_token_hint=" + id_token);
|
||||
"?id_token_hint=" + id_token, _ct);
|
||||
|
||||
_mockPipeline.LogoutRequest.PostLogoutRedirectUri.ShouldBeNull();
|
||||
}
|
||||
|
|
@ -548,7 +547,7 @@ public class EndSessionTests
|
|||
nonce: "123_nonce");
|
||||
response.ShouldNotBeNull();
|
||||
|
||||
await _mockPipeline.BrowserClient.GetAsync(IdentityServerPipeline.EndSessionEndpoint);
|
||||
await _mockPipeline.BrowserClient.GetAsync(IdentityServerPipeline.EndSessionEndpoint, _ct);
|
||||
|
||||
_mockPipeline.LogoutWasCalled.ShouldBeTrue();
|
||||
_mockPipeline.LogoutRequest.SignOutIFrameUrl.ShouldNotBeNull();
|
||||
|
|
@ -560,7 +559,7 @@ public class EndSessionTests
|
|||
{
|
||||
await _mockPipeline.LoginAsync("bob");
|
||||
|
||||
await _mockPipeline.BrowserClient.GetAsync(IdentityServerPipeline.EndSessionEndpoint);
|
||||
await _mockPipeline.BrowserClient.GetAsync(IdentityServerPipeline.EndSessionEndpoint, _ct);
|
||||
|
||||
_mockPipeline.LogoutWasCalled.ShouldBeTrue();
|
||||
_mockPipeline.LogoutRequest.SignOutIFrameUrl.ShouldBeNull();
|
||||
|
|
@ -609,7 +608,7 @@ public class EndSessionTests
|
|||
nonce: "123_nonce");
|
||||
response.ShouldNotBeNull();
|
||||
|
||||
await _mockPipeline.BrowserClient.GetAsync(IdentityServerPipeline.EndSessionEndpoint);
|
||||
await _mockPipeline.BrowserClient.GetAsync(IdentityServerPipeline.EndSessionEndpoint, _ct);
|
||||
|
||||
_mockPipeline.BackChannelMessageHandler.InvokeWasCalled.ShouldBeTrue();
|
||||
}
|
||||
|
|
@ -647,7 +646,7 @@ public class EndSessionTests
|
|||
nonce: "123_nonce");
|
||||
response.ShouldNotBeNull();
|
||||
|
||||
await _mockPipeline.BrowserClient.GetAsync(IdentityServerPipeline.EndSessionEndpoint);
|
||||
await _mockPipeline.BrowserClient.GetAsync(IdentityServerPipeline.EndSessionEndpoint, _ct);
|
||||
|
||||
_mockPipeline.BackChannelMessageHandler.InvokeWasCalled.ShouldBeTrue();
|
||||
}
|
||||
|
|
@ -687,7 +686,7 @@ public class EndSessionTests
|
|||
nonce: "123_nonce");
|
||||
response.ShouldNotBeNull();
|
||||
|
||||
await _mockPipeline.BrowserClient.GetAsync(IdentityServerPipeline.EndSessionEndpoint);
|
||||
await _mockPipeline.BrowserClient.GetAsync(IdentityServerPipeline.EndSessionEndpoint, _ct);
|
||||
|
||||
_mockPipeline.BackChannelMessageHandler.InvokeWasCalled.ShouldBeTrue();
|
||||
}
|
||||
|
|
@ -709,7 +708,7 @@ public class EndSessionTests
|
|||
nonce: "123_nonce");
|
||||
response.ShouldNotBeNull();
|
||||
|
||||
await _mockPipeline.BrowserClient.GetAsync(IdentityServerPipeline.EndSessionEndpoint);
|
||||
await _mockPipeline.BrowserClient.GetAsync(IdentityServerPipeline.EndSessionEndpoint, _ct);
|
||||
|
||||
_mockPipeline.BackChannelMessageHandler.InvokeWasCalled.ShouldBeTrue();
|
||||
}
|
||||
|
|
@ -734,7 +733,7 @@ public class EndSessionTests
|
|||
nonce: "123_nonce");
|
||||
response.ShouldNotBeNull();
|
||||
|
||||
await _mockPipeline.BrowserClient.GetAsync(IdentityServerPipeline.EndSessionEndpoint);
|
||||
await _mockPipeline.BrowserClient.GetAsync(IdentityServerPipeline.EndSessionEndpoint, _ct);
|
||||
|
||||
_mockPipeline.BackChannelMessageHandler.InvokeWasCalled.ShouldBeTrue();
|
||||
}
|
||||
|
|
@ -759,7 +758,7 @@ public class EndSessionTests
|
|||
nonce: "123_nonce");
|
||||
response.ShouldNotBeNull();
|
||||
|
||||
await _mockPipeline.BrowserClient.GetAsync(IdentityServerPipeline.EndSessionEndpoint);
|
||||
await _mockPipeline.BrowserClient.GetAsync(IdentityServerPipeline.EndSessionEndpoint, _ct);
|
||||
|
||||
_mockPipeline.BackChannelMessageHandler.InvokeWasCalled.ShouldBeTrue();
|
||||
}
|
||||
|
|
@ -782,7 +781,7 @@ public class EndSessionTests
|
|||
nonce: "123_nonce");
|
||||
response.ShouldNotBeNull();
|
||||
|
||||
await _mockPipeline.BrowserClient.GetAsync(IdentityServerPipeline.EndSessionEndpoint);
|
||||
await _mockPipeline.BrowserClient.GetAsync(IdentityServerPipeline.EndSessionEndpoint, _ct);
|
||||
|
||||
_mockPipeline.BackChannelMessageHandler.InvokeWasCalled.ShouldBeTrue();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ public class IntrospectionTests
|
|||
private const string IntrospectionEndpoint = "https://server/connect/introspect";
|
||||
private const string TokenEndpoint = "https://server/connect/token";
|
||||
private const string RevocationEndpoint = "https://server/connect/revocation";
|
||||
|
||||
private readonly CancellationToken _ct = TestContext.Current.CancellationToken;
|
||||
private readonly HttpClient _client;
|
||||
private readonly HttpMessageHandler _handler;
|
||||
|
||||
|
|
@ -49,7 +49,7 @@ public class IntrospectionTests
|
|||
{
|
||||
var form = new Dictionary<string, string>();
|
||||
|
||||
var response = await _client.PostAsync(IntrospectionEndpoint, new FormUrlEncodedContent(form));
|
||||
var response = await _client.PostAsync(IntrospectionEndpoint, new FormUrlEncodedContent(form), _ct);
|
||||
|
||||
response.StatusCode.ShouldBe(HttpStatusCode.Unauthorized);
|
||||
}
|
||||
|
|
@ -61,7 +61,7 @@ public class IntrospectionTests
|
|||
var form = new Dictionary<string, string>();
|
||||
|
||||
_client.SetBasicAuthentication("unknown", "invalid");
|
||||
var response = await _client.PostAsync(IntrospectionEndpoint, new FormUrlEncodedContent(form));
|
||||
var response = await _client.PostAsync(IntrospectionEndpoint, new FormUrlEncodedContent(form), _ct);
|
||||
|
||||
response.StatusCode.ShouldBe(HttpStatusCode.Unauthorized);
|
||||
}
|
||||
|
|
@ -73,7 +73,7 @@ public class IntrospectionTests
|
|||
var form = new Dictionary<string, string>();
|
||||
|
||||
_client.SetBasicAuthentication("api1", "invalid");
|
||||
var response = await _client.PostAsync(IntrospectionEndpoint, new FormUrlEncodedContent(form));
|
||||
var response = await _client.PostAsync(IntrospectionEndpoint, new FormUrlEncodedContent(form), _ct);
|
||||
|
||||
response.StatusCode.ShouldBe(HttpStatusCode.Unauthorized);
|
||||
}
|
||||
|
|
@ -85,7 +85,7 @@ public class IntrospectionTests
|
|||
var form = new Dictionary<string, string>();
|
||||
|
||||
_client.SetBasicAuthentication("api1", "secret");
|
||||
var response = await _client.PostAsync(IntrospectionEndpoint, new FormUrlEncodedContent(form));
|
||||
var response = await _client.PostAsync(IntrospectionEndpoint, new FormUrlEncodedContent(form), _ct);
|
||||
|
||||
response.StatusCode.ShouldBe(HttpStatusCode.BadRequest);
|
||||
}
|
||||
|
|
@ -101,7 +101,7 @@ public class IntrospectionTests
|
|||
ClientSecret = "secret",
|
||||
|
||||
Token = "invalid"
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
introspectionResponse.IsActive.ShouldBe(false);
|
||||
introspectionResponse.IsError.ShouldBe(false);
|
||||
|
|
@ -117,7 +117,7 @@ public class IntrospectionTests
|
|||
ClientId = "client1",
|
||||
ClientSecret = "secret",
|
||||
Scope = "api1"
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
var data = new
|
||||
{
|
||||
|
|
@ -129,7 +129,7 @@ public class IntrospectionTests
|
|||
|
||||
var client = new HttpClient(_handler);
|
||||
var response = await client.PostAsync(IntrospectionEndpoint,
|
||||
new StringContent(json, Encoding.UTF8, "application/json"));
|
||||
new StringContent(json, Encoding.UTF8, "application/json"), _ct);
|
||||
response.StatusCode.ShouldBe(HttpStatusCode.UnsupportedMediaType);
|
||||
}
|
||||
|
||||
|
|
@ -143,7 +143,7 @@ public class IntrospectionTests
|
|||
ClientId = "client1",
|
||||
ClientSecret = "secret",
|
||||
Scope = "api1"
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
var introspectionResponse = await _client.IntrospectTokenAsync(new TokenIntrospectionRequest
|
||||
{
|
||||
|
|
@ -153,7 +153,7 @@ public class IntrospectionTests
|
|||
|
||||
Token = tokenResponse.AccessToken,
|
||||
TokenTypeHint = "invalid"
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
introspectionResponse.IsActive.ShouldBe(true);
|
||||
introspectionResponse.IsError.ShouldBe(false);
|
||||
|
|
@ -176,9 +176,7 @@ public class IntrospectionTests
|
|||
[InlineData("api1", "bogus")]
|
||||
public async Task Access_tokens_can_be_introspected_with_any_hint(string introspectedBy, string hint)
|
||||
{
|
||||
TokenResponse tokenResponse;
|
||||
|
||||
tokenResponse = await _client.RequestPasswordTokenAsync(new PasswordTokenRequest
|
||||
var tokenResponse = await _client.RequestPasswordTokenAsync(new PasswordTokenRequest
|
||||
{
|
||||
Address = TokenEndpoint,
|
||||
ClientId = "ro.client",
|
||||
|
|
@ -186,7 +184,7 @@ public class IntrospectionTests
|
|||
UserName = "bob",
|
||||
Password = "bob",
|
||||
Scope = "api1 offline_access"
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
var introspectionResponse = await _client.IntrospectTokenAsync(new TokenIntrospectionRequest
|
||||
{
|
||||
|
|
@ -196,7 +194,7 @@ public class IntrospectionTests
|
|||
|
||||
Token = tokenResponse.AccessToken,
|
||||
TokenTypeHint = hint
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
introspectionResponse.IsActive.ShouldBe(true);
|
||||
introspectionResponse.IsError.ShouldBe(false);
|
||||
|
|
@ -223,9 +221,7 @@ public class IntrospectionTests
|
|||
public async Task Refresh_tokens_can_be_introspected_by_their_client_with_any_hint(string introspectedBy,
|
||||
string hint, bool isActive)
|
||||
{
|
||||
TokenResponse tokenResponse;
|
||||
|
||||
tokenResponse = await _client.RequestPasswordTokenAsync(new PasswordTokenRequest
|
||||
var tokenResponse = await _client.RequestPasswordTokenAsync(new PasswordTokenRequest
|
||||
{
|
||||
Address = TokenEndpoint,
|
||||
ClientId = "ro.client",
|
||||
|
|
@ -233,7 +229,7 @@ public class IntrospectionTests
|
|||
UserName = "bob",
|
||||
Password = "bob",
|
||||
Scope = "api1 offline_access"
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
var introspectionResponse = await _client.IntrospectTokenAsync(new TokenIntrospectionRequest
|
||||
{
|
||||
|
|
@ -243,7 +239,7 @@ public class IntrospectionTests
|
|||
|
||||
Token = tokenResponse.RefreshToken,
|
||||
TokenTypeHint = hint
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
if (isActive)
|
||||
{
|
||||
|
|
@ -274,7 +270,7 @@ public class IntrospectionTests
|
|||
ClientId = "client1",
|
||||
ClientSecret = "secret",
|
||||
Scope = "api1"
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
var introspectionResponse = await _client.IntrospectTokenAsync(new TokenIntrospectionRequest
|
||||
{
|
||||
|
|
@ -283,7 +279,7 @@ public class IntrospectionTests
|
|||
ClientSecret = "secret",
|
||||
|
||||
Token = tokenResponse.AccessToken
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
introspectionResponse.IsActive.ShouldBe(true);
|
||||
introspectionResponse.IsError.ShouldBe(false);
|
||||
|
|
@ -306,7 +302,7 @@ public class IntrospectionTests
|
|||
ClientId = "client1",
|
||||
ClientSecret = "secret",
|
||||
Scope = "api1"
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
var introspectionResponse = await _client.IntrospectTokenAsync(new TokenIntrospectionRequest
|
||||
{
|
||||
|
|
@ -315,7 +311,7 @@ public class IntrospectionTests
|
|||
ClientSecret = "secret",
|
||||
|
||||
Token = tokenResponse.AccessToken
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
var values = GetFields(introspectionResponse);
|
||||
|
||||
|
|
@ -344,7 +340,7 @@ public class IntrospectionTests
|
|||
Password = "bob",
|
||||
|
||||
Scope = "api1",
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
tokenResponse.IsError.ShouldBeFalse();
|
||||
|
||||
|
|
@ -355,7 +351,7 @@ public class IntrospectionTests
|
|||
ClientSecret = "secret",
|
||||
|
||||
Token = tokenResponse.AccessToken
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
var values = GetFields(introspectionResponse);
|
||||
|
||||
|
|
@ -382,7 +378,7 @@ public class IntrospectionTests
|
|||
ClientSecret = "secret",
|
||||
|
||||
Scope = "api2 api3-a api3-b",
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
tokenResponse.IsError.ShouldBeFalse();
|
||||
|
||||
|
|
@ -393,7 +389,7 @@ public class IntrospectionTests
|
|||
ClientSecret = "secret",
|
||||
|
||||
Token = tokenResponse.AccessToken
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
var values = GetFields(introspectionResponse);
|
||||
|
||||
|
|
@ -427,7 +423,7 @@ public class IntrospectionTests
|
|||
ClientSecret = "secret",
|
||||
|
||||
Scope = "api3-a api3-b",
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
tokenResponse.IsError.ShouldBeFalse();
|
||||
|
||||
|
|
@ -438,7 +434,7 @@ public class IntrospectionTests
|
|||
ClientSecret = "secret",
|
||||
|
||||
Token = tokenResponse.AccessToken
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
var values = GetFields(introspectionResponse);
|
||||
|
||||
|
|
@ -465,7 +461,7 @@ public class IntrospectionTests
|
|||
ClientSecret = "secret",
|
||||
|
||||
Scope = "api1 api2 api3-a",
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
tokenResponse.IsError.ShouldBeFalse();
|
||||
|
||||
|
|
@ -476,7 +472,7 @@ public class IntrospectionTests
|
|||
ClientSecret = "secret",
|
||||
|
||||
Token = tokenResponse.AccessToken
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
introspectionResponse.IsActive.ShouldBeTrue();
|
||||
introspectionResponse.IsError.ShouldBeFalse();
|
||||
|
|
@ -500,7 +496,7 @@ public class IntrospectionTests
|
|||
ClientSecret = "secret",
|
||||
|
||||
Scope = "api1 api2",
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
var introspectionResponse = await _client.IntrospectTokenAsync(new TokenIntrospectionRequest
|
||||
{
|
||||
|
|
@ -509,7 +505,7 @@ public class IntrospectionTests
|
|||
ClientSecret = "secret",
|
||||
|
||||
Token = tokenResponse.AccessToken
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
introspectionResponse.IsActive.ShouldBe(true);
|
||||
introspectionResponse.IsError.ShouldBe(false);
|
||||
|
|
@ -533,7 +529,7 @@ public class IntrospectionTests
|
|||
ClientSecret = "secret",
|
||||
|
||||
Scope = "api1",
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
var introspectionResponse = await _client.IntrospectTokenAsync(new TokenIntrospectionRequest
|
||||
{
|
||||
|
|
@ -542,7 +538,7 @@ public class IntrospectionTests
|
|||
ClientSecret = "secret",
|
||||
|
||||
Token = tokenResponse.AccessToken
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
introspectionResponse.IsActive.ShouldBe(false);
|
||||
introspectionResponse.IsError.ShouldBe(false);
|
||||
|
|
@ -558,7 +554,7 @@ public class IntrospectionTests
|
|||
ClientId = "client1",
|
||||
ClientSecret = "secret",
|
||||
Scope = "api1"
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
var introspectionResponse = await _client.IntrospectTokenAsync(new TokenIntrospectionRequest
|
||||
{
|
||||
|
|
@ -567,7 +563,7 @@ public class IntrospectionTests
|
|||
ClientSecret = "secret",
|
||||
|
||||
Token = tokenResponse.AccessToken
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
introspectionResponse.IsActive.ShouldBeTrue();
|
||||
introspectionResponse.IsError.ShouldBeFalse();
|
||||
|
|
@ -586,7 +582,7 @@ public class IntrospectionTests
|
|||
UserName = "bob",
|
||||
Password = "bob",
|
||||
Scope = "api1 offline_access"
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
var introspectionResponse = await _client.IntrospectTokenAsync(new TokenIntrospectionRequest
|
||||
{
|
||||
|
|
@ -595,7 +591,7 @@ public class IntrospectionTests
|
|||
ClientSecret = "secret",
|
||||
|
||||
Token = tokenResponse.RefreshToken
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
introspectionResponse.IsActive.ShouldBeTrue();
|
||||
introspectionResponse.IsError.ShouldBeFalse();
|
||||
|
|
@ -617,7 +613,7 @@ public class IntrospectionTests
|
|||
UserName = "bob",
|
||||
Password = "bob",
|
||||
Scope = "api1 offline_access"
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
var introspectionResponse = await _client.IntrospectTokenAsync(new TokenIntrospectionRequest
|
||||
{
|
||||
|
|
@ -626,7 +622,7 @@ public class IntrospectionTests
|
|||
ClientSecret = "secret",
|
||||
|
||||
Token = tokenResponse.RefreshToken
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
introspectionResponse.IsActive.ShouldBeFalse();
|
||||
introspectionResponse.IsError.ShouldBeFalse();
|
||||
|
|
@ -644,7 +640,7 @@ public class IntrospectionTests
|
|||
UserName = "bob",
|
||||
Password = "bob",
|
||||
Scope = "api1 offline_access"
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
var revocationResponse = await _client.RevokeTokenAsync(new TokenRevocationRequest
|
||||
{
|
||||
|
|
@ -653,7 +649,7 @@ public class IntrospectionTests
|
|||
ClientSecret = "secret",
|
||||
|
||||
Token = tokenResponse.RefreshToken
|
||||
});
|
||||
}, _ct);
|
||||
revocationResponse.IsError.ShouldBeFalse();
|
||||
|
||||
var introspectionResponse = await _client.IntrospectTokenAsync(new TokenIntrospectionRequest
|
||||
|
|
@ -663,7 +659,7 @@ public class IntrospectionTests
|
|||
ClientSecret = "secret",
|
||||
|
||||
Token = tokenResponse.RefreshToken
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
introspectionResponse.IsActive.ShouldBeFalse();
|
||||
introspectionResponse.IsError.ShouldBeFalse();
|
||||
|
|
@ -679,7 +675,7 @@ public class IntrospectionTests
|
|||
ClientId = "client1",
|
||||
ClientSecret = "secret",
|
||||
Scope = "api1"
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
var introspectionResponse = await _client.IntrospectTokenAsync(new TokenIntrospectionRequest
|
||||
{
|
||||
|
|
@ -688,7 +684,7 @@ public class IntrospectionTests
|
|||
ClientSecret = "secret",
|
||||
|
||||
Token = tokenResponse.AccessToken
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
introspectionResponse.IsActive.ShouldBeFalse();
|
||||
introspectionResponse.IsError.ShouldBeFalse();
|
||||
|
|
@ -706,7 +702,7 @@ public class IntrospectionTests
|
|||
UserName = "bob",
|
||||
Password = "bob",
|
||||
Scope = "api1 offline_access"
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
var introspectionResponse = await _client.IntrospectTokenAsync(new TokenIntrospectionRequest
|
||||
{
|
||||
|
|
@ -715,7 +711,7 @@ public class IntrospectionTests
|
|||
ClientSecret = "secret",
|
||||
|
||||
Token = tokenResponse.RefreshToken
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
introspectionResponse.IsActive.ShouldBeFalse();
|
||||
introspectionResponse.IsError.ShouldBeFalse();
|
||||
|
|
@ -733,7 +729,7 @@ public class IntrospectionTests
|
|||
UserName = "bob",
|
||||
Password = "bob",
|
||||
Scope = "api1 offline_access"
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
var introspectionResponse = await _client.IntrospectTokenAsync(new TokenIntrospectionRequest
|
||||
{
|
||||
|
|
@ -744,7 +740,7 @@ public class IntrospectionTests
|
|||
Token = tokenResponse.AccessToken,
|
||||
TokenTypeHint = Constants.TokenTypeHints.AccessToken,
|
||||
ResponseFormat = ResponseFormat.Jwt
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
introspectionResponse.HttpResponse.Content.Headers.ContentType.MediaType.ShouldBe($"application/{JwtClaimTypes.JwtTypes.IntrospectionJwtResponse}");
|
||||
}
|
||||
|
|
@ -761,7 +757,7 @@ public class IntrospectionTests
|
|||
UserName = "bob",
|
||||
Password = "bob",
|
||||
Scope = "api1 offline_access"
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
var introspectionResponse = await _client.IntrospectTokenAsync(new TokenIntrospectionRequest
|
||||
{
|
||||
|
|
@ -772,7 +768,7 @@ public class IntrospectionTests
|
|||
Token = tokenResponse.AccessToken,
|
||||
TokenTypeHint = Constants.TokenTypeHints.AccessToken,
|
||||
ResponseFormat = ResponseFormat.Jwt
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
var handler = new JwtSecurityTokenHandler();
|
||||
var jwt = handler.ReadJwtToken(introspectionResponse.Raw);
|
||||
|
|
@ -804,7 +800,7 @@ public class IntrospectionTests
|
|||
UserName = "bob",
|
||||
Password = "bob",
|
||||
Scope = "api1 offline_access"
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
var revocationResponse = await _client.RevokeTokenAsync(new TokenRevocationRequest
|
||||
{
|
||||
|
|
@ -813,7 +809,7 @@ public class IntrospectionTests
|
|||
ClientSecret = "secret",
|
||||
|
||||
Token = tokenResponse.RefreshToken
|
||||
});
|
||||
}, _ct);
|
||||
revocationResponse.IsError.ShouldBeFalse();
|
||||
|
||||
var introspectionResponse = await _client.IntrospectTokenAsync(new TokenIntrospectionRequest
|
||||
|
|
@ -825,7 +821,7 @@ public class IntrospectionTests
|
|||
Token = tokenResponse.AccessToken,
|
||||
TokenTypeHint = Constants.TokenTypeHints.AccessToken,
|
||||
ResponseFormat = ResponseFormat.Jwt
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
var handler = new JwtSecurityTokenHandler();
|
||||
var jwt = handler.ReadJwtToken(introspectionResponse.Raw);
|
||||
|
|
@ -850,7 +846,7 @@ public class IntrospectionTests
|
|||
|
||||
Token = "invalid",
|
||||
ResponseFormat = ResponseFormat.Jwt
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
var handler = new JwtSecurityTokenHandler();
|
||||
var jwt = handler.ReadJwtToken(introspectionResponse.Raw);
|
||||
|
|
@ -876,7 +872,7 @@ public class IntrospectionTests
|
|||
Scope = "api1 offline_access roles address",
|
||||
UserName = "bob",
|
||||
Password = "bob"
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
var introspectionResponse = await _client.IntrospectTokenAsync(new TokenIntrospectionRequest
|
||||
{
|
||||
|
|
@ -887,7 +883,7 @@ public class IntrospectionTests
|
|||
Token = tokenResponse.AccessToken,
|
||||
TokenTypeHint = Constants.TokenTypeHints.AccessToken,
|
||||
ResponseFormat = ResponseFormat.Jwt
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
introspectionResponse.Json.ShouldNotBeNull();
|
||||
var addressClaim = introspectionResponse.Json.Value.TryGetString("address");
|
||||
|
|
@ -907,7 +903,7 @@ public class IntrospectionTests
|
|||
Scope = "api1 offline_access roles",
|
||||
UserName = "bob",
|
||||
Password = "bob"
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
var introspectionResponse = await _client.IntrospectTokenAsync(new TokenIntrospectionRequest
|
||||
{
|
||||
|
|
@ -918,7 +914,7 @@ public class IntrospectionTests
|
|||
Token = tokenResponse.AccessToken,
|
||||
TokenTypeHint = Constants.TokenTypeHints.AccessToken,
|
||||
ResponseFormat = ResponseFormat.Jwt
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
introspectionResponse.Json.ShouldNotBeNull();
|
||||
var rolesClaim = introspectionResponse.Json.Value.TryGetStringArray("role").ToList();
|
||||
|
|
@ -939,7 +935,7 @@ public class IntrospectionTests
|
|||
ClientId = "client1",
|
||||
ClientSecret = "secret",
|
||||
Scope = "api1"
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
var introspectionResponse = await _client.IntrospectTokenAsync(new TokenIntrospectionRequest
|
||||
{
|
||||
|
|
@ -948,7 +944,7 @@ public class IntrospectionTests
|
|||
ClientSecret = "secret",
|
||||
|
||||
Token = tokenResponse.AccessToken
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
introspectionResponse.IsActive.ShouldBe(true);
|
||||
introspectionResponse.IsError.ShouldBe(false);
|
||||
|
|
@ -971,7 +967,7 @@ public class IntrospectionTests
|
|||
ClientSecret = "secret",
|
||||
|
||||
Token = "invalid"
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
introspectionResponse.IsActive.ShouldBe(false);
|
||||
introspectionResponse.IsError.ShouldBe(false);
|
||||
|
|
@ -993,8 +989,8 @@ public class IntrospectionTests
|
|||
{ "client_secret", "secret" },
|
||||
{ "token", "" }
|
||||
});
|
||||
var rawIntrospectionResponse = await _client.PostAsync(IntrospectionEndpoint, requestContent);
|
||||
var introspectionResponse = await rawIntrospectionResponse.Content.ReadFromJsonAsync<TokenIntrospectionResponse>();
|
||||
var rawIntrospectionResponse = await _client.PostAsync(IntrospectionEndpoint, requestContent, _ct);
|
||||
var introspectionResponse = await rawIntrospectionResponse.Content.ReadFromJsonAsync<TokenIntrospectionResponse>(_ct);
|
||||
|
||||
introspectionResponse.IsActive.ShouldBe(false);
|
||||
introspectionResponse.IsError.ShouldBe(false);
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ namespace Duende.IdentityServer.IntegrationTests.Endpoints.OAuthMetadata;
|
|||
public class OAuthMetadataTests
|
||||
{
|
||||
private const string Category = "OAuth Metadata endpoint";
|
||||
private readonly CancellationToken _ct = TestContext.Current.CancellationToken;
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", Category)]
|
||||
|
|
@ -21,7 +22,7 @@ public class OAuthMetadataTests
|
|||
var pipeline = new IdentityServerPipeline();
|
||||
pipeline.Initialize();
|
||||
|
||||
var result = await pipeline.BackChannelClient.PostAsync("https://server/.well-known/oauth-authorization-server", null);
|
||||
var result = await pipeline.BackChannelClient.PostAsync("https://server/.well-known/oauth-authorization-server", null, _ct);
|
||||
|
||||
result.StatusCode.ShouldBe(HttpStatusCode.MethodNotAllowed);
|
||||
}
|
||||
|
|
@ -33,9 +34,9 @@ public class OAuthMetadataTests
|
|||
var pipeline = new IdentityServerPipeline();
|
||||
pipeline.Initialize();
|
||||
|
||||
var result = await pipeline.BackChannelClient.GetAsync("https://server/.well-known/oauth-authorization-server");
|
||||
var result = await pipeline.BackChannelClient.GetAsync("https://server/.well-known/oauth-authorization-server", _ct);
|
||||
|
||||
var json = await result.Content.ReadAsStringAsync();
|
||||
var json = await result.Content.ReadAsStringAsync(_ct);
|
||||
var data = JsonSerializer.Deserialize<Dictionary<string, JsonElement>>(json);
|
||||
data["issuer"].GetString().ShouldBe("https://server");
|
||||
}
|
||||
|
|
@ -49,9 +50,9 @@ public class OAuthMetadataTests
|
|||
pipeline.Initialize();
|
||||
pipeline.Options.IssuerUri = "https://server/identity";
|
||||
|
||||
var result = await pipeline.BackChannelClient.GetAsync("https://server/.well-known/oauth-authorization-server/identity");
|
||||
var result = await pipeline.BackChannelClient.GetAsync("https://server/.well-known/oauth-authorization-server/identity", _ct);
|
||||
|
||||
var json = await result.Content.ReadAsStringAsync();
|
||||
var json = await result.Content.ReadAsStringAsync(_ct);
|
||||
var data = JsonSerializer.Deserialize<Dictionary<string, JsonElement>>(json);
|
||||
data["issuer"].GetString().ShouldBe("https://server/identity");
|
||||
}
|
||||
|
|
@ -65,9 +66,9 @@ public class OAuthMetadataTests
|
|||
pipeline.Initialize();
|
||||
pipeline.Options.IssuerUri = "https://server/identity";
|
||||
|
||||
var result = await pipeline.BackChannelClient.GetAsync("https://server/.well-known/oauth-authorization-server/identity?query=string");
|
||||
var result = await pipeline.BackChannelClient.GetAsync("https://server/.well-known/oauth-authorization-server/identity?query=string", _ct);
|
||||
|
||||
var json = await result.Content.ReadAsStringAsync();
|
||||
var json = await result.Content.ReadAsStringAsync(_ct);
|
||||
var data = JsonSerializer.Deserialize<Dictionary<string, JsonElement>>(json);
|
||||
data["issuer"].GetString().ShouldBe("https://server/identity");
|
||||
}
|
||||
|
|
@ -81,9 +82,9 @@ public class OAuthMetadataTests
|
|||
pipeline.Initialize();
|
||||
pipeline.Options.IssuerUri = "https://server/identity";
|
||||
|
||||
var result = await pipeline.BackChannelClient.GetAsync("https://server/.well-known/oauth-authorization-server/identity#fragment");
|
||||
var result = await pipeline.BackChannelClient.GetAsync("https://server/.well-known/oauth-authorization-server/identity#fragment", _ct);
|
||||
|
||||
var json = await result.Content.ReadAsStringAsync();
|
||||
var json = await result.Content.ReadAsStringAsync(_ct);
|
||||
var data = JsonSerializer.Deserialize<Dictionary<string, JsonElement>>(json);
|
||||
data["issuer"].GetString().ShouldBe("https://server/identity");
|
||||
}
|
||||
|
|
@ -96,9 +97,9 @@ public class OAuthMetadataTests
|
|||
pipeline.Initialize();
|
||||
pipeline.Options.IssuerUri = "https://server/explicit";
|
||||
|
||||
var result = await pipeline.BackChannelClient.GetAsync("https://server/.well-known/oauth-authorization-server/explicit");
|
||||
var result = await pipeline.BackChannelClient.GetAsync("https://server/.well-known/oauth-authorization-server/explicit", _ct);
|
||||
|
||||
var json = await result.Content.ReadAsStringAsync();
|
||||
var json = await result.Content.ReadAsStringAsync(_ct);
|
||||
var data = JsonSerializer.Deserialize<Dictionary<string, JsonElement>>(json);
|
||||
data["issuer"].GetString().ShouldBe("https://server/explicit");
|
||||
}
|
||||
|
|
@ -111,7 +112,7 @@ public class OAuthMetadataTests
|
|||
pipeline.Initialize();
|
||||
pipeline.Options.IssuerUri = "https://example.com/explicit";
|
||||
|
||||
var result = await pipeline.BackChannelClient.GetAsync("https://server/.well-known/oauth-authorization-server");
|
||||
var result = await pipeline.BackChannelClient.GetAsync("https://server/.well-known/oauth-authorization-server", _ct);
|
||||
|
||||
result.StatusCode.ShouldBe(HttpStatusCode.NotFound);
|
||||
}
|
||||
|
|
@ -123,7 +124,7 @@ public class OAuthMetadataTests
|
|||
var pipeline = new IdentityServerPipeline();
|
||||
pipeline.Initialize("/identity");
|
||||
|
||||
var result = await pipeline.BackChannelClient.GetAsync("https://server/identity/.well-known/oauth-authorization-server");
|
||||
var result = await pipeline.BackChannelClient.GetAsync("https://server/identity/.well-known/oauth-authorization-server", _ct);
|
||||
|
||||
result.StatusCode.ShouldBe(HttpStatusCode.NotFound);
|
||||
}
|
||||
|
|
@ -137,7 +138,7 @@ public class OAuthMetadataTests
|
|||
pipeline.Initialize();
|
||||
pipeline.Options.IssuerUri = "https://server/identity";
|
||||
|
||||
var result = await pipeline.BackChannelClient.GetAsync("https://server/.well-known/oauth-authorization-server/wrong");
|
||||
var result = await pipeline.BackChannelClient.GetAsync("https://server/.well-known/oauth-authorization-server/wrong", _ct);
|
||||
|
||||
result.StatusCode.ShouldBe(HttpStatusCode.NotFound);
|
||||
}
|
||||
|
|
@ -151,9 +152,9 @@ public class OAuthMetadataTests
|
|||
pipeline.Initialize();
|
||||
pipeline.Options.IssuerUri = "https://server/identity";
|
||||
|
||||
var result = await pipeline.BackChannelClient.GetAsync("https://server/.well-known/oauth-authorization-server/identity");
|
||||
var result = await pipeline.BackChannelClient.GetAsync("https://server/.well-known/oauth-authorization-server/identity", _ct);
|
||||
|
||||
var json = await result.Content.ReadAsStringAsync();
|
||||
var json = await result.Content.ReadAsStringAsync(_ct);
|
||||
var data = JsonSerializer.Deserialize<Dictionary<string, JsonElement>>(json);
|
||||
data["issuer"].GetString().ShouldBe("https://server/identity");
|
||||
|
||||
|
|
|
|||
|
|
@ -14,15 +14,13 @@ namespace Duende.IdentityServer.IntegrationTests.Endpoints.Revocation;
|
|||
public class RevocationTests
|
||||
{
|
||||
private const string Category = "RevocationTests endpoint";
|
||||
|
||||
private string client_id = "client";
|
||||
private string client_secret = "secret";
|
||||
private string redirect_uri = "https://client/callback";
|
||||
|
||||
private string scope_name = "api";
|
||||
private string scope_secret = "api_secret";
|
||||
|
||||
private IdentityServerPipeline _mockPipeline = new IdentityServerPipeline();
|
||||
private const string client_id = "client";
|
||||
private const string client_secret = "secret";
|
||||
private const string redirect_uri = "https://client/callback";
|
||||
private const string scope_name = "api";
|
||||
private const string scope_secret = "api_secret";
|
||||
private readonly CancellationToken _ct = TestContext.Current.CancellationToken;
|
||||
private readonly IdentityServerPipeline _mockPipeline = new IdentityServerPipeline();
|
||||
|
||||
public RevocationTests()
|
||||
{
|
||||
|
|
@ -197,7 +195,7 @@ public class RevocationTests
|
|||
[Trait("Category", Category)]
|
||||
public async Task Get_request_should_return_405()
|
||||
{
|
||||
var response = await _mockPipeline.BackChannelClient.GetAsync(IdentityServerPipeline.RevocationEndpoint);
|
||||
var response = await _mockPipeline.BackChannelClient.GetAsync(IdentityServerPipeline.RevocationEndpoint, _ct);
|
||||
|
||||
response.StatusCode.ShouldBe(HttpStatusCode.MethodNotAllowed);
|
||||
}
|
||||
|
|
@ -206,7 +204,7 @@ public class RevocationTests
|
|||
[Trait("Category", Category)]
|
||||
public async Task Post_without_form_urlencoded_should_return_415()
|
||||
{
|
||||
var response = await _mockPipeline.BackChannelClient.PostAsync(IdentityServerPipeline.RevocationEndpoint, null);
|
||||
var response = await _mockPipeline.BackChannelClient.PostAsync(IdentityServerPipeline.RevocationEndpoint, null, _ct);
|
||||
|
||||
response.StatusCode.ShouldBe(HttpStatusCode.UnsupportedMediaType);
|
||||
}
|
||||
|
|
@ -225,7 +223,7 @@ public class RevocationTests
|
|||
ClientSecret = client_secret,
|
||||
|
||||
Token = tokens.AccessToken
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
result.IsError.ShouldBeFalse();
|
||||
(await IsAccessTokenValidAsync(tokens)).ShouldBeFalse();
|
||||
|
|
@ -245,7 +243,7 @@ public class RevocationTests
|
|||
ClientSecret = client_secret,
|
||||
|
||||
Token = tokens.AccessToken
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
result.IsError.ShouldBeFalse();
|
||||
(await IsAccessTokenValidAsync(tokens)).ShouldBeTrue();
|
||||
|
|
@ -265,7 +263,7 @@ public class RevocationTests
|
|||
ClientSecret = client_secret,
|
||||
|
||||
Token = tokens.RefreshToken
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
result.IsError.ShouldBeFalse();
|
||||
|
||||
|
|
@ -286,7 +284,7 @@ public class RevocationTests
|
|||
ClientSecret = client_secret,
|
||||
|
||||
Token = tokens.RefreshToken
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
result.IsError.ShouldBeFalse();
|
||||
|
||||
|
|
@ -311,7 +309,7 @@ public class RevocationTests
|
|||
ClientSecret = client_secret,
|
||||
|
||||
Token = tokens1.RefreshToken
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
result.IsError.ShouldBeFalse();
|
||||
|
||||
|
|
@ -333,7 +331,7 @@ public class RevocationTests
|
|||
ClientSecret = client_secret,
|
||||
|
||||
Token = tokens.AccessToken
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
result.IsError.ShouldBeFalse();
|
||||
|
||||
|
|
@ -346,7 +344,7 @@ public class RevocationTests
|
|||
ClientSecret = client_secret,
|
||||
|
||||
Token = tokens.AccessToken
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
result.IsError.ShouldBeFalse();
|
||||
}
|
||||
|
|
@ -365,7 +363,7 @@ public class RevocationTests
|
|||
ClientSecret = client_secret,
|
||||
|
||||
Token = tokens.RefreshToken
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
result.IsError.ShouldBeFalse();
|
||||
|
||||
|
|
@ -378,7 +376,7 @@ public class RevocationTests
|
|||
ClientSecret = client_secret,
|
||||
|
||||
Token = tokens.RefreshToken
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
result.IsError.ShouldBeFalse();
|
||||
}
|
||||
|
|
@ -397,7 +395,7 @@ public class RevocationTests
|
|||
ClientSecret = client_secret,
|
||||
|
||||
Token = tokens.AccessToken
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
result.IsError.ShouldBeTrue();
|
||||
result.Error.ShouldBe("invalid_client");
|
||||
|
|
@ -417,7 +415,7 @@ public class RevocationTests
|
|||
ClientSecret = "not_valid",
|
||||
|
||||
Token = tokens.AccessToken
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
result.IsError.ShouldBeTrue();
|
||||
result.Error.ShouldBe("invalid_client");
|
||||
|
|
@ -433,7 +431,7 @@ public class RevocationTests
|
|||
{ "client_secret", client_secret }
|
||||
};
|
||||
|
||||
var response = await _mockPipeline.BackChannelClient.PostAsync(IdentityServerPipeline.RevocationEndpoint, new FormUrlEncodedContent(data));
|
||||
var response = await _mockPipeline.BackChannelClient.PostAsync(IdentityServerPipeline.RevocationEndpoint, new FormUrlEncodedContent(data), _ct);
|
||||
response.StatusCode.ShouldBe(HttpStatusCode.BadRequest);
|
||||
|
||||
var result = await ProtocolResponse.FromHttpResponseAsync<TokenRevocationResponse>(response);
|
||||
|
|
@ -456,7 +454,7 @@ public class RevocationTests
|
|||
{ "token_type_hint", "not_valid" }
|
||||
};
|
||||
|
||||
var response = await _mockPipeline.BackChannelClient.PostAsync(IdentityServerPipeline.RevocationEndpoint, new FormUrlEncodedContent(data));
|
||||
var response = await _mockPipeline.BackChannelClient.PostAsync(IdentityServerPipeline.RevocationEndpoint, new FormUrlEncodedContent(data), _ct);
|
||||
response.StatusCode.ShouldBe(HttpStatusCode.BadRequest);
|
||||
|
||||
var result = await ProtocolResponse.FromHttpResponseAsync<TokenRevocationResponse>(response);
|
||||
|
|
@ -478,7 +476,7 @@ public class RevocationTests
|
|||
{ "token", tokens.AccessToken }
|
||||
};
|
||||
|
||||
var response = await _mockPipeline.BackChannelClient.PostAsync(IdentityServerPipeline.RevocationEndpoint, new FormUrlEncodedContent(data));
|
||||
var response = await _mockPipeline.BackChannelClient.PostAsync(IdentityServerPipeline.RevocationEndpoint, new FormUrlEncodedContent(data), _ct);
|
||||
response.StatusCode.ShouldBe(HttpStatusCode.OK);
|
||||
|
||||
(await IsAccessTokenValidAsync(tokens)).ShouldBeFalse();
|
||||
|
|
@ -498,7 +496,7 @@ public class RevocationTests
|
|||
{ "token", tokens.RefreshToken }
|
||||
};
|
||||
|
||||
var response = await _mockPipeline.BackChannelClient.PostAsync(IdentityServerPipeline.RevocationEndpoint, new FormUrlEncodedContent(data));
|
||||
var response = await _mockPipeline.BackChannelClient.PostAsync(IdentityServerPipeline.RevocationEndpoint, new FormUrlEncodedContent(data), _ct);
|
||||
response.StatusCode.ShouldBe(HttpStatusCode.OK);
|
||||
|
||||
(await UseRefreshTokenAsync(tokens)).ShouldBeFalse();
|
||||
|
|
@ -518,7 +516,7 @@ public class RevocationTests
|
|||
|
||||
(await IsAccessTokenValidAsync(token)).ShouldBeTrue();
|
||||
|
||||
var response = await _mockPipeline.BackChannelClient.PostAsync(IdentityServerPipeline.RevocationEndpoint, new FormUrlEncodedContent(data));
|
||||
var response = await _mockPipeline.BackChannelClient.PostAsync(IdentityServerPipeline.RevocationEndpoint, new FormUrlEncodedContent(data), _ct);
|
||||
response.StatusCode.ShouldBe(HttpStatusCode.OK);
|
||||
(await IsAccessTokenValidAsync(token)).ShouldBeFalse();
|
||||
}
|
||||
|
|
@ -537,7 +535,7 @@ public class RevocationTests
|
|||
|
||||
(await IsAccessTokenValidAsync(token)).ShouldBeTrue();
|
||||
|
||||
var response = await _mockPipeline.BackChannelClient.PostAsync(IdentityServerPipeline.RevocationEndpoint, new FormUrlEncodedContent(data));
|
||||
var response = await _mockPipeline.BackChannelClient.PostAsync(IdentityServerPipeline.RevocationEndpoint, new FormUrlEncodedContent(data), _ct);
|
||||
response.StatusCode.ShouldBe(HttpStatusCode.BadRequest);
|
||||
(await IsAccessTokenValidAsync(token)).ShouldBeTrue();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
// Copyright (c) Duende Software. All rights reserved.
|
||||
// See LICENSE in the project root for license information.
|
||||
|
||||
|
||||
using System.Net;
|
||||
using System.Security.Claims;
|
||||
using System.Text.Json;
|
||||
|
|
@ -16,13 +15,14 @@ namespace Duende.IdentityServer.IntegrationTests.Endpoints.Token;
|
|||
|
||||
public class CibaTokenEndpointTests
|
||||
{
|
||||
private readonly CancellationToken _ct = TestContext.Current.CancellationToken;
|
||||
private const string Category = "CIBA Token endpoint";
|
||||
|
||||
private IdentityServerPipeline _mockPipeline = new IdentityServerPipeline();
|
||||
private readonly IdentityServerPipeline _mockPipeline = new IdentityServerPipeline();
|
||||
private MockCibaUserValidator _mockCibaUserValidator = new MockCibaUserValidator();
|
||||
private MockCibaUserNotificationService _mockCibaUserNotificationService = new MockCibaUserNotificationService();
|
||||
|
||||
private TestUser _user;
|
||||
private readonly TestUser _user;
|
||||
private Client _cibaClient;
|
||||
|
||||
public CibaTokenEndpointTests()
|
||||
|
|
@ -138,7 +138,8 @@ public class CibaTokenEndpointTests
|
|||
|
||||
var cibaResponse = await _mockPipeline.BackChannelClient.PostAsync(
|
||||
IdentityServerPipeline.BackchannelAuthenticationEndpoint,
|
||||
new FormUrlEncodedContent(cibaBody));
|
||||
new FormUrlEncodedContent(cibaBody),
|
||||
_ct);
|
||||
cibaResponse.StatusCode.ShouldBe(HttpStatusCode.OK);
|
||||
|
||||
|
||||
|
|
@ -158,7 +159,8 @@ public class CibaTokenEndpointTests
|
|||
|
||||
|
||||
// token request
|
||||
var values = JsonSerializer.Deserialize<Dictionary<string, object>>(await cibaResponse.Content.ReadAsStringAsync());
|
||||
var body = await cibaResponse.Content.ReadAsStringAsync(_ct);
|
||||
var values = JsonSerializer.Deserialize<Dictionary<string, object>>(body);
|
||||
var requestId = values["auth_req_id"].ToString();
|
||||
|
||||
var tokenBody = new Dictionary<string, string>
|
||||
|
|
@ -171,7 +173,8 @@ public class CibaTokenEndpointTests
|
|||
|
||||
var tokenResponse = await _mockPipeline.BackChannelClient.PostAsync(
|
||||
IdentityServerPipeline.TokenEndpoint,
|
||||
new FormUrlEncodedContent(tokenBody));
|
||||
new FormUrlEncodedContent(tokenBody),
|
||||
_ct);
|
||||
|
||||
tokenResponse.StatusCode.ShouldBe(HttpStatusCode.OK);
|
||||
}
|
||||
|
|
@ -196,13 +199,14 @@ public class CibaTokenEndpointTests
|
|||
|
||||
var cibaResponse = await _mockPipeline.BackChannelClient.PostAsync(
|
||||
IdentityServerPipeline.BackchannelAuthenticationEndpoint,
|
||||
new FormUrlEncodedContent(cibaBody));
|
||||
new FormUrlEncodedContent(cibaBody),
|
||||
_ct);
|
||||
cibaResponse.StatusCode.ShouldBe(HttpStatusCode.OK);
|
||||
|
||||
|
||||
|
||||
// token request
|
||||
var values = JsonSerializer.Deserialize<Dictionary<string, object>>(await cibaResponse.Content.ReadAsStringAsync());
|
||||
var values = JsonSerializer.Deserialize<Dictionary<string, object>>(await cibaResponse.Content.ReadAsStringAsync(_ct));
|
||||
var requestId = values["auth_req_id"].ToString();
|
||||
|
||||
var tokenBody = new Dictionary<string, string>
|
||||
|
|
@ -215,11 +219,12 @@ public class CibaTokenEndpointTests
|
|||
|
||||
var tokenResponse = await _mockPipeline.BackChannelClient.PostAsync(
|
||||
IdentityServerPipeline.TokenEndpoint,
|
||||
new FormUrlEncodedContent(tokenBody));
|
||||
new FormUrlEncodedContent(tokenBody),
|
||||
_ct);
|
||||
|
||||
tokenResponse.StatusCode.ShouldBe(HttpStatusCode.BadRequest);
|
||||
|
||||
var json = await tokenResponse.Content.ReadAsStringAsync();
|
||||
var json = await tokenResponse.Content.ReadAsStringAsync(_ct);
|
||||
values = JsonSerializer.Deserialize<Dictionary<string, object>>(json);
|
||||
|
||||
values.ContainsKey("error").ShouldBeTrue();
|
||||
|
|
@ -245,7 +250,8 @@ public class CibaTokenEndpointTests
|
|||
|
||||
var cibaResponse = await _mockPipeline.BackChannelClient.PostAsync(
|
||||
IdentityServerPipeline.BackchannelAuthenticationEndpoint,
|
||||
new FormUrlEncodedContent(cibaBody));
|
||||
new FormUrlEncodedContent(cibaBody),
|
||||
_ct);
|
||||
cibaResponse.StatusCode.ShouldBe(HttpStatusCode.OK);
|
||||
|
||||
|
||||
|
|
@ -265,7 +271,7 @@ public class CibaTokenEndpointTests
|
|||
|
||||
|
||||
// token request
|
||||
var values = JsonSerializer.Deserialize<Dictionary<string, object>>(await cibaResponse.Content.ReadAsStringAsync());
|
||||
var values = JsonSerializer.Deserialize<Dictionary<string, object>>(await cibaResponse.Content.ReadAsStringAsync(_ct));
|
||||
var requestId = values["auth_req_id"].ToString();
|
||||
|
||||
var tokenBody = new Dictionary<string, string>
|
||||
|
|
@ -278,11 +284,12 @@ public class CibaTokenEndpointTests
|
|||
|
||||
var tokenResponse = await _mockPipeline.BackChannelClient.PostAsync(
|
||||
IdentityServerPipeline.TokenEndpoint,
|
||||
new FormUrlEncodedContent(tokenBody));
|
||||
new FormUrlEncodedContent(tokenBody),
|
||||
_ct);
|
||||
|
||||
tokenResponse.StatusCode.ShouldBe(HttpStatusCode.BadRequest);
|
||||
|
||||
var json = await tokenResponse.Content.ReadAsStringAsync();
|
||||
var json = await tokenResponse.Content.ReadAsStringAsync(_ct);
|
||||
values = JsonSerializer.Deserialize<Dictionary<string, object>>(json);
|
||||
|
||||
values.ContainsKey("error").ShouldBeTrue();
|
||||
|
|
@ -308,7 +315,8 @@ public class CibaTokenEndpointTests
|
|||
|
||||
var cibaResponse = await _mockPipeline.BackChannelClient.PostAsync(
|
||||
IdentityServerPipeline.BackchannelAuthenticationEndpoint,
|
||||
new FormUrlEncodedContent(cibaBody));
|
||||
new FormUrlEncodedContent(cibaBody),
|
||||
_ct);
|
||||
cibaResponse.StatusCode.ShouldBe(HttpStatusCode.OK);
|
||||
|
||||
|
||||
|
|
@ -328,7 +336,8 @@ public class CibaTokenEndpointTests
|
|||
|
||||
|
||||
// token request
|
||||
var values = JsonSerializer.Deserialize<Dictionary<string, object>>(await cibaResponse.Content.ReadAsStringAsync());
|
||||
var body = await cibaResponse.Content.ReadAsStringAsync(_ct);
|
||||
var values = JsonSerializer.Deserialize<Dictionary<string, object>>(body);
|
||||
var requestId = values["auth_req_id"].ToString();
|
||||
|
||||
var tokenBody = new Dictionary<string, string>
|
||||
|
|
@ -341,11 +350,12 @@ public class CibaTokenEndpointTests
|
|||
|
||||
var tokenResponse = await _mockPipeline.BackChannelClient.PostAsync(
|
||||
IdentityServerPipeline.TokenEndpoint,
|
||||
new FormUrlEncodedContent(tokenBody));
|
||||
new FormUrlEncodedContent(tokenBody),
|
||||
_ct);
|
||||
|
||||
tokenResponse.StatusCode.ShouldBe(HttpStatusCode.BadRequest);
|
||||
|
||||
var json = await tokenResponse.Content.ReadAsStringAsync();
|
||||
var json = await tokenResponse.Content.ReadAsStringAsync(_ct);
|
||||
values = JsonSerializer.Deserialize<Dictionary<string, object>>(json);
|
||||
|
||||
values.ContainsKey("error").ShouldBeTrue();
|
||||
|
|
@ -371,7 +381,8 @@ public class CibaTokenEndpointTests
|
|||
|
||||
var cibaResponse = await _mockPipeline.BackChannelClient.PostAsync(
|
||||
IdentityServerPipeline.BackchannelAuthenticationEndpoint,
|
||||
new FormUrlEncodedContent(cibaBody));
|
||||
new FormUrlEncodedContent(cibaBody),
|
||||
_ct);
|
||||
cibaResponse.StatusCode.ShouldBe(HttpStatusCode.OK);
|
||||
|
||||
|
||||
|
|
@ -391,7 +402,8 @@ public class CibaTokenEndpointTests
|
|||
|
||||
|
||||
// token request
|
||||
var values = JsonSerializer.Deserialize<Dictionary<string, object>>(await cibaResponse.Content.ReadAsStringAsync());
|
||||
var body = await cibaResponse.Content.ReadAsStringAsync(_ct);
|
||||
var values = JsonSerializer.Deserialize<Dictionary<string, object>>(body);
|
||||
var requestId = values["auth_req_id"].ToString();
|
||||
|
||||
var tokenBody = new Dictionary<string, string>
|
||||
|
|
@ -404,11 +416,12 @@ public class CibaTokenEndpointTests
|
|||
|
||||
var tokenResponse = await _mockPipeline.BackChannelClient.PostAsync(
|
||||
IdentityServerPipeline.TokenEndpoint,
|
||||
new FormUrlEncodedContent(tokenBody));
|
||||
new FormUrlEncodedContent(tokenBody),
|
||||
_ct);
|
||||
|
||||
tokenResponse.StatusCode.ShouldBe(HttpStatusCode.BadRequest);
|
||||
|
||||
var json = await tokenResponse.Content.ReadAsStringAsync();
|
||||
var json = await tokenResponse.Content.ReadAsStringAsync(_ct);
|
||||
values = JsonSerializer.Deserialize<Dictionary<string, object>>(json);
|
||||
|
||||
values.ContainsKey("error").ShouldBeTrue();
|
||||
|
|
@ -434,10 +447,10 @@ public class CibaTokenEndpointTests
|
|||
|
||||
var cibaResponse = await _mockPipeline.BackChannelClient.PostAsync(
|
||||
IdentityServerPipeline.BackchannelAuthenticationEndpoint,
|
||||
new FormUrlEncodedContent(cibaBody));
|
||||
new FormUrlEncodedContent(cibaBody),
|
||||
_ct);
|
||||
cibaResponse.StatusCode.ShouldBe(HttpStatusCode.OK);
|
||||
|
||||
|
||||
// user auth/consent
|
||||
var cibaService = _mockPipeline.Resolve<IBackchannelAuthenticationInteractionService>();
|
||||
var request = await cibaService.GetLoginRequestByInternalIdAsync(_mockCibaUserNotificationService.LoginRequest.InternalId);
|
||||
|
|
@ -456,7 +469,7 @@ public class CibaTokenEndpointTests
|
|||
// token request
|
||||
_user.IsActive = false;
|
||||
|
||||
var values = JsonSerializer.Deserialize<Dictionary<string, object>>(await cibaResponse.Content.ReadAsStringAsync());
|
||||
var values = JsonSerializer.Deserialize<Dictionary<string, object>>(await cibaResponse.Content.ReadAsStringAsync(_ct));
|
||||
var requestId = values["auth_req_id"].ToString();
|
||||
|
||||
var tokenBody = new Dictionary<string, string>
|
||||
|
|
@ -469,11 +482,12 @@ public class CibaTokenEndpointTests
|
|||
|
||||
var tokenResponse = await _mockPipeline.BackChannelClient.PostAsync(
|
||||
IdentityServerPipeline.TokenEndpoint,
|
||||
new FormUrlEncodedContent(tokenBody));
|
||||
new FormUrlEncodedContent(tokenBody),
|
||||
_ct);
|
||||
|
||||
tokenResponse.StatusCode.ShouldBe(HttpStatusCode.BadRequest);
|
||||
|
||||
var json = await tokenResponse.Content.ReadAsStringAsync();
|
||||
var json = await tokenResponse.Content.ReadAsStringAsync(_ct);
|
||||
values = JsonSerializer.Deserialize<Dictionary<string, object>>(json);
|
||||
|
||||
values.ContainsKey("error").ShouldBeTrue();
|
||||
|
|
@ -503,7 +517,8 @@ public class CibaTokenEndpointTests
|
|||
|
||||
var cibaResponse = await _mockPipeline.BackChannelClient.PostAsync(
|
||||
IdentityServerPipeline.BackchannelAuthenticationEndpoint,
|
||||
new FormUrlEncodedContent(cibaBody));
|
||||
new FormUrlEncodedContent(cibaBody),
|
||||
_ct);
|
||||
cibaResponse.StatusCode.ShouldBe(HttpStatusCode.OK);
|
||||
|
||||
|
||||
|
|
@ -525,7 +540,8 @@ public class CibaTokenEndpointTests
|
|||
// token request
|
||||
clock.UtcNow = DateTimeOffset.UtcNow.AddHours(1);
|
||||
|
||||
var values = JsonSerializer.Deserialize<Dictionary<string, object>>(await cibaResponse.Content.ReadAsStringAsync());
|
||||
var body = await cibaResponse.Content.ReadAsStringAsync(_ct);
|
||||
var values = JsonSerializer.Deserialize<Dictionary<string, object>>(body);
|
||||
var requestId = values["auth_req_id"].ToString();
|
||||
|
||||
var tokenBody = new Dictionary<string, string>
|
||||
|
|
@ -538,11 +554,12 @@ public class CibaTokenEndpointTests
|
|||
|
||||
var tokenResponse = await _mockPipeline.BackChannelClient.PostAsync(
|
||||
IdentityServerPipeline.TokenEndpoint,
|
||||
new FormUrlEncodedContent(tokenBody));
|
||||
new FormUrlEncodedContent(tokenBody),
|
||||
_ct);
|
||||
|
||||
tokenResponse.StatusCode.ShouldBe(HttpStatusCode.BadRequest);
|
||||
|
||||
var json = await tokenResponse.Content.ReadAsStringAsync();
|
||||
var json = await tokenResponse.Content.ReadAsStringAsync(_ct);
|
||||
values = JsonSerializer.Deserialize<Dictionary<string, object>>(json);
|
||||
|
||||
values.ContainsKey("error").ShouldBeTrue();
|
||||
|
|
@ -572,12 +589,13 @@ public class CibaTokenEndpointTests
|
|||
|
||||
var cibaResponse = await _mockPipeline.BackChannelClient.PostAsync(
|
||||
IdentityServerPipeline.BackchannelAuthenticationEndpoint,
|
||||
new FormUrlEncodedContent(cibaBody));
|
||||
new FormUrlEncodedContent(cibaBody),
|
||||
_ct);
|
||||
cibaResponse.StatusCode.ShouldBe(HttpStatusCode.OK);
|
||||
|
||||
|
||||
// token request
|
||||
var values = JsonSerializer.Deserialize<Dictionary<string, object>>(await cibaResponse.Content.ReadAsStringAsync());
|
||||
var values = JsonSerializer.Deserialize<Dictionary<string, object>>(await cibaResponse.Content.ReadAsStringAsync(_ct));
|
||||
var requestId = values["auth_req_id"].ToString();
|
||||
|
||||
{
|
||||
|
|
@ -591,11 +609,12 @@ public class CibaTokenEndpointTests
|
|||
|
||||
var tokenResponse = await _mockPipeline.BackChannelClient.PostAsync(
|
||||
IdentityServerPipeline.TokenEndpoint,
|
||||
new FormUrlEncodedContent(tokenBody));
|
||||
new FormUrlEncodedContent(tokenBody),
|
||||
_ct);
|
||||
|
||||
tokenResponse.StatusCode.ShouldBe(HttpStatusCode.BadRequest);
|
||||
|
||||
var json = await tokenResponse.Content.ReadAsStringAsync();
|
||||
var json = await tokenResponse.Content.ReadAsStringAsync(_ct);
|
||||
values = JsonSerializer.Deserialize<Dictionary<string, object>>(json);
|
||||
|
||||
values.ContainsKey("error").ShouldBeTrue();
|
||||
|
|
@ -612,11 +631,12 @@ public class CibaTokenEndpointTests
|
|||
|
||||
var tokenResponse = await _mockPipeline.BackChannelClient.PostAsync(
|
||||
IdentityServerPipeline.TokenEndpoint,
|
||||
new FormUrlEncodedContent(tokenBody));
|
||||
new FormUrlEncodedContent(tokenBody),
|
||||
_ct);
|
||||
|
||||
tokenResponse.StatusCode.ShouldBe(HttpStatusCode.BadRequest);
|
||||
|
||||
var json = await tokenResponse.Content.ReadAsStringAsync();
|
||||
var json = await tokenResponse.Content.ReadAsStringAsync(_ct);
|
||||
values = JsonSerializer.Deserialize<Dictionary<string, object>>(json);
|
||||
|
||||
values.ContainsKey("error").ShouldBeTrue();
|
||||
|
|
@ -647,12 +667,14 @@ public class CibaTokenEndpointTests
|
|||
|
||||
var cibaResponse = await _mockPipeline.BackChannelClient.PostAsync(
|
||||
IdentityServerPipeline.BackchannelAuthenticationEndpoint,
|
||||
new FormUrlEncodedContent(cibaBody));
|
||||
new FormUrlEncodedContent(cibaBody),
|
||||
_ct);
|
||||
cibaResponse.StatusCode.ShouldBe(HttpStatusCode.OK);
|
||||
|
||||
|
||||
// token request
|
||||
var values = JsonSerializer.Deserialize<Dictionary<string, object>>(await cibaResponse.Content.ReadAsStringAsync());
|
||||
var body = await cibaResponse.Content.ReadAsStringAsync(_ct);
|
||||
var values = JsonSerializer.Deserialize<Dictionary<string, object>>(body);
|
||||
var requestId = values["auth_req_id"].ToString();
|
||||
|
||||
{
|
||||
|
|
@ -666,11 +688,12 @@ public class CibaTokenEndpointTests
|
|||
|
||||
var tokenResponse = await _mockPipeline.BackChannelClient.PostAsync(
|
||||
IdentityServerPipeline.TokenEndpoint,
|
||||
new FormUrlEncodedContent(tokenBody));
|
||||
new FormUrlEncodedContent(tokenBody),
|
||||
_ct);
|
||||
|
||||
tokenResponse.StatusCode.ShouldBe(HttpStatusCode.BadRequest);
|
||||
|
||||
var json = await tokenResponse.Content.ReadAsStringAsync();
|
||||
var json = await tokenResponse.Content.ReadAsStringAsync(_ct);
|
||||
values = JsonSerializer.Deserialize<Dictionary<string, object>>(json);
|
||||
|
||||
values.ContainsKey("error").ShouldBeTrue();
|
||||
|
|
@ -687,11 +710,11 @@ public class CibaTokenEndpointTests
|
|||
|
||||
var tokenResponse = await _mockPipeline.BackChannelClient.PostAsync(
|
||||
IdentityServerPipeline.TokenEndpoint,
|
||||
new FormUrlEncodedContent(tokenBody));
|
||||
new FormUrlEncodedContent(tokenBody), _ct);
|
||||
|
||||
tokenResponse.StatusCode.ShouldBe(HttpStatusCode.BadRequest);
|
||||
|
||||
var json = await tokenResponse.Content.ReadAsStringAsync();
|
||||
var json = await tokenResponse.Content.ReadAsStringAsync(_ct);
|
||||
values = JsonSerializer.Deserialize<Dictionary<string, object>>(json);
|
||||
|
||||
values.ContainsKey("error").ShouldBeTrue();
|
||||
|
|
@ -711,11 +734,12 @@ public class CibaTokenEndpointTests
|
|||
|
||||
var tokenResponse = await _mockPipeline.BackChannelClient.PostAsync(
|
||||
IdentityServerPipeline.TokenEndpoint,
|
||||
new FormUrlEncodedContent(tokenBody));
|
||||
new FormUrlEncodedContent(tokenBody),
|
||||
_ct);
|
||||
|
||||
tokenResponse.StatusCode.ShouldBe(HttpStatusCode.BadRequest);
|
||||
|
||||
var json = await tokenResponse.Content.ReadAsStringAsync();
|
||||
var json = await tokenResponse.Content.ReadAsStringAsync(_ct);
|
||||
values = JsonSerializer.Deserialize<Dictionary<string, object>>(json);
|
||||
|
||||
values.ContainsKey("error").ShouldBeTrue();
|
||||
|
|
@ -732,11 +756,12 @@ public class CibaTokenEndpointTests
|
|||
|
||||
var tokenResponse = await _mockPipeline.BackChannelClient.PostAsync(
|
||||
IdentityServerPipeline.TokenEndpoint,
|
||||
new FormUrlEncodedContent(tokenBody));
|
||||
new FormUrlEncodedContent(tokenBody),
|
||||
_ct);
|
||||
|
||||
tokenResponse.StatusCode.ShouldBe(HttpStatusCode.BadRequest);
|
||||
|
||||
var json = await tokenResponse.Content.ReadAsStringAsync();
|
||||
var json = await tokenResponse.Content.ReadAsStringAsync(_ct);
|
||||
values = JsonSerializer.Deserialize<Dictionary<string, object>>(json);
|
||||
|
||||
values.ContainsKey("error").ShouldBeTrue();
|
||||
|
|
@ -769,12 +794,13 @@ public class CibaTokenEndpointTests
|
|||
|
||||
var cibaResponse = await _mockPipeline.BackChannelClient.PostAsync(
|
||||
IdentityServerPipeline.BackchannelAuthenticationEndpoint,
|
||||
new FormUrlEncodedContent(cibaBody));
|
||||
new FormUrlEncodedContent(cibaBody),
|
||||
_ct);
|
||||
cibaResponse.StatusCode.ShouldBe(HttpStatusCode.OK);
|
||||
|
||||
|
||||
// token request
|
||||
var values = JsonSerializer.Deserialize<Dictionary<string, object>>(await cibaResponse.Content.ReadAsStringAsync());
|
||||
var values = JsonSerializer.Deserialize<Dictionary<string, object>>(await cibaResponse.Content.ReadAsStringAsync(_ct));
|
||||
var requestId = values["auth_req_id"].ToString();
|
||||
|
||||
{
|
||||
|
|
@ -788,11 +814,12 @@ public class CibaTokenEndpointTests
|
|||
|
||||
var tokenResponse = await _mockPipeline.BackChannelClient.PostAsync(
|
||||
IdentityServerPipeline.TokenEndpoint,
|
||||
new FormUrlEncodedContent(tokenBody));
|
||||
new FormUrlEncodedContent(tokenBody),
|
||||
_ct);
|
||||
|
||||
tokenResponse.StatusCode.ShouldBe(HttpStatusCode.BadRequest);
|
||||
|
||||
var json = await tokenResponse.Content.ReadAsStringAsync();
|
||||
var json = await tokenResponse.Content.ReadAsStringAsync(_ct);
|
||||
values = JsonSerializer.Deserialize<Dictionary<string, object>>(json);
|
||||
|
||||
values.ContainsKey("error").ShouldBeTrue();
|
||||
|
|
@ -809,11 +836,12 @@ public class CibaTokenEndpointTests
|
|||
|
||||
var tokenResponse = await _mockPipeline.BackChannelClient.PostAsync(
|
||||
IdentityServerPipeline.TokenEndpoint,
|
||||
new FormUrlEncodedContent(tokenBody));
|
||||
new FormUrlEncodedContent(tokenBody),
|
||||
_ct);
|
||||
|
||||
tokenResponse.StatusCode.ShouldBe(HttpStatusCode.BadRequest);
|
||||
|
||||
var json = await tokenResponse.Content.ReadAsStringAsync();
|
||||
var json = await tokenResponse.Content.ReadAsStringAsync(_ct);
|
||||
values = JsonSerializer.Deserialize<Dictionary<string, object>>(json);
|
||||
|
||||
values.ContainsKey("error").ShouldBeTrue();
|
||||
|
|
@ -833,11 +861,12 @@ public class CibaTokenEndpointTests
|
|||
|
||||
var tokenResponse = await _mockPipeline.BackChannelClient.PostAsync(
|
||||
IdentityServerPipeline.TokenEndpoint,
|
||||
new FormUrlEncodedContent(tokenBody));
|
||||
new FormUrlEncodedContent(tokenBody),
|
||||
_ct);
|
||||
|
||||
tokenResponse.StatusCode.ShouldBe(HttpStatusCode.BadRequest);
|
||||
|
||||
var json = await tokenResponse.Content.ReadAsStringAsync();
|
||||
var json = await tokenResponse.Content.ReadAsStringAsync(_ct);
|
||||
values = JsonSerializer.Deserialize<Dictionary<string, object>>(json);
|
||||
|
||||
values.ContainsKey("error").ShouldBeTrue();
|
||||
|
|
@ -857,11 +886,12 @@ public class CibaTokenEndpointTests
|
|||
|
||||
var tokenResponse = await _mockPipeline.BackChannelClient.PostAsync(
|
||||
IdentityServerPipeline.TokenEndpoint,
|
||||
new FormUrlEncodedContent(tokenBody));
|
||||
new FormUrlEncodedContent(tokenBody),
|
||||
_ct);
|
||||
|
||||
tokenResponse.StatusCode.ShouldBe(HttpStatusCode.BadRequest);
|
||||
|
||||
var json = await tokenResponse.Content.ReadAsStringAsync();
|
||||
var json = await tokenResponse.Content.ReadAsStringAsync(_ct);
|
||||
values = JsonSerializer.Deserialize<Dictionary<string, object>>(json);
|
||||
|
||||
values.ContainsKey("error").ShouldBeTrue();
|
||||
|
|
@ -878,11 +908,12 @@ public class CibaTokenEndpointTests
|
|||
|
||||
var tokenResponse = await _mockPipeline.BackChannelClient.PostAsync(
|
||||
IdentityServerPipeline.TokenEndpoint,
|
||||
new FormUrlEncodedContent(tokenBody));
|
||||
new FormUrlEncodedContent(tokenBody),
|
||||
_ct);
|
||||
|
||||
tokenResponse.StatusCode.ShouldBe(HttpStatusCode.BadRequest);
|
||||
|
||||
var json = await tokenResponse.Content.ReadAsStringAsync();
|
||||
var json = await tokenResponse.Content.ReadAsStringAsync(_ct);
|
||||
values = JsonSerializer.Deserialize<Dictionary<string, object>>(json);
|
||||
|
||||
values.ContainsKey("error").ShouldBeTrue();
|
||||
|
|
@ -915,12 +946,13 @@ public class CibaTokenEndpointTests
|
|||
|
||||
var cibaResponse = await _mockPipeline.BackChannelClient.PostAsync(
|
||||
IdentityServerPipeline.BackchannelAuthenticationEndpoint,
|
||||
new FormUrlEncodedContent(cibaBody));
|
||||
new FormUrlEncodedContent(cibaBody),
|
||||
_ct);
|
||||
cibaResponse.StatusCode.ShouldBe(HttpStatusCode.OK);
|
||||
|
||||
|
||||
// token request
|
||||
var values = JsonSerializer.Deserialize<Dictionary<string, object>>(await cibaResponse.Content.ReadAsStringAsync());
|
||||
var values = JsonSerializer.Deserialize<Dictionary<string, object>>(await cibaResponse.Content.ReadAsStringAsync(_ct));
|
||||
var requestId = values["auth_req_id"].ToString();
|
||||
|
||||
{
|
||||
|
|
@ -934,11 +966,12 @@ public class CibaTokenEndpointTests
|
|||
|
||||
var tokenResponse = await _mockPipeline.BackChannelClient.PostAsync(
|
||||
IdentityServerPipeline.TokenEndpoint,
|
||||
new FormUrlEncodedContent(tokenBody));
|
||||
new FormUrlEncodedContent(tokenBody),
|
||||
_ct);
|
||||
|
||||
tokenResponse.StatusCode.ShouldBe(HttpStatusCode.BadRequest);
|
||||
|
||||
var json = await tokenResponse.Content.ReadAsStringAsync();
|
||||
var json = await tokenResponse.Content.ReadAsStringAsync(_ct);
|
||||
values = JsonSerializer.Deserialize<Dictionary<string, object>>(json);
|
||||
|
||||
values.ContainsKey("error").ShouldBeTrue();
|
||||
|
|
@ -958,11 +991,12 @@ public class CibaTokenEndpointTests
|
|||
|
||||
var tokenResponse = await _mockPipeline.BackChannelClient.PostAsync(
|
||||
IdentityServerPipeline.TokenEndpoint,
|
||||
new FormUrlEncodedContent(tokenBody));
|
||||
new FormUrlEncodedContent(tokenBody),
|
||||
_ct);
|
||||
|
||||
tokenResponse.StatusCode.ShouldBe(HttpStatusCode.BadRequest);
|
||||
|
||||
var json = await tokenResponse.Content.ReadAsStringAsync();
|
||||
var json = await tokenResponse.Content.ReadAsStringAsync(_ct);
|
||||
values = JsonSerializer.Deserialize<Dictionary<string, object>>(json);
|
||||
|
||||
values.ContainsKey("error").ShouldBeTrue();
|
||||
|
|
|
|||
|
|
@ -17,7 +17,8 @@ namespace Duende.IdentityServer.IntegrationTests.Endpoints.Token;
|
|||
/// </summary>
|
||||
public class DPoPPushedAuthorizationEndpointTests : DPoPEndpointTestBase
|
||||
{
|
||||
protected const string Category = "DPoP PAR endpoint";
|
||||
private const string Category = "DPoP PAR endpoint";
|
||||
private readonly CancellationToken _ct = TestContext.Current.CancellationToken;
|
||||
|
||||
private PushedAuthorizationRequest CreatePushedAuthorizationRequest(
|
||||
string proofToken = null, bool omitDPoPProof = false, string dpopKeyThumprint = null
|
||||
|
|
@ -47,7 +48,7 @@ public class DPoPPushedAuthorizationEndpointTests : DPoPEndpointTestBase
|
|||
{
|
||||
Payload.Add("foo", new string('x', 3000));
|
||||
var request = CreatePushedAuthorizationRequest();
|
||||
var response = await Pipeline.BackChannelClient.PushAuthorizationAsync(request);
|
||||
var response = await Pipeline.BackChannelClient.PushAuthorizationAsync(request, _ct);
|
||||
response.IsError.ShouldBeTrue();
|
||||
response.Error.ShouldBe("invalid_dpop_proof");
|
||||
}
|
||||
|
|
@ -61,12 +62,12 @@ public class DPoPPushedAuthorizationEndpointTests : DPoPEndpointTestBase
|
|||
|
||||
// Initial request succeeds
|
||||
var firstRequest = CreatePushedAuthorizationRequest(dpopToken);
|
||||
var firstResponse = await Pipeline.BackChannelClient.PushAuthorizationAsync(firstRequest);
|
||||
var firstResponse = await Pipeline.BackChannelClient.PushAuthorizationAsync(firstRequest, _ct);
|
||||
firstResponse.IsError.ShouldBeFalse();
|
||||
|
||||
// Second request fails
|
||||
var secondRequest = CreatePushedAuthorizationRequest(dpopToken);
|
||||
var secondResponse = await Pipeline.BackChannelClient.PushAuthorizationAsync(secondRequest);
|
||||
var secondResponse = await Pipeline.BackChannelClient.PushAuthorizationAsync(secondRequest, _ct);
|
||||
secondResponse.IsError.ShouldBeTrue();
|
||||
secondResponse.Error.ShouldBe("invalid_dpop_proof");
|
||||
}
|
||||
|
|
@ -76,7 +77,7 @@ public class DPoPPushedAuthorizationEndpointTests : DPoPEndpointTestBase
|
|||
public async Task invalid_dpop_request_should_fail()
|
||||
{
|
||||
var request = CreatePushedAuthorizationRequest(proofToken: "malformed");
|
||||
var response = await Pipeline.BackChannelClient.PushAuthorizationAsync(request);
|
||||
var response = await Pipeline.BackChannelClient.PushAuthorizationAsync(request, _ct);
|
||||
response.IsError.ShouldBeTrue();
|
||||
response.Error.ShouldBe("invalid_dpop_proof");
|
||||
}
|
||||
|
|
@ -89,7 +90,7 @@ public class DPoPPushedAuthorizationEndpointTests : DPoPEndpointTestBase
|
|||
request.Headers.Add("DPoP", dpopToken);
|
||||
request.Headers.Add("DPoP", dpopToken);
|
||||
|
||||
var response = await Pipeline.BackChannelClient.PushAuthorizationAsync(request);
|
||||
var response = await Pipeline.BackChannelClient.PushAuthorizationAsync(request, _ct);
|
||||
|
||||
response.IsError.ShouldBeTrue();
|
||||
response.Error.ShouldBe(OidcConstants.AuthorizeErrors.InvalidRequest);
|
||||
|
|
@ -103,7 +104,7 @@ public class DPoPPushedAuthorizationEndpointTests : DPoPEndpointTestBase
|
|||
oldThumbprint.ShouldNotBe(JKT);
|
||||
var request = CreatePushedAuthorizationRequest(dpopKeyThumprint: oldThumbprint);
|
||||
|
||||
var response = await Pipeline.BackChannelClient.PushAuthorizationAsync(request);
|
||||
var response = await Pipeline.BackChannelClient.PushAuthorizationAsync(request, _ct);
|
||||
|
||||
response.IsError.ShouldBeTrue();
|
||||
response.Error.ShouldBe(OidcConstants.AuthorizeErrors.InvalidRequest);
|
||||
|
|
@ -144,7 +145,7 @@ public class DPoPPushedAuthorizationEndpointTests : DPoPEndpointTestBase
|
|||
tokenClient.DefaultRequestHeaders.Add("DPoP", proofToken);
|
||||
var request = CreatePushedAuthorizationRequest(proofToken);
|
||||
|
||||
var response = await tokenClient.PushAuthorizationAsync(request);
|
||||
var response = await tokenClient.PushAuthorizationAsync(request, _ct);
|
||||
|
||||
response.IsError.ShouldBeFalse();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ namespace Duende.IdentityServer.IntegrationTests.Endpoints.Token;
|
|||
|
||||
public class DPoPTokenEndpointTests : DPoPEndpointTestBase
|
||||
{
|
||||
private readonly CancellationToken _ct = TestContext.Current.CancellationToken;
|
||||
protected const string Category = "DPoP Token endpoint";
|
||||
|
||||
private ClientCredentialsTokenRequest CreateClientCredentialsTokenRequest(
|
||||
|
|
@ -61,7 +62,7 @@ public class DPoPTokenEndpointTests : DPoPEndpointTestBase
|
|||
{
|
||||
var request = CreateClientCredentialsTokenRequest();
|
||||
|
||||
var response = await Pipeline.BackChannelClient.RequestClientCredentialsTokenAsync(request);
|
||||
var response = await Pipeline.BackChannelClient.RequestClientCredentialsTokenAsync(request, _ct);
|
||||
|
||||
response.IsError.ShouldBeFalse();
|
||||
response.TokenType.ShouldBe("DPoP");
|
||||
|
|
@ -78,7 +79,7 @@ public class DPoPTokenEndpointTests : DPoPEndpointTestBase
|
|||
Payload.Add("key_ops", new string[] { "sign", "verify" });
|
||||
var request = CreateClientCredentialsTokenRequest();
|
||||
|
||||
var response = await Pipeline.BackChannelClient.RequestClientCredentialsTokenAsync(request);
|
||||
var response = await Pipeline.BackChannelClient.RequestClientCredentialsTokenAsync(request, _ct);
|
||||
|
||||
response.IsError.ShouldBeFalse();
|
||||
response.TokenType.ShouldBe("DPoP");
|
||||
|
|
@ -93,7 +94,7 @@ public class DPoPTokenEndpointTests : DPoPEndpointTestBase
|
|||
Payload.Add("foo", new string('x', 3000));
|
||||
var request = CreateClientCredentialsTokenRequest();
|
||||
|
||||
var response = await Pipeline.BackChannelClient.RequestClientCredentialsTokenAsync(request);
|
||||
var response = await Pipeline.BackChannelClient.RequestClientCredentialsTokenAsync(request, _ct);
|
||||
|
||||
response.IsError.ShouldBeTrue();
|
||||
}
|
||||
|
|
@ -107,7 +108,7 @@ public class DPoPTokenEndpointTests : DPoPEndpointTestBase
|
|||
|
||||
// Initial request succeeds
|
||||
var firstRequest = CreateClientCredentialsTokenRequest(dpopToken);
|
||||
var firstResponse = await Pipeline.BackChannelClient.RequestClientCredentialsTokenAsync(firstRequest);
|
||||
var firstResponse = await Pipeline.BackChannelClient.RequestClientCredentialsTokenAsync(firstRequest, _ct);
|
||||
firstResponse.IsError.ShouldBeFalse();
|
||||
firstResponse.TokenType.ShouldBe("DPoP");
|
||||
var jkt = GetJKTFromAccessToken(firstResponse);
|
||||
|
|
@ -116,7 +117,7 @@ public class DPoPTokenEndpointTests : DPoPEndpointTestBase
|
|||
// Second request fails
|
||||
var secondRequest = CreateClientCredentialsTokenRequest(dpopToken);
|
||||
secondRequest.Headers.Add("DPoP", dpopToken);
|
||||
var secondResponse = await Pipeline.BackChannelClient.RequestClientCredentialsTokenAsync(secondRequest);
|
||||
var secondResponse = await Pipeline.BackChannelClient.RequestClientCredentialsTokenAsync(secondRequest, _ct);
|
||||
secondResponse.IsError.ShouldBeTrue();
|
||||
}
|
||||
|
||||
|
|
@ -126,7 +127,7 @@ public class DPoPTokenEndpointTests : DPoPEndpointTestBase
|
|||
{
|
||||
var request = CreateClientCredentialsTokenRequest(proofToken: "malformed");
|
||||
|
||||
var response = await Pipeline.BackChannelClient.RequestClientCredentialsTokenAsync(request);
|
||||
var response = await Pipeline.BackChannelClient.RequestClientCredentialsTokenAsync(request, _ct);
|
||||
|
||||
response.IsError.ShouldBeTrue();
|
||||
response.Error.ShouldBe("invalid_dpop_proof");
|
||||
|
|
@ -139,7 +140,7 @@ public class DPoPTokenEndpointTests : DPoPEndpointTestBase
|
|||
ConfidentialClient.RequireDPoP = true;
|
||||
var request = CreateClientCredentialsTokenRequest(omitDPoPProof: true);
|
||||
|
||||
var response = await Pipeline.BackChannelClient.RequestClientCredentialsTokenAsync(request);
|
||||
var response = await Pipeline.BackChannelClient.RequestClientCredentialsTokenAsync(request, _ct);
|
||||
|
||||
response.IsError.ShouldBeTrue();
|
||||
response.Error.ShouldBe("invalid_request");
|
||||
|
|
@ -154,7 +155,7 @@ public class DPoPTokenEndpointTests : DPoPEndpointTestBase
|
|||
request.Headers.Add("DPoP", dpopToken);
|
||||
request.Headers.Add("DPoP", dpopToken);
|
||||
|
||||
var response = await Pipeline.BackChannelClient.RequestClientCredentialsTokenAsync(request);
|
||||
var response = await Pipeline.BackChannelClient.RequestClientCredentialsTokenAsync(request, _ct);
|
||||
|
||||
response.IsError.ShouldBeTrue();
|
||||
response.Error.ShouldBe("invalid_request");
|
||||
|
|
@ -166,11 +167,11 @@ public class DPoPTokenEndpointTests : DPoPEndpointTestBase
|
|||
public async Task valid_dpop_request_should_return_bound_refresh_token(ParMode parMode)
|
||||
{
|
||||
var codeRequest = await CreateAuthCodeTokenRequestAsync(parMode: parMode);
|
||||
var codeResponse = await Pipeline.BackChannelClient.RequestAuthorizationCodeTokenAsync(codeRequest);
|
||||
var codeResponse = await Pipeline.BackChannelClient.RequestAuthorizationCodeTokenAsync(codeRequest, _ct);
|
||||
codeResponse.ShouldHaveDPoPThumbprint(JKT);
|
||||
|
||||
var rtRequest = CreateRefreshTokenRequest(codeResponse);
|
||||
var rtResponse = await Pipeline.BackChannelClient.RequestRefreshTokenAsync(rtRequest);
|
||||
var rtResponse = await Pipeline.BackChannelClient.RequestRefreshTokenAsync(rtRequest, _ct);
|
||||
rtResponse.ShouldHaveDPoPThumbprint(JKT);
|
||||
}
|
||||
|
||||
|
|
@ -180,11 +181,11 @@ public class DPoPTokenEndpointTests : DPoPEndpointTestBase
|
|||
public async Task confidential_client_dpop_proof_should_be_required_on_renewal(ParMode parMode)
|
||||
{
|
||||
var codeRequest = await CreateAuthCodeTokenRequestAsync(parMode: parMode);
|
||||
var codeResponse = await Pipeline.BackChannelClient.RequestAuthorizationCodeTokenAsync(codeRequest);
|
||||
var codeResponse = await Pipeline.BackChannelClient.RequestAuthorizationCodeTokenAsync(codeRequest, _ct);
|
||||
codeResponse.ShouldHaveDPoPThumbprint(JKT);
|
||||
|
||||
var rtRequest = CreateRefreshTokenRequest(codeResponse, omitDPoPProof: true);
|
||||
var rtResponse = await Pipeline.BackChannelClient.RequestRefreshTokenAsync(rtRequest);
|
||||
var rtResponse = await Pipeline.BackChannelClient.RequestRefreshTokenAsync(rtRequest, _ct);
|
||||
rtResponse.IsError.ShouldBeTrue();
|
||||
rtResponse.Error.ShouldBe("invalid_request");
|
||||
}
|
||||
|
|
@ -195,11 +196,11 @@ public class DPoPTokenEndpointTests : DPoPEndpointTestBase
|
|||
public async Task public_client_dpop_proof_should_be_required_on_renewal(ParMode parMode)
|
||||
{
|
||||
var codeRequest = await CreateAuthCodeTokenRequestAsync(clientId: "client2", parMode: parMode);
|
||||
var codeResponse = await Pipeline.BackChannelClient.RequestAuthorizationCodeTokenAsync(codeRequest);
|
||||
var codeResponse = await Pipeline.BackChannelClient.RequestAuthorizationCodeTokenAsync(codeRequest, _ct);
|
||||
codeResponse.ShouldHaveDPoPThumbprint(JKT);
|
||||
|
||||
var rtRequest = CreateRefreshTokenRequest(codeResponse, clientId: "client2", omitDPoPProof: true);
|
||||
var rtResponse = await Pipeline.BackChannelClient.RequestRefreshTokenAsync(rtRequest);
|
||||
var rtResponse = await Pipeline.BackChannelClient.RequestRefreshTokenAsync(rtRequest, _ct);
|
||||
rtResponse.IsError.ShouldBeTrue();
|
||||
rtResponse.Error.ShouldBe("invalid_request");
|
||||
}
|
||||
|
|
@ -212,13 +213,13 @@ public class DPoPTokenEndpointTests : DPoPEndpointTestBase
|
|||
{
|
||||
// Initial code flow doesn't use dpop
|
||||
var codeRequest = await CreateAuthCodeTokenRequestAsync(omitDPoPProofAtTokenEndpoint: true, parMode: parMode);
|
||||
var codeResponse = await Pipeline.BackChannelClient.RequestAuthorizationCodeTokenAsync(codeRequest);
|
||||
var codeResponse = await Pipeline.BackChannelClient.RequestAuthorizationCodeTokenAsync(codeRequest, _ct);
|
||||
codeResponse.IsError.ShouldBeFalse();
|
||||
|
||||
// Subsequent refresh token request tries to use dpop
|
||||
var rtRequest = CreateRefreshTokenRequest(codeResponse, omitDPoPProof: false);
|
||||
|
||||
var rtResponse = await Pipeline.BackChannelClient.RequestRefreshTokenAsync(rtRequest);
|
||||
var rtResponse = await Pipeline.BackChannelClient.RequestRefreshTokenAsync(rtRequest, _ct);
|
||||
rtResponse.IsError.ShouldBeTrue();
|
||||
}
|
||||
|
||||
|
|
@ -228,13 +229,13 @@ public class DPoPTokenEndpointTests : DPoPEndpointTestBase
|
|||
public async Task confidential_client_should_be_able_to_use_different_dpop_key_for_refresh_token_request(ParMode parMode)
|
||||
{
|
||||
var codeRequest = await CreateAuthCodeTokenRequestAsync(parMode: parMode);
|
||||
var codeResponse = await Pipeline.BackChannelClient.RequestAuthorizationCodeTokenAsync(codeRequest);
|
||||
var codeResponse = await Pipeline.BackChannelClient.RequestAuthorizationCodeTokenAsync(codeRequest, _ct);
|
||||
codeResponse.ShouldHaveDPoPThumbprint(JKT);
|
||||
|
||||
CreateNewRSAKey();
|
||||
var rtRequest = CreateRefreshTokenRequest(codeResponse);
|
||||
|
||||
var rtResponse = await Pipeline.BackChannelClient.RequestRefreshTokenAsync(rtRequest);
|
||||
var rtResponse = await Pipeline.BackChannelClient.RequestRefreshTokenAsync(rtRequest, _ct);
|
||||
rtResponse.ShouldHaveDPoPThumbprint(JKT);
|
||||
}
|
||||
|
||||
|
|
@ -244,13 +245,13 @@ public class DPoPTokenEndpointTests : DPoPEndpointTestBase
|
|||
public async Task public_client_should_not_be_able_to_use_different_dpop_key_for_refresh_token_request(ParMode parMode)
|
||||
{
|
||||
var codeRequest = await CreateAuthCodeTokenRequestAsync(clientId: "client2", parMode: parMode);
|
||||
var codeResponse = await Pipeline.BackChannelClient.RequestAuthorizationCodeTokenAsync(codeRequest);
|
||||
var codeResponse = await Pipeline.BackChannelClient.RequestAuthorizationCodeTokenAsync(codeRequest, _ct);
|
||||
codeResponse.ShouldHaveDPoPThumbprint(JKT);
|
||||
|
||||
CreateNewRSAKey();
|
||||
var rtRequest = CreateRefreshTokenRequest(codeResponse, clientId: "client2");
|
||||
|
||||
var rtResponse = await Pipeline.BackChannelClient.RequestRefreshTokenAsync(rtRequest);
|
||||
var rtResponse = await Pipeline.BackChannelClient.RequestRefreshTokenAsync(rtRequest, _ct);
|
||||
rtResponse.IsError.ShouldBeTrue();
|
||||
rtResponse.Error.ShouldBe("invalid_dpop_proof");
|
||||
}
|
||||
|
|
@ -261,15 +262,15 @@ public class DPoPTokenEndpointTests : DPoPEndpointTestBase
|
|||
public async Task public_client_using_same_dpop_key_for_refresh_token_request_should_succeed(ParMode parMode)
|
||||
{
|
||||
var codeRequest = await CreateAuthCodeTokenRequestAsync(clientId: "client2", parMode: parMode);
|
||||
var codeResponse = await Pipeline.BackChannelClient.RequestAuthorizationCodeTokenAsync(codeRequest);
|
||||
var codeResponse = await Pipeline.BackChannelClient.RequestAuthorizationCodeTokenAsync(codeRequest, _ct);
|
||||
codeResponse.ShouldHaveDPoPThumbprint(JKT);
|
||||
|
||||
var firstRefreshRequest = CreateRefreshTokenRequest(codeResponse, clientId: "client2");
|
||||
var firstRefreshResponse = await Pipeline.BackChannelClient.RequestRefreshTokenAsync(firstRefreshRequest);
|
||||
var firstRefreshResponse = await Pipeline.BackChannelClient.RequestRefreshTokenAsync(firstRefreshRequest, _ct);
|
||||
firstRefreshResponse.ShouldHaveDPoPThumbprint(JKT);
|
||||
|
||||
var secondRefreshRequest = CreateRefreshTokenRequest(codeResponse, clientId: "client2");
|
||||
var secondRefreshResponse = await Pipeline.BackChannelClient.RequestRefreshTokenAsync(secondRefreshRequest);
|
||||
var secondRefreshResponse = await Pipeline.BackChannelClient.RequestRefreshTokenAsync(secondRefreshRequest, _ct);
|
||||
secondRefreshResponse.ShouldHaveDPoPThumbprint(JKT);
|
||||
}
|
||||
|
||||
|
|
@ -282,11 +283,11 @@ public class DPoPTokenEndpointTests : DPoPEndpointTestBase
|
|||
ConfidentialClient.RequireDPoP = true;
|
||||
|
||||
var codeRequest = await CreateAuthCodeTokenRequestAsync(parMode: parMode);
|
||||
var codeResponse = await Pipeline.BackChannelClient.RequestAuthorizationCodeTokenAsync(codeRequest);
|
||||
var codeResponse = await Pipeline.BackChannelClient.RequestAuthorizationCodeTokenAsync(codeRequest, _ct);
|
||||
codeResponse.ShouldHaveDPoPThumbprint(JKT);
|
||||
|
||||
var rtRequest = CreateRefreshTokenRequest(codeResponse, omitDPoPProof: true);
|
||||
var rtResponse = await Pipeline.BackChannelClient.RequestRefreshTokenAsync(rtRequest);
|
||||
var rtResponse = await Pipeline.BackChannelClient.RequestRefreshTokenAsync(rtRequest, _ct);
|
||||
rtResponse.IsError.ShouldBeTrue();
|
||||
rtResponse.Error.ShouldBe("invalid_request");
|
||||
}
|
||||
|
|
@ -299,7 +300,7 @@ public class DPoPTokenEndpointTests : DPoPEndpointTestBase
|
|||
{
|
||||
ConfidentialClient.AccessTokenType = accessTokenType;
|
||||
var codeRequest = await CreateAuthCodeTokenRequestAsync();
|
||||
var codeResponse = await Pipeline.BackChannelClient.RequestAuthorizationCodeTokenAsync(codeRequest);
|
||||
var codeResponse = await Pipeline.BackChannelClient.RequestAuthorizationCodeTokenAsync(codeRequest, _ct);
|
||||
|
||||
var introspectionRequest = new TokenIntrospectionRequest
|
||||
{
|
||||
|
|
@ -308,7 +309,7 @@ public class DPoPTokenEndpointTests : DPoPEndpointTestBase
|
|||
ClientSecret = "secret",
|
||||
Token = codeResponse.AccessToken,
|
||||
};
|
||||
var introspectionResponse = await Pipeline.BackChannelClient.IntrospectTokenAsync(introspectionRequest);
|
||||
var introspectionResponse = await Pipeline.BackChannelClient.IntrospectTokenAsync(introspectionRequest, _ct);
|
||||
introspectionResponse.IsError.ShouldBeFalse();
|
||||
GetJKTFromCnfClaim(introspectionResponse.Claims).ShouldBe(JKT);
|
||||
}
|
||||
|
|
@ -319,7 +320,7 @@ public class DPoPTokenEndpointTests : DPoPEndpointTestBase
|
|||
{
|
||||
var codeRequest = await CreateAuthCodeTokenRequestAsync(dpopJkt: JKT);
|
||||
|
||||
var codeResponse = await Pipeline.BackChannelClient.RequestAuthorizationCodeTokenAsync(codeRequest);
|
||||
var codeResponse = await Pipeline.BackChannelClient.RequestAuthorizationCodeTokenAsync(codeRequest, _ct);
|
||||
codeResponse.ShouldHaveDPoPThumbprint(JKT);
|
||||
}
|
||||
|
||||
|
|
@ -337,7 +338,7 @@ public class DPoPTokenEndpointTests : DPoPEndpointTestBase
|
|||
{
|
||||
dpop_jkt = new string('x', 101)
|
||||
});
|
||||
await Pipeline.BrowserClient.GetAsync(url);
|
||||
await Pipeline.BrowserClient.GetAsync(url, _ct);
|
||||
|
||||
Pipeline.ErrorWasCalled.ShouldBeTrue();
|
||||
}
|
||||
|
|
@ -356,7 +357,7 @@ public class DPoPTokenEndpointTests : DPoPEndpointTestBase
|
|||
JKT.ShouldNotBe(oldJkt);
|
||||
var codeRequest = await CreateAuthCodeTokenRequestAsync(parMode: parMode, dpopJkt: oldJkt, dpopProof: oldProof);
|
||||
|
||||
var codeResponse = await Pipeline.BackChannelClient.RequestAuthorizationCodeTokenAsync(codeRequest);
|
||||
var codeResponse = await Pipeline.BackChannelClient.RequestAuthorizationCodeTokenAsync(codeRequest, _ct);
|
||||
codeResponse.IsError.ShouldBeTrue();
|
||||
codeResponse.Error.ShouldBe("invalid_dpop_proof");
|
||||
}
|
||||
|
|
@ -386,7 +387,7 @@ public class DPoPTokenEndpointTests : DPoPEndpointTestBase
|
|||
{
|
||||
return;
|
||||
}
|
||||
var codeResponse = await Pipeline.BackChannelClient.RequestAuthorizationCodeTokenAsync(codeRequest);
|
||||
var codeResponse = await Pipeline.BackChannelClient.RequestAuthorizationCodeTokenAsync(codeRequest, _ct);
|
||||
codeResponse.IsError.ShouldBeTrue();
|
||||
codeResponse.Error.ShouldBe(OidcConstants.TokenErrors.UseDPoPNonce);
|
||||
codeResponse.DPoPNonce.ShouldBe(expectedNonce);
|
||||
|
|
@ -428,10 +429,10 @@ public class DPoPTokenEndpointTests : DPoPEndpointTestBase
|
|||
};
|
||||
|
||||
var form = new FormUrlEncodedContent(formParams);
|
||||
var response = await tokenClient.PostAsync(IdentityServerPipeline.TokenMtlsEndpoint, form);
|
||||
var response = await tokenClient.PostAsync(IdentityServerPipeline.TokenMtlsEndpoint, form, _ct);
|
||||
|
||||
response.StatusCode.ShouldBe(HttpStatusCode.OK);
|
||||
var json = await response.Content.ReadAsStringAsync();
|
||||
var json = await response.Content.ReadAsStringAsync(_ct);
|
||||
json.ShouldContain("access_token");
|
||||
json.ShouldContain("\"token_type\":\"DPoP\"");
|
||||
}
|
||||
|
|
@ -485,7 +486,7 @@ public class DPoPTokenEndpointTests : DPoPEndpointTestBase
|
|||
var proofToken = CreateDPoPProofToken(alg);
|
||||
var request = CreateClientCredentialsTokenRequest(proofToken);
|
||||
|
||||
var response = await Pipeline.BackChannelClient.RequestClientCredentialsTokenAsync(request);
|
||||
var response = await Pipeline.BackChannelClient.RequestClientCredentialsTokenAsync(request, _ct);
|
||||
|
||||
response.IsError.ShouldBeFalse();
|
||||
response.TokenType.ShouldBe("DPoP");
|
||||
|
|
@ -533,11 +534,11 @@ public class DPoPTokenEndpointTests : DPoPEndpointTestBase
|
|||
var form = new FormUrlEncodedContent(formParams);
|
||||
tokenClient.DefaultRequestHeaders.Add("DPoP", CreateDPoPProofToken(htu: IdentityServerPipeline.TokenMtlsEndpoint));
|
||||
|
||||
var response = await tokenClient.PostAsync(IdentityServerPipeline.TokenMtlsEndpoint, form);
|
||||
var response = await tokenClient.PostAsync(IdentityServerPipeline.TokenMtlsEndpoint, form, _ct);
|
||||
|
||||
response.StatusCode.ShouldBe(System.Net.HttpStatusCode.OK);
|
||||
|
||||
var json = await response.Content.ReadAsStringAsync();
|
||||
var json = await response.Content.ReadAsStringAsync(_ct);
|
||||
json.ShouldContain("access_token");
|
||||
json.ShouldContain("\"token_type\":\"DPoP\"");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,8 +10,8 @@ namespace Duende.IdentityServer.IntegrationTests.Endpoints.Token;
|
|||
public class MtlsTokenEndpointTests
|
||||
{
|
||||
private const string Category = "mTLS Token endpoint";
|
||||
|
||||
private IdentityServerPipeline _pipeline = new IdentityServerPipeline();
|
||||
private readonly CancellationToken _ct = TestContext.Current.CancellationToken;
|
||||
private readonly IdentityServerPipeline _pipeline = new IdentityServerPipeline();
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", Category)]
|
||||
|
|
@ -57,12 +57,12 @@ public class MtlsTokenEndpointTests
|
|||
};
|
||||
|
||||
var form = new FormUrlEncodedContent(formParams);
|
||||
var response = await tokenClient.PostAsync(IdentityServerPipeline.TokenMtlsEndpoint, form);
|
||||
var response = await tokenClient.PostAsync(IdentityServerPipeline.TokenMtlsEndpoint, form, _ct);
|
||||
|
||||
// Assert
|
||||
response.StatusCode.ShouldBe(System.Net.HttpStatusCode.OK);
|
||||
|
||||
var json = await response.Content.ReadAsStringAsync();
|
||||
var json = await response.Content.ReadAsStringAsync(_ct);
|
||||
json.ShouldContain("access_token");
|
||||
json.ShouldContain("\"token_type\":\"Bearer\"");
|
||||
}
|
||||
|
|
@ -99,12 +99,12 @@ public class MtlsTokenEndpointTests
|
|||
};
|
||||
|
||||
var form = new FormUrlEncodedContent(formParams);
|
||||
var response = await tokenClient.PostAsync(IdentityServerPipeline.TokenEndpoint, form);
|
||||
var response = await tokenClient.PostAsync(IdentityServerPipeline.TokenEndpoint, form, _ct);
|
||||
|
||||
// Assert
|
||||
response.StatusCode.ShouldBe(System.Net.HttpStatusCode.OK);
|
||||
|
||||
var json = await response.Content.ReadAsStringAsync();
|
||||
var json = await response.Content.ReadAsStringAsync(_ct);
|
||||
json.ShouldContain("access_token");
|
||||
json.ShouldContain("\"token_type\":\"Bearer\"");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,12 +15,11 @@ namespace Duende.IdentityServer.IntegrationTests.Endpoints.Token;
|
|||
public class RefreshTokenTests
|
||||
{
|
||||
private const string Category = "Refresh Token Tests";
|
||||
|
||||
private const string client_id = "client";
|
||||
private const string client_secret = "secret";
|
||||
private readonly CancellationToken _ct = TestContext.Current.CancellationToken;
|
||||
private readonly Client _client;
|
||||
private string client_id = "client";
|
||||
private string client_secret = "secret";
|
||||
|
||||
private IdentityServerPipeline _mockPipeline = new IdentityServerPipeline();
|
||||
private readonly IdentityServerPipeline _mockPipeline = new IdentityServerPipeline();
|
||||
|
||||
public RefreshTokenTests()
|
||||
{
|
||||
|
|
@ -91,7 +90,7 @@ public class RefreshTokenTests
|
|||
|
||||
Code = code,
|
||||
RedirectUri = "https://client/callback"
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
tokenResult1.IsError.ShouldBeFalse();
|
||||
tokenResult1.AccessToken.ShouldNotBeNull();
|
||||
|
|
@ -109,7 +108,7 @@ public class RefreshTokenTests
|
|||
ClientCredentialStyle = ClientCredentialStyle.PostBody,
|
||||
|
||||
RefreshToken = tokenResult1.RefreshToken
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
tokenResult2.IsError.ShouldBeFalse();
|
||||
tokenResult2.AccessToken.ShouldNotBeNull();
|
||||
|
|
@ -149,7 +148,7 @@ public class RefreshTokenTests
|
|||
|
||||
Code = code,
|
||||
RedirectUri = "https://client/callback"
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
tokenResult1.IsError.ShouldBeFalse();
|
||||
tokenResult1.AccessToken.ShouldNotBeNull();
|
||||
|
|
@ -167,7 +166,7 @@ public class RefreshTokenTests
|
|||
ClientCredentialStyle = ClientCredentialStyle.PostBody,
|
||||
|
||||
RefreshToken = tokenResult1.RefreshToken
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
tokenResult2.IsError.ShouldBeFalse();
|
||||
tokenResult2.AccessToken.ShouldNotBeNull();
|
||||
|
|
|
|||
|
|
@ -14,13 +14,13 @@ namespace Duende.IdentityServer.IntegrationTests.Endpoints.Token;
|
|||
public class ResourceTests
|
||||
{
|
||||
private const string Category = "Token endpoint";
|
||||
private const string client_id = "client";
|
||||
private const string client_secret = "secret";
|
||||
private const string username = "bob";
|
||||
private const string password = "password";
|
||||
|
||||
private string client_id = "client";
|
||||
private string client_secret = "secret";
|
||||
private string username = "bob";
|
||||
private string password = "password";
|
||||
|
||||
private IdentityServerPipeline _mockPipeline = new IdentityServerPipeline();
|
||||
private readonly CancellationToken _ct = TestContext.Current.CancellationToken;
|
||||
private readonly IdentityServerPipeline _mockPipeline = new IdentityServerPipeline();
|
||||
|
||||
public ResourceTests()
|
||||
{
|
||||
|
|
@ -33,7 +33,6 @@ public class ResourceTests
|
|||
AllowOfflineAccess = true,
|
||||
});
|
||||
|
||||
|
||||
_mockPipeline.Users.Add(new TestUser
|
||||
{
|
||||
SubjectId = "bob",
|
||||
|
|
@ -87,12 +86,13 @@ public class ResourceTests
|
|||
Address = IdentityServerPipeline.TokenEndpoint,
|
||||
ClientId = client_id,
|
||||
ClientSecret = client_secret,
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
var claims = ParseAccessTokenClaims(tokenResponse);
|
||||
claims.Where(x => x.Type == "aud").Select(x => x.Value).ShouldBe(["urn:api1", "urn:api2"]);
|
||||
claims.Where(x => x.Type == "scope").Select(x => x.Value).ShouldBe(["scope1", "scope2", "scope3", "scope4"]);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", Category)]
|
||||
public async Task client_credentials_with_resource_without_scope_should_succeed()
|
||||
|
|
@ -107,7 +107,7 @@ public class ResourceTests
|
|||
{
|
||||
{ "resource", "urn:api1" }
|
||||
}
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
var claims = ParseAccessTokenClaims(tokenResponse);
|
||||
claims.Where(x => x.Type == "aud").Select(x => x.Value).ShouldBe(["urn:api1"]);
|
||||
|
|
@ -123,7 +123,7 @@ public class ResourceTests
|
|||
{
|
||||
{ "resource", "urn:api2" }
|
||||
}
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
var claims = ParseAccessTokenClaims(tokenResponse);
|
||||
claims.Where(x => x.Type == "aud").Select(x => x.Value).ShouldBe(["urn:api2"]);
|
||||
|
|
@ -139,13 +139,14 @@ public class ResourceTests
|
|||
{
|
||||
{ "resource", "urn:api3" }
|
||||
}
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
var claims = ParseAccessTokenClaims(tokenResponse);
|
||||
claims.Where(x => x.Type == "aud").Select(x => x.Value).ShouldBe(["urn:api3"]);
|
||||
claims.Where(x => x.Type == "scope").Select(x => x.Value).ShouldBe(["scope1", "scope3"]);
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", Category)]
|
||||
public async Task client_credentials_without_resource_with_scope_should_succeed()
|
||||
|
|
@ -156,12 +157,13 @@ public class ResourceTests
|
|||
ClientId = client_id,
|
||||
ClientSecret = client_secret,
|
||||
Scope = "scope1",
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
var claims = ParseAccessTokenClaims(tokenResponse);
|
||||
claims.Where(x => x.Type == "aud").Select(x => x.Value).ShouldBe(["urn:api1"]);
|
||||
claims.Where(x => x.Type == "scope").Select(x => x.Value).ShouldBe(["scope1"]);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", Category)]
|
||||
public async Task client_credentials_with_resource_with_scope_should_succeed()
|
||||
|
|
@ -177,7 +179,7 @@ public class ResourceTests
|
|||
{
|
||||
{ "resource", "urn:api1" }
|
||||
}
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
var claims = ParseAccessTokenClaims(tokenResponse);
|
||||
claims.Where(x => x.Type == "aud").Select(x => x.Value).ShouldBe(["urn:api1"]);
|
||||
|
|
@ -194,13 +196,14 @@ public class ResourceTests
|
|||
{
|
||||
{ "resource", "urn:api3" }
|
||||
}
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
var claims = ParseAccessTokenClaims(tokenResponse);
|
||||
claims.Where(x => x.Type == "aud").Select(x => x.Value).ShouldBe(["urn:api3"]);
|
||||
claims.Where(x => x.Type == "scope").Select(x => x.Value).ShouldBe(["scope1"]);
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", Category)]
|
||||
public async Task client_credentials_with_invalid_resource_and_scope_should_fail()
|
||||
|
|
@ -216,7 +219,7 @@ public class ResourceTests
|
|||
{
|
||||
{ "resource", "urn:api2" }
|
||||
}
|
||||
});
|
||||
}, _ct);
|
||||
tokenResponse.IsError.ShouldBeTrue();
|
||||
tokenResponse.Error.ShouldBe("invalid_target");
|
||||
}
|
||||
|
|
@ -231,7 +234,7 @@ public class ResourceTests
|
|||
{
|
||||
{ "resource", "urn:api3" }
|
||||
}
|
||||
});
|
||||
}, _ct);
|
||||
tokenResponse.IsError.ShouldBeTrue();
|
||||
tokenResponse.Error.ShouldBe("invalid_target");
|
||||
}
|
||||
|
|
@ -246,7 +249,7 @@ public class ResourceTests
|
|||
{
|
||||
{ "resource", "urn:api4" }
|
||||
}
|
||||
});
|
||||
}, _ct);
|
||||
tokenResponse.IsError.ShouldBeTrue();
|
||||
tokenResponse.Error.ShouldBe("invalid_target");
|
||||
}
|
||||
|
|
@ -260,14 +263,13 @@ public class ResourceTests
|
|||
{
|
||||
{ "resource", "urn:api4" }
|
||||
}
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
tokenResponse.IsError.ShouldBeTrue();
|
||||
tokenResponse.Error.ShouldBe("invalid_target");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", Category)]
|
||||
public async Task client_credentials_with_empty_resource_should_be_treated_as_if_no_resource_and_succeed()
|
||||
|
|
@ -281,7 +283,7 @@ public class ResourceTests
|
|||
{
|
||||
{ "resource", " " }
|
||||
}
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
var claims = ParseAccessTokenClaims(tokenResponse);
|
||||
claims.Where(x => x.Type == "aud").Select(x => x.Value).ShouldBe(["urn:api1", "urn:api2"]);
|
||||
|
|
@ -299,12 +301,13 @@ public class ResourceTests
|
|||
ClientSecret = client_secret,
|
||||
UserName = username,
|
||||
Password = password,
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
var claims = ParseAccessTokenClaims(tokenResponse);
|
||||
claims.Where(x => x.Type == "aud").Select(x => x.Value).ShouldBe(["urn:api1", "urn:api2"]);
|
||||
claims.Where(x => x.Type == "scope").Select(x => x.Value).ShouldBe(["scope1", "scope2", "scope3", "scope4", "offline_access"]);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", Category)]
|
||||
public async Task refresh_token_requested_with_resource_without_scope_should_succeed()
|
||||
|
|
@ -321,7 +324,7 @@ public class ResourceTests
|
|||
{
|
||||
{ "resource", "urn:api1" }
|
||||
}
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
var claims = ParseAccessTokenClaims(tokenResponse);
|
||||
claims.Where(x => x.Type == "aud").Select(x => x.Value).ShouldBe(["urn:api1"]);
|
||||
|
|
@ -340,7 +343,7 @@ public class ResourceTests
|
|||
{
|
||||
{ "resource", "urn:api2" }
|
||||
}
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
var claims = ParseAccessTokenClaims(tokenResponse);
|
||||
claims.Where(x => x.Type == "aud").Select(x => x.Value).ShouldBe(["urn:api2"]);
|
||||
|
|
@ -359,13 +362,14 @@ public class ResourceTests
|
|||
{
|
||||
{ "resource", "urn:api3" }
|
||||
}
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
var claims = ParseAccessTokenClaims(tokenResponse);
|
||||
claims.Where(x => x.Type == "aud").Select(x => x.Value).ShouldBe(["urn:api3"]);
|
||||
claims.Where(x => x.Type == "scope").Select(x => x.Value).ShouldBe(["scope1", "scope3", "offline_access"]);
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", Category)]
|
||||
public async Task refresh_token_requested_without_resource_with_scope_should_succeed()
|
||||
|
|
@ -378,12 +382,13 @@ public class ResourceTests
|
|||
UserName = username,
|
||||
Password = password,
|
||||
Scope = "scope1 offline_access"
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
var claims = ParseAccessTokenClaims(tokenResponse);
|
||||
claims.Where(x => x.Type == "aud").Select(x => x.Value).ShouldBe(["urn:api1"]);
|
||||
claims.Where(x => x.Type == "scope").Select(x => x.Value).ShouldBe(["scope1", "offline_access"]);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", Category)]
|
||||
public async Task refresh_token_requested_with_resource_with_scope_should_succeed()
|
||||
|
|
@ -401,7 +406,7 @@ public class ResourceTests
|
|||
{
|
||||
{ "resource", "urn:api1" }
|
||||
}
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
var claims = ParseAccessTokenClaims(tokenResponse);
|
||||
claims.Where(x => x.Type == "aud").Select(x => x.Value).ShouldBe(["urn:api1"]);
|
||||
|
|
@ -420,13 +425,14 @@ public class ResourceTests
|
|||
{
|
||||
{ "resource", "urn:api3" }
|
||||
}
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
var claims = ParseAccessTokenClaims(tokenResponse);
|
||||
claims.Where(x => x.Type == "aud").Select(x => x.Value).ShouldBe(["urn:api3"]);
|
||||
claims.Where(x => x.Type == "scope").Select(x => x.Value).ShouldBe(["scope1", "offline_access"]);
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", Category)]
|
||||
public async Task refresh_token_requested_with_invalid_resource_and_scope_should_fail()
|
||||
|
|
@ -444,7 +450,7 @@ public class ResourceTests
|
|||
{
|
||||
{ "resource", "urn:api2" }
|
||||
}
|
||||
});
|
||||
}, _ct);
|
||||
tokenResponse.IsError.ShouldBeTrue();
|
||||
tokenResponse.Error.ShouldBe("invalid_target");
|
||||
}
|
||||
|
|
@ -461,7 +467,7 @@ public class ResourceTests
|
|||
{
|
||||
{ "resource", "urn:api3" }
|
||||
}
|
||||
});
|
||||
}, _ct);
|
||||
tokenResponse.IsError.ShouldBeTrue();
|
||||
tokenResponse.Error.ShouldBe("invalid_target");
|
||||
}
|
||||
|
|
@ -478,7 +484,7 @@ public class ResourceTests
|
|||
{
|
||||
{ "resource", "urn:api4" }
|
||||
}
|
||||
});
|
||||
}, _ct);
|
||||
tokenResponse.IsError.ShouldBeTrue();
|
||||
tokenResponse.Error.ShouldBe("invalid_target");
|
||||
}
|
||||
|
|
@ -495,14 +501,13 @@ public class ResourceTests
|
|||
{
|
||||
{ "resource", "urn:api4" }
|
||||
}
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
tokenResponse.IsError.ShouldBeTrue();
|
||||
tokenResponse.Error.ShouldBe("invalid_target");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", Category)]
|
||||
public async Task refresh_token_exchange_with_resource_should_succeed()
|
||||
|
|
@ -515,7 +520,7 @@ public class ResourceTests
|
|||
UserName = username,
|
||||
Password = password,
|
||||
Scope = "scope1 scope2 scope3 scope4 offline_access",
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
{
|
||||
tokenResponse = await _mockPipeline.BackChannelClient.RequestRefreshTokenAsync(new RefreshTokenRequest
|
||||
|
|
@ -524,7 +529,7 @@ public class ResourceTests
|
|||
ClientId = client_id,
|
||||
ClientSecret = client_secret,
|
||||
RefreshToken = tokenResponse.RefreshToken,
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
var claims = ParseAccessTokenClaims(tokenResponse);
|
||||
claims.Where(x => x.Type == "aud").Select(x => x.Value).ShouldBe(["urn:api1", "urn:api2"]);
|
||||
|
|
@ -541,7 +546,7 @@ public class ResourceTests
|
|||
{
|
||||
{ "resource", "urn:api1" }
|
||||
}
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
var claims = ParseAccessTokenClaims(tokenResponse);
|
||||
claims.Where(x => x.Type == "aud").Select(x => x.Value).ShouldBe(["urn:api1"]);
|
||||
|
|
@ -558,7 +563,7 @@ public class ResourceTests
|
|||
{
|
||||
{ "resource", "urn:api2" }
|
||||
}
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
var claims = ParseAccessTokenClaims(tokenResponse);
|
||||
claims.Where(x => x.Type == "aud").Select(x => x.Value).ShouldBe(["urn:api2"]);
|
||||
|
|
@ -575,13 +580,14 @@ public class ResourceTests
|
|||
{
|
||||
{ "resource", "urn:api3" }
|
||||
}
|
||||
});
|
||||
}, _ct);
|
||||
|
||||
var claims = ParseAccessTokenClaims(tokenResponse);
|
||||
claims.Where(x => x.Type == "aud").Select(x => x.Value).ShouldBe(new[] { "urn:api3" });
|
||||
claims.Where(x => x.Type == "scope").Select(x => x.Value).ShouldBe(new[] { "scope1", "scope3", "offline_access" });
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", Category)]
|
||||
public async Task refresh_token_exchange_with_invalid_resource_should_fail()
|
||||
|
|
@ -595,7 +601,7 @@ public class ResourceTests
|
|||
UserName = username,
|
||||
Password = password,
|
||||
Scope = "scope1 scope2 scope3 scope4 offline_access",
|
||||
});
|
||||
}, _ct);
|
||||
tokenResponse = await _mockPipeline.BackChannelClient.RequestRefreshTokenAsync(new RefreshTokenRequest
|
||||
{
|
||||
Address = IdentityServerPipeline.TokenEndpoint,
|
||||
|
|
@ -606,7 +612,7 @@ public class ResourceTests
|
|||
{
|
||||
{ "resource", "urn:api4" }
|
||||
}
|
||||
});
|
||||
}, _ct);
|
||||
tokenResponse.IsError.ShouldBeTrue();
|
||||
tokenResponse.Error.ShouldBe("invalid_target");
|
||||
}
|
||||
|
|
@ -621,7 +627,7 @@ public class ResourceTests
|
|||
UserName = username,
|
||||
Password = password,
|
||||
Scope = "scope2 offline_access",
|
||||
});
|
||||
}, _ct);
|
||||
tokenResponse = await _mockPipeline.BackChannelClient.RequestRefreshTokenAsync(new RefreshTokenRequest
|
||||
{
|
||||
Address = IdentityServerPipeline.TokenEndpoint,
|
||||
|
|
@ -632,7 +638,7 @@ public class ResourceTests
|
|||
{
|
||||
{ "resource", "urn:api1" }
|
||||
}
|
||||
});
|
||||
}, _ct);
|
||||
tokenResponse.IsError.ShouldBeTrue();
|
||||
tokenResponse.Error.ShouldBe("invalid_target");
|
||||
}
|
||||
|
|
@ -646,7 +652,7 @@ public class ResourceTests
|
|||
UserName = username,
|
||||
Password = password,
|
||||
Scope = "scope4 offline_access",
|
||||
});
|
||||
}, _ct);
|
||||
tokenResponse = await _mockPipeline.BackChannelClient.RequestRefreshTokenAsync(new RefreshTokenRequest
|
||||
{
|
||||
Address = IdentityServerPipeline.TokenEndpoint,
|
||||
|
|
@ -657,7 +663,7 @@ public class ResourceTests
|
|||
{
|
||||
{ "resource", "urn:api1" }
|
||||
}
|
||||
});
|
||||
}, _ct);
|
||||
tokenResponse.IsError.ShouldBeTrue();
|
||||
tokenResponse.Error.ShouldBe("invalid_target");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,14 +15,12 @@ namespace Duende.IdentityServer.IntegrationTests.Endpoints.Token;
|
|||
public class TokenEndpointTests
|
||||
{
|
||||
private const string Category = "Token endpoint";
|
||||
|
||||
private string client_id = "client";
|
||||
private string client_secret = "secret";
|
||||
|
||||
private string scope_name = "api";
|
||||
private string scope_secret = "api_secret";
|
||||
|
||||
private IdentityServerPipeline _mockPipeline = new IdentityServerPipeline();
|
||||
private const string client_id = "client";
|
||||
private const string client_secret = "secret";
|
||||
private const string scope_name = "api";
|
||||
private const string scope_secret = "api_secret";
|
||||
private readonly CancellationToken _ct = TestContext.Current.CancellationToken;
|
||||
private readonly IdentityServerPipeline _mockPipeline = new IdentityServerPipeline();
|
||||
|
||||
public TokenEndpointTests()
|
||||
{
|
||||
|
|
@ -84,10 +82,10 @@ public class TokenEndpointTests
|
|||
};
|
||||
var form = new FormUrlEncodedContent(data);
|
||||
_mockPipeline.BackChannelClient.DefaultRequestHeaders.Add("Referer", "http://127.0.0.1:33086/appservice/appservice?t=1564165664142?load");
|
||||
var response = await _mockPipeline.BackChannelClient.PostAsync(IdentityServerPipeline.TokenEndpoint, form);
|
||||
var response = await _mockPipeline.BackChannelClient.PostAsync(IdentityServerPipeline.TokenEndpoint, form, _ct);
|
||||
|
||||
response.StatusCode.ShouldBe(HttpStatusCode.OK);
|
||||
var json = await response.Content.ReadAsStringAsync();
|
||||
var json = await response.Content.ReadAsStringAsync(_ct);
|
||||
var result = JsonSerializer.Deserialize<Dictionary<string, JsonElement>>(json);
|
||||
result.ContainsKey("error").ShouldBeFalse();
|
||||
}
|
||||
|
|
@ -107,10 +105,10 @@ public class TokenEndpointTests
|
|||
};
|
||||
var form = new FormUrlEncodedContent(data);
|
||||
_mockPipeline.BackChannelClient.DefaultRequestHeaders.Add("Referer", "http://127.0.0.1:33086/appservice/appservice?t=1564165664142?load");
|
||||
var response = await _mockPipeline.BackChannelClient.PostAsync(IdentityServerPipeline.TokenEndpoint, form);
|
||||
var response = await _mockPipeline.BackChannelClient.PostAsync(IdentityServerPipeline.TokenEndpoint, form, _ct);
|
||||
|
||||
response.StatusCode.ShouldBe(HttpStatusCode.OK);
|
||||
var json = await response.Content.ReadAsStringAsync();
|
||||
var json = await response.Content.ReadAsStringAsync(_ct);
|
||||
var result = JsonSerializer.Deserialize<Dictionary<string, JsonElement>>(json);
|
||||
result.ContainsKey("error").ShouldBeFalse();
|
||||
}
|
||||
|
|
@ -122,10 +120,10 @@ public class TokenEndpointTests
|
|||
var text = $"grant_type=client_credentials&client_id={client_id}&client_secret={client_secret}&scope=%00";
|
||||
var content = new StringContent(text, Encoding.UTF8, "application/x-www-form-urlencoded");
|
||||
|
||||
var response = await _mockPipeline.BackChannelClient.PostAsync(IdentityServerPipeline.TokenEndpoint, content);
|
||||
var response = await _mockPipeline.BackChannelClient.PostAsync(IdentityServerPipeline.TokenEndpoint, content, _ct);
|
||||
|
||||
response.StatusCode.ShouldBe(HttpStatusCode.BadRequest);
|
||||
var json = await response.Content.ReadAsStringAsync();
|
||||
var json = await response.Content.ReadAsStringAsync(_ct);
|
||||
var result = JsonSerializer.Deserialize<Dictionary<string, JsonElement>>(json);
|
||||
var error = result["error"].GetString();
|
||||
error.ShouldBe("invalid_request");
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ namespace Duende.IdentityServer.IntegrationTests.EntityFramework;
|
|||
|
||||
public class EntityFrameworkBasedLogoutTests
|
||||
{
|
||||
private readonly CancellationToken _ct = TestContext.Current.CancellationToken;
|
||||
private readonly IdentityServerPipeline _mockPipeline = new();
|
||||
|
||||
private static readonly ICollection<Client> _clients =
|
||||
|
|
@ -74,7 +75,7 @@ public class EntityFrameworkBasedLogoutTests
|
|||
var options = DatabaseProviderBuilder.BuildSqlite<PersistedGrantDbContext, OperationalStoreOptions>("NotUsed", new OperationalStoreOptions(),
|
||||
TimeSpan.FromMilliseconds(1));
|
||||
await using var context = new PersistedGrantDbContext(options);
|
||||
await context.Database.EnsureCreatedAsync();
|
||||
await context.Database.EnsureCreatedAsync(_ct);
|
||||
|
||||
_mockPipeline.OnPostConfigureServices += services =>
|
||||
{
|
||||
|
|
@ -98,7 +99,7 @@ public class EntityFrameworkBasedLogoutTests
|
|||
ClientId = client.ClientId,
|
||||
Code = authzResponse.Code,
|
||||
RedirectUri = client.RedirectUris.First()
|
||||
});
|
||||
}, _ct);
|
||||
}
|
||||
|
||||
//Clear cache to simulate needing to load from db when creating logout notifications to send
|
||||
|
|
|
|||
|
|
@ -15,12 +15,13 @@ namespace Duende.IdentityServer.IntegrationTests.EntityFramework;
|
|||
/// <typeparam name="TDbContext">The type of the database context.</typeparam>
|
||||
/// <typeparam name="TStoreOption">The type of the store option.</typeparam>
|
||||
/// <seealso cref="DatabaseProviderFixture{T}" />
|
||||
public class IntegrationTest<TClass, TDbContext, TStoreOption> : IClassFixture<DatabaseProviderFixture<TDbContext>>
|
||||
public abstract class IntegrationTest<TClass, TDbContext, TStoreOption> : IClassFixture<DatabaseProviderFixture<TDbContext>>
|
||||
where TDbContext : DbContext
|
||||
where TStoreOption : class
|
||||
{
|
||||
public static readonly TheoryData<DbContextOptions<TDbContext>> TestDatabaseProviders;
|
||||
protected static TStoreOption StoreOptions = Activator.CreateInstance<TStoreOption>();
|
||||
|
||||
protected static readonly TStoreOption StoreOptions = Activator.CreateInstance<TStoreOption>();
|
||||
|
||||
static IntegrationTest()
|
||||
{
|
||||
|
|
@ -50,5 +51,6 @@ public class IntegrationTest<TClass, TDbContext, TStoreOption> : IClassFixture<D
|
|||
}
|
||||
}
|
||||
|
||||
protected IntegrationTest(DatabaseProviderFixture<TDbContext> fixture) => fixture.Options = TestDatabaseProviders.ToList<DbContextOptions<TDbContext>>();
|
||||
protected IntegrationTest(DatabaseProviderFixture<TDbContext> fixture)
|
||||
=> fixture.Options = TestDatabaseProviders.Select(row => row.Data).ToList();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,6 +15,8 @@ namespace Duende.IdentityServer.IntegrationTests.EntityFramework.Services;
|
|||
|
||||
public class CorsPolicyServiceTests : IntegrationTest<CorsPolicyServiceTests, ConfigurationDbContext, ConfigurationStoreOptions>
|
||||
{
|
||||
private readonly CancellationToken _ct = TestContext.Current.CancellationToken;
|
||||
|
||||
public CorsPolicyServiceTests(DatabaseProviderFixture<ConfigurationDbContext> fixture) : base(fixture)
|
||||
{
|
||||
foreach (var options in TestDatabaseProviders)
|
||||
|
|
@ -43,7 +45,7 @@ public class CorsPolicyServiceTests : IntegrationTest<CorsPolicyServiceTests, Co
|
|||
ClientName = "2",
|
||||
AllowedCorsOrigins = new List<string> { "https://www.identityserver.com", testCorsOrigin }
|
||||
}.ToEntity());
|
||||
await context.SaveChangesAsync();
|
||||
await context.SaveChangesAsync(_ct);
|
||||
}
|
||||
|
||||
bool result;
|
||||
|
|
@ -67,7 +69,7 @@ public class CorsPolicyServiceTests : IntegrationTest<CorsPolicyServiceTests, Co
|
|||
ClientName = Guid.NewGuid().ToString(),
|
||||
AllowedCorsOrigins = new List<string> { "https://www.identityserver.com" }
|
||||
}.ToEntity());
|
||||
await context.SaveChangesAsync();
|
||||
await context.SaveChangesAsync(_ct);
|
||||
}
|
||||
|
||||
bool result;
|
||||
|
|
|
|||
|
|
@ -16,6 +16,8 @@ namespace Duende.IdentityServer.IntegrationTests.EntityFramework.Storage.Stores;
|
|||
|
||||
public class ClientStoreTests : IntegrationTest<ClientStoreTests, ConfigurationDbContext, ConfigurationStoreOptions>
|
||||
{
|
||||
private readonly CancellationToken _ct = TestContext.Current.CancellationToken;
|
||||
|
||||
public ClientStoreTests(DatabaseProviderFixture<ConfigurationDbContext> fixture) : base(fixture)
|
||||
{
|
||||
foreach (var options in TestDatabaseProviders)
|
||||
|
|
@ -46,7 +48,7 @@ public class ClientStoreTests : IntegrationTest<ClientStoreTests, ConfigurationD
|
|||
await using (var context = new ConfigurationDbContext(options))
|
||||
{
|
||||
context.Clients.Add(testClient.ToEntity());
|
||||
await context.SaveChangesAsync();
|
||||
await context.SaveChangesAsync(_ct);
|
||||
}
|
||||
|
||||
Client client;
|
||||
|
|
@ -80,7 +82,7 @@ public class ClientStoreTests : IntegrationTest<ClientStoreTests, ConfigurationD
|
|||
await using (var context = new ConfigurationDbContext(options))
|
||||
{
|
||||
context.Clients.Add(testClient.ToEntity());
|
||||
await context.SaveChangesAsync();
|
||||
await context.SaveChangesAsync(_ct);
|
||||
}
|
||||
|
||||
Client client;
|
||||
|
|
@ -142,7 +144,7 @@ public class ClientStoreTests : IntegrationTest<ClientStoreTests, ConfigurationD
|
|||
}.ToEntity());
|
||||
}
|
||||
|
||||
context.SaveChanges();
|
||||
await context.SaveChangesAsync(_ct);
|
||||
}
|
||||
|
||||
await using (var context = new ConfigurationDbContext(options))
|
||||
|
|
@ -152,7 +154,7 @@ public class ClientStoreTests : IntegrationTest<ClientStoreTests, ConfigurationD
|
|||
const int timeout = 5000;
|
||||
var task = Task.Run(() => store.FindClientByIdAsync(testClient.ClientId));
|
||||
|
||||
if (await Task.WhenAny(task, Task.Delay(timeout)) == task)
|
||||
if (await Task.WhenAny(task, Task.Delay(timeout, _ct)) == task)
|
||||
{
|
||||
#pragma warning disable xUnit1031 // Do not use blocking task operations in test method, suppressed because the task must have completed to enter this block
|
||||
var client = task.Result;
|
||||
|
|
@ -167,7 +169,7 @@ public class ClientStoreTests : IntegrationTest<ClientStoreTests, ConfigurationD
|
|||
}
|
||||
else
|
||||
{
|
||||
throw new TestTimeoutException(timeout);
|
||||
throw TestTimeoutException.ForTimedOutTest(timeout);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ namespace Duende.IdentityServer.IntegrationTests.EntityFramework.Storage.Stores;
|
|||
|
||||
public class DeviceFlowStoreTests : IntegrationTest<DeviceFlowStoreTests, PersistedGrantDbContext, OperationalStoreOptions>
|
||||
{
|
||||
private readonly CancellationToken _ct = TestContext.Current.CancellationToken;
|
||||
private readonly IPersistentGrantSerializer serializer = new PersistentGrantSerializer();
|
||||
|
||||
public DeviceFlowStoreTests(DatabaseProviderFixture<PersistedGrantDbContext> fixture) : base(fixture)
|
||||
|
|
@ -116,7 +117,7 @@ public class DeviceFlowStoreTests : IntegrationTest<DeviceFlowStoreTests, Persis
|
|||
Expiration = deviceCodeData.CreationTime.AddSeconds(deviceCodeData.Lifetime),
|
||||
Data = serializer.Serialize(deviceCodeData)
|
||||
});
|
||||
await context.SaveChangesAsync();
|
||||
await context.SaveChangesAsync(_ct);
|
||||
}
|
||||
|
||||
await using (var context = new PersistedGrantDbContext(options))
|
||||
|
|
@ -161,7 +162,7 @@ public class DeviceFlowStoreTests : IntegrationTest<DeviceFlowStoreTests, Persis
|
|||
Expiration = deviceCodeData.CreationTime.AddSeconds(deviceCodeData.Lifetime),
|
||||
Data = serializer.Serialize(deviceCodeData)
|
||||
});
|
||||
await context.SaveChangesAsync();
|
||||
await context.SaveChangesAsync(_ct);
|
||||
}
|
||||
|
||||
await using (var context = new PersistedGrantDbContext(options))
|
||||
|
|
@ -208,7 +209,7 @@ public class DeviceFlowStoreTests : IntegrationTest<DeviceFlowStoreTests, Persis
|
|||
Expiration = expectedDeviceCodeData.CreationTime.AddSeconds(expectedDeviceCodeData.Lifetime),
|
||||
Data = serializer.Serialize(expectedDeviceCodeData)
|
||||
});
|
||||
await context.SaveChangesAsync();
|
||||
await context.SaveChangesAsync(_ct);
|
||||
}
|
||||
|
||||
DeviceCode code;
|
||||
|
|
@ -270,7 +271,7 @@ public class DeviceFlowStoreTests : IntegrationTest<DeviceFlowStoreTests, Persis
|
|||
Expiration = expectedDeviceCodeData.CreationTime.AddSeconds(expectedDeviceCodeData.Lifetime),
|
||||
Data = serializer.Serialize(expectedDeviceCodeData)
|
||||
});
|
||||
await context.SaveChangesAsync();
|
||||
await context.SaveChangesAsync(_ct);
|
||||
}
|
||||
|
||||
DeviceCode code;
|
||||
|
|
@ -329,7 +330,7 @@ public class DeviceFlowStoreTests : IntegrationTest<DeviceFlowStoreTests, Persis
|
|||
Expiration = unauthorizedDeviceCode.CreationTime.AddSeconds(unauthorizedDeviceCode.Lifetime),
|
||||
Data = serializer.Serialize(unauthorizedDeviceCode)
|
||||
});
|
||||
await context.SaveChangesAsync();
|
||||
await context.SaveChangesAsync(_ct);
|
||||
}
|
||||
|
||||
var authorizedDeviceCode = new DeviceCode
|
||||
|
|
@ -404,7 +405,7 @@ public class DeviceFlowStoreTests : IntegrationTest<DeviceFlowStoreTests, Persis
|
|||
Expiration = existingDeviceCode.CreationTime.AddSeconds(existingDeviceCode.Lifetime),
|
||||
Data = serializer.Serialize(existingDeviceCode)
|
||||
});
|
||||
await context.SaveChangesAsync();
|
||||
await context.SaveChangesAsync(_ct);
|
||||
}
|
||||
|
||||
await using (var context = new PersistedGrantDbContext(options))
|
||||
|
|
|
|||
|
|
@ -15,6 +15,8 @@ namespace Duende.IdentityServer.IntegrationTests.EntityFramework.Storage.Stores;
|
|||
|
||||
public class IdentityProviderStoreTests : IntegrationTest<IdentityProviderStoreTests, ConfigurationDbContext, ConfigurationStoreOptions>
|
||||
{
|
||||
private readonly CancellationToken _ct = TestContext.Current.CancellationToken;
|
||||
|
||||
public IdentityProviderStoreTests(DatabaseProviderFixture<ConfigurationDbContext> fixture) : base(fixture)
|
||||
{
|
||||
foreach (var options in TestDatabaseProviders)
|
||||
|
|
@ -24,8 +26,6 @@ public class IdentityProviderStoreTests : IntegrationTest<IdentityProviderStoreT
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
[Theory, MemberData(nameof(TestDatabaseProviders))]
|
||||
public async Task GetBySchemeAsync_should_find_by_scheme(DbContextOptions<ConfigurationDbContext> options)
|
||||
{
|
||||
|
|
@ -37,7 +37,7 @@ public class IdentityProviderStoreTests : IntegrationTest<IdentityProviderStoreT
|
|||
Type = "oidc"
|
||||
};
|
||||
context.IdentityProviders.Add(idp.ToEntity());
|
||||
await context.SaveChangesAsync();
|
||||
await context.SaveChangesAsync(_ct);
|
||||
}
|
||||
|
||||
await using (var context = new ConfigurationDbContext(options))
|
||||
|
|
@ -61,7 +61,7 @@ public class IdentityProviderStoreTests : IntegrationTest<IdentityProviderStoreT
|
|||
Type = "saml"
|
||||
};
|
||||
context.IdentityProviders.Add(idp.ToEntity());
|
||||
await context.SaveChangesAsync();
|
||||
await context.SaveChangesAsync(_ct);
|
||||
}
|
||||
|
||||
await using (var context = new ConfigurationDbContext(options))
|
||||
|
|
@ -84,7 +84,7 @@ public class IdentityProviderStoreTests : IntegrationTest<IdentityProviderStoreT
|
|||
Type = "oidc"
|
||||
};
|
||||
context.IdentityProviders.Add(idp.ToEntity());
|
||||
await context.SaveChangesAsync();
|
||||
await context.SaveChangesAsync(_ct);
|
||||
}
|
||||
|
||||
await using (var context = new ConfigurationDbContext(options))
|
||||
|
|
|
|||
|
|
@ -16,6 +16,8 @@ namespace Duende.IdentityServer.IntegrationTests.EntityFramework.Storage.Stores;
|
|||
|
||||
public class PersistedGrantStoreTests : IntegrationTest<PersistedGrantStoreTests, PersistedGrantDbContext, OperationalStoreOptions>
|
||||
{
|
||||
private readonly CancellationToken _ct = TestContext.Current.CancellationToken;
|
||||
|
||||
public PersistedGrantStoreTests(DatabaseProviderFixture<PersistedGrantDbContext> fixture) : base(fixture)
|
||||
{
|
||||
foreach (var options in TestDatabaseProviders)
|
||||
|
|
@ -63,7 +65,7 @@ public class PersistedGrantStoreTests : IntegrationTest<PersistedGrantStoreTests
|
|||
await using (var context = new PersistedGrantDbContext(options))
|
||||
{
|
||||
context.PersistedGrants.Add(persistedGrant.ToEntity());
|
||||
await context.SaveChangesAsync();
|
||||
await context.SaveChangesAsync(_ct);
|
||||
}
|
||||
|
||||
PersistedGrant foundPersistedGrant;
|
||||
|
|
@ -84,7 +86,7 @@ public class PersistedGrantStoreTests : IntegrationTest<PersistedGrantStoreTests
|
|||
await using (var context = new PersistedGrantDbContext(options))
|
||||
{
|
||||
context.PersistedGrants.Add(persistedGrant.ToEntity());
|
||||
await context.SaveChangesAsync();
|
||||
await context.SaveChangesAsync(_ct);
|
||||
}
|
||||
|
||||
IList<PersistedGrant> foundPersistedGrants;
|
||||
|
|
@ -114,7 +116,7 @@ public class PersistedGrantStoreTests : IntegrationTest<PersistedGrantStoreTests
|
|||
context.PersistedGrants.Add(CreateTestObject(sub: "sub1", clientId: "c2", sid: "s2", type: "t2").ToEntity());
|
||||
context.PersistedGrants.Add(CreateTestObject(sub: "sub1", clientId: "c3", sid: "s3", type: "t3").ToEntity());
|
||||
context.PersistedGrants.Add(CreateTestObject().ToEntity());
|
||||
await context.SaveChangesAsync();
|
||||
await context.SaveChangesAsync(_ct);
|
||||
}
|
||||
|
||||
await using (var context = new PersistedGrantDbContext(options))
|
||||
|
|
@ -186,7 +188,7 @@ public class PersistedGrantStoreTests : IntegrationTest<PersistedGrantStoreTests
|
|||
await using (var context = new PersistedGrantDbContext(options))
|
||||
{
|
||||
context.PersistedGrants.Add(persistedGrant.ToEntity());
|
||||
await context.SaveChangesAsync();
|
||||
await context.SaveChangesAsync(_ct);
|
||||
}
|
||||
|
||||
await using (var context = new PersistedGrantDbContext(options))
|
||||
|
|
@ -210,7 +212,7 @@ public class PersistedGrantStoreTests : IntegrationTest<PersistedGrantStoreTests
|
|||
await using (var context = new PersistedGrantDbContext(options))
|
||||
{
|
||||
context.PersistedGrants.Add(persistedGrant.ToEntity());
|
||||
await context.SaveChangesAsync();
|
||||
await context.SaveChangesAsync(_ct);
|
||||
}
|
||||
|
||||
await using (var context = new PersistedGrantDbContext(options))
|
||||
|
|
@ -238,7 +240,7 @@ public class PersistedGrantStoreTests : IntegrationTest<PersistedGrantStoreTests
|
|||
await using (var context = new PersistedGrantDbContext(options))
|
||||
{
|
||||
context.PersistedGrants.Add(persistedGrant.ToEntity());
|
||||
await context.SaveChangesAsync();
|
||||
await context.SaveChangesAsync(_ct);
|
||||
}
|
||||
|
||||
await using (var context = new PersistedGrantDbContext(options))
|
||||
|
|
@ -449,7 +451,7 @@ public class PersistedGrantStoreTests : IntegrationTest<PersistedGrantStoreTests
|
|||
await using (var context = new PersistedGrantDbContext(options))
|
||||
{
|
||||
context.PersistedGrants.Add(persistedGrant.ToEntity());
|
||||
await context.SaveChangesAsync();
|
||||
await context.SaveChangesAsync(_ct);
|
||||
}
|
||||
|
||||
var newDate = persistedGrant.Expiration.Value.AddHours(1);
|
||||
|
|
|
|||
|
|
@ -16,6 +16,8 @@ namespace Duende.IdentityServer.IntegrationTests.EntityFramework.Storage.Stores;
|
|||
|
||||
public class ScopeStoreTests : IntegrationTest<ScopeStoreTests, ConfigurationDbContext, ConfigurationStoreOptions>
|
||||
{
|
||||
private readonly CancellationToken _ct = TestContext.Current.CancellationToken;
|
||||
|
||||
public ScopeStoreTests(DatabaseProviderFixture<ConfigurationDbContext> fixture) : base(fixture)
|
||||
{
|
||||
foreach (var options in TestDatabaseProviders)
|
||||
|
|
@ -69,7 +71,7 @@ public class ScopeStoreTests : IntegrationTest<ScopeStoreTests, ConfigurationDbC
|
|||
await using (var context = new ConfigurationDbContext(options))
|
||||
{
|
||||
context.ApiResources.Add(resource.ToEntity());
|
||||
await context.SaveChangesAsync();
|
||||
await context.SaveChangesAsync(_ct);
|
||||
}
|
||||
|
||||
ApiResource foundResource;
|
||||
|
|
@ -98,7 +100,7 @@ public class ScopeStoreTests : IntegrationTest<ScopeStoreTests, ConfigurationDbC
|
|||
{
|
||||
context.ApiResources.Add(resource.ToEntity());
|
||||
context.ApiResources.Add(CreateApiResourceTestResource().ToEntity());
|
||||
await context.SaveChangesAsync();
|
||||
await context.SaveChangesAsync(_ct);
|
||||
}
|
||||
|
||||
ApiResource foundResource;
|
||||
|
|
@ -130,7 +132,7 @@ public class ScopeStoreTests : IntegrationTest<ScopeStoreTests, ConfigurationDbC
|
|||
{
|
||||
context.ApiResources.Add(testApiResource.ToEntity());
|
||||
context.ApiScopes.Add(testApiScope.ToEntity());
|
||||
await context.SaveChangesAsync();
|
||||
await context.SaveChangesAsync(_ct);
|
||||
}
|
||||
|
||||
IEnumerable<ApiResource> resources;
|
||||
|
|
@ -164,7 +166,7 @@ public class ScopeStoreTests : IntegrationTest<ScopeStoreTests, ConfigurationDbC
|
|||
context.IdentityResources.Add(CreateIdentityTestResource().ToEntity());
|
||||
context.ApiResources.Add(CreateApiResourceTestResource().ToEntity());
|
||||
context.ApiScopes.Add(CreateApiScopeTestResource().ToEntity());
|
||||
await context.SaveChangesAsync();
|
||||
await context.SaveChangesAsync(_ct);
|
||||
}
|
||||
|
||||
IEnumerable<ApiResource> resources;
|
||||
|
|
@ -187,7 +189,7 @@ public class ScopeStoreTests : IntegrationTest<ScopeStoreTests, ConfigurationDbC
|
|||
await using (var context = new ConfigurationDbContext(options))
|
||||
{
|
||||
context.IdentityResources.Add(resource.ToEntity());
|
||||
await context.SaveChangesAsync();
|
||||
await context.SaveChangesAsync(_ct);
|
||||
}
|
||||
|
||||
IList<IdentityResource> resources;
|
||||
|
|
@ -218,7 +220,7 @@ public class ScopeStoreTests : IntegrationTest<ScopeStoreTests, ConfigurationDbC
|
|||
{
|
||||
context.IdentityResources.Add(resource.ToEntity());
|
||||
context.IdentityResources.Add(CreateIdentityTestResource().ToEntity());
|
||||
await context.SaveChangesAsync();
|
||||
await context.SaveChangesAsync(_ct);
|
||||
}
|
||||
|
||||
IList<IdentityResource> resources;
|
||||
|
|
@ -244,7 +246,7 @@ public class ScopeStoreTests : IntegrationTest<ScopeStoreTests, ConfigurationDbC
|
|||
await using (var context = new ConfigurationDbContext(options))
|
||||
{
|
||||
context.ApiScopes.Add(resource.ToEntity());
|
||||
await context.SaveChangesAsync();
|
||||
await context.SaveChangesAsync(_ct);
|
||||
}
|
||||
|
||||
IList<ApiScope> resources;
|
||||
|
|
@ -275,7 +277,7 @@ public class ScopeStoreTests : IntegrationTest<ScopeStoreTests, ConfigurationDbC
|
|||
{
|
||||
context.ApiScopes.Add(resource.ToEntity());
|
||||
context.ApiScopes.Add(CreateApiScopeTestResource().ToEntity());
|
||||
await context.SaveChangesAsync();
|
||||
await context.SaveChangesAsync(_ct);
|
||||
}
|
||||
|
||||
IList<ApiScope> resources;
|
||||
|
|
@ -322,7 +324,7 @@ public class ScopeStoreTests : IntegrationTest<ScopeStoreTests, ConfigurationDbC
|
|||
context.ApiResources.Add(hiddenApiResource.ToEntity());
|
||||
context.ApiScopes.Add(hiddenApiScope.ToEntity());
|
||||
|
||||
await context.SaveChangesAsync();
|
||||
await context.SaveChangesAsync(_ct);
|
||||
}
|
||||
|
||||
Resources resources;
|
||||
|
|
|
|||
|
|
@ -18,6 +18,8 @@ namespace Duende.IdentityServer.IntegrationTests.EntityFramework.Storage.TokenCl
|
|||
|
||||
public class TokenCleanupTests : IntegrationTest<TokenCleanupTests, PersistedGrantDbContext, OperationalStoreOptions>
|
||||
{
|
||||
private readonly CancellationToken _ct = TestContext.Current.CancellationToken;
|
||||
|
||||
public TokenCleanupTests(DatabaseProviderFixture<PersistedGrantDbContext> fixture) : base(fixture)
|
||||
{
|
||||
foreach (var options in TestDatabaseProviders)
|
||||
|
|
@ -54,10 +56,10 @@ public class TokenCleanupTests : IntegrationTest<TokenCleanupTests, PersistedGra
|
|||
await using (var context = new PersistedGrantDbContext(options))
|
||||
{
|
||||
context.PersistedGrants.Add(expiredGrant);
|
||||
await context.SaveChangesAsync();
|
||||
await context.SaveChangesAsync(_ct);
|
||||
}
|
||||
|
||||
await CreateSut(options).CleanupGrantsAsync();
|
||||
await CreateSut(options).CleanupGrantsAsync(_ct);
|
||||
|
||||
await using (var context = new PersistedGrantDbContext(options))
|
||||
{
|
||||
|
|
@ -81,10 +83,10 @@ public class TokenCleanupTests : IntegrationTest<TokenCleanupTests, PersistedGra
|
|||
await using (var context = new PersistedGrantDbContext(options))
|
||||
{
|
||||
context.PersistedGrants.Add(validGrant);
|
||||
await context.SaveChangesAsync();
|
||||
await context.SaveChangesAsync(_ct);
|
||||
}
|
||||
|
||||
await CreateSut(options).CleanupGrantsAsync();
|
||||
await CreateSut(options).CleanupGrantsAsync(_ct);
|
||||
|
||||
await using (var context = new PersistedGrantDbContext(options))
|
||||
{
|
||||
|
|
@ -125,10 +127,10 @@ public class TokenCleanupTests : IntegrationTest<TokenCleanupTests, PersistedGra
|
|||
{
|
||||
context.PersistedGrants.AddRange(expiredGrants);
|
||||
context.PersistedGrants.AddRange(validGrants);
|
||||
await context.SaveChangesAsync();
|
||||
await context.SaveChangesAsync(_ct);
|
||||
}
|
||||
|
||||
await CreateSut(options).CleanupGrantsAsync();
|
||||
await CreateSut(options).CleanupGrantsAsync(_ct);
|
||||
|
||||
await using (var context = new PersistedGrantDbContext(options))
|
||||
{
|
||||
|
|
@ -156,10 +158,10 @@ public class TokenCleanupTests : IntegrationTest<TokenCleanupTests, PersistedGra
|
|||
await using (var context = new PersistedGrantDbContext(options))
|
||||
{
|
||||
context.DeviceFlowCodes.Add(expiredGrant);
|
||||
await context.SaveChangesAsync();
|
||||
await context.SaveChangesAsync(_ct);
|
||||
}
|
||||
|
||||
await CreateSut(options).CleanupGrantsAsync();
|
||||
await CreateSut(options).CleanupGrantsAsync(_ct);
|
||||
|
||||
await using (var context = new PersistedGrantDbContext(options))
|
||||
{
|
||||
|
|
@ -184,10 +186,10 @@ public class TokenCleanupTests : IntegrationTest<TokenCleanupTests, PersistedGra
|
|||
await using (var context = new PersistedGrantDbContext(options))
|
||||
{
|
||||
context.DeviceFlowCodes.Add(validGrant);
|
||||
await context.SaveChangesAsync();
|
||||
await context.SaveChangesAsync(_ct);
|
||||
}
|
||||
|
||||
await CreateSut(options).CleanupGrantsAsync();
|
||||
await CreateSut(options).CleanupGrantsAsync(_ct);
|
||||
|
||||
await using (var context = new PersistedGrantDbContext(options))
|
||||
{
|
||||
|
|
@ -213,10 +215,10 @@ public class TokenCleanupTests : IntegrationTest<TokenCleanupTests, PersistedGra
|
|||
await using (var context = new PersistedGrantDbContext(options))
|
||||
{
|
||||
context.PersistedGrants.Add(consumedGrant);
|
||||
await context.SaveChangesAsync();
|
||||
await context.SaveChangesAsync(_ct);
|
||||
}
|
||||
|
||||
await CreateSut(options, removeConsumedTokens: true).CleanupGrantsAsync();
|
||||
await CreateSut(options, removeConsumedTokens: true).CleanupGrantsAsync(_ct);
|
||||
|
||||
await using (var context = new PersistedGrantDbContext(options))
|
||||
{
|
||||
|
|
@ -241,10 +243,10 @@ public class TokenCleanupTests : IntegrationTest<TokenCleanupTests, PersistedGra
|
|||
await using (var context = new PersistedGrantDbContext(options))
|
||||
{
|
||||
context.PersistedGrants.Add(consumedGrant);
|
||||
await context.SaveChangesAsync();
|
||||
await context.SaveChangesAsync(_ct);
|
||||
}
|
||||
|
||||
await CreateSut(options, removeConsumedTokens: false).CleanupGrantsAsync();
|
||||
await CreateSut(options, removeConsumedTokens: false).CleanupGrantsAsync(_ct);
|
||||
|
||||
await using (var context = new PersistedGrantDbContext(options))
|
||||
{
|
||||
|
|
@ -277,7 +279,7 @@ public class TokenCleanupTests : IntegrationTest<TokenCleanupTests, PersistedGra
|
|||
context.PersistedGrants.Add(expiredGrant);
|
||||
}
|
||||
|
||||
await context.SaveChangesAsync();
|
||||
await context.SaveChangesAsync(_ct);
|
||||
|
||||
context.PersistedGrants.Count().ShouldBe(StoreOptions.TokenCleanupBatchSize * expectedPageCount);
|
||||
}
|
||||
|
|
@ -287,7 +289,7 @@ public class TokenCleanupTests : IntegrationTest<TokenCleanupTests, PersistedGra
|
|||
await CreateSut(options, svcs =>
|
||||
{
|
||||
svcs.AddSingleton<IOperationalStoreNotification>(mockNotifications);
|
||||
}).CleanupGrantsAsync();
|
||||
}).CleanupGrantsAsync(_ct);
|
||||
|
||||
// The right number of batches executed
|
||||
mockNotifications.PersistedGrantNotifications.Count.ShouldBe(expectedPageCount);
|
||||
|
|
@ -328,7 +330,7 @@ public class TokenCleanupTests : IntegrationTest<TokenCleanupTests, PersistedGra
|
|||
context.PersistedGrants.Add(expiredGrant);
|
||||
}
|
||||
|
||||
await context.SaveChangesAsync();
|
||||
await context.SaveChangesAsync(_ct);
|
||||
}
|
||||
|
||||
// Whenever we cleanup a batch of grants, a new (expired) grant is inserted
|
||||
|
|
@ -356,7 +358,7 @@ public class TokenCleanupTests : IntegrationTest<TokenCleanupTests, PersistedGra
|
|||
await CreateSut(options, svcs =>
|
||||
{
|
||||
svcs.AddSingleton<IOperationalStoreNotification>(mockNotifications);
|
||||
}).CleanupGrantsAsync();
|
||||
}).CleanupGrantsAsync(_ct);
|
||||
|
||||
// Each batch created an extra grant, so we do an extra batch to clean up
|
||||
// the extras
|
||||
|
|
@ -414,10 +416,10 @@ public class TokenCleanupTests : IntegrationTest<TokenCleanupTests, PersistedGra
|
|||
{
|
||||
context.PersistedGrants.Add(newConsumedGrant);
|
||||
context.PersistedGrants.Add(oldConsumedGrant);
|
||||
await context.SaveChangesAsync();
|
||||
await context.SaveChangesAsync(_ct);
|
||||
}
|
||||
|
||||
await CreateSut(options, removeConsumedTokens: true, delay).CleanupGrantsAsync();
|
||||
await CreateSut(options, removeConsumedTokens: true, delay).CleanupGrantsAsync(_ct);
|
||||
|
||||
await using (var context = new PersistedGrantDbContext(options))
|
||||
{
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ namespace Duende.IdentityServer.IntegrationTests.Extensibility;
|
|||
|
||||
public class CustomAuthorizeResponseGeneratorTests
|
||||
{
|
||||
private readonly CancellationToken _ct = TestContext.Current.CancellationToken;
|
||||
private const string Category = "CustomAuthorizeResponseGeneratorTests";
|
||||
|
||||
private IdentityServerPipeline _mockPipeline = new IdentityServerPipeline();
|
||||
|
|
@ -71,7 +72,7 @@ public class CustomAuthorizeResponseGeneratorTests
|
|||
codeChallengeMethod: OidcConstants.CodeChallengeMethods.Sha256,
|
||||
state: "123_state",
|
||||
nonce: "123_nonce");
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(url);
|
||||
var response = await _mockPipeline.BrowserClient.GetAsync(url, _ct);
|
||||
|
||||
response.StatusCode.ShouldBe(HttpStatusCode.Redirect);
|
||||
response.Headers.Location.ShouldNotBeNull();
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ namespace Duende.IdentityServer.IntegrationTests.Extensibility;
|
|||
|
||||
public class CustomClaimsServiceTests
|
||||
{
|
||||
private readonly CancellationToken _ct = TestContext.Current.CancellationToken;
|
||||
private const string Category = "CustomClaimsServiceTests";
|
||||
|
||||
private IdentityServerPipeline _mockPipeline = new IdentityServerPipeline();
|
||||
|
|
@ -59,7 +60,7 @@ public class CustomClaimsServiceTests
|
|||
Address = IdentityServerPipeline.TokenEndpoint,
|
||||
ClientId = "test",
|
||||
ClientSecret = "secret"
|
||||
});
|
||||
}, _ct);
|
||||
result.IsError.ShouldBeFalse();
|
||||
|
||||
var accessToken = result.AccessToken;
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue