diff --git a/identity-server/aspire/AppHosts/All/All.csproj b/identity-server/aspire/AppHosts/All/All.csproj
index 59260731c..3ab38c47e 100644
--- a/identity-server/aspire/AppHosts/All/All.csproj
+++ b/identity-server/aspire/AppHosts/All/All.csproj
@@ -60,6 +60,12 @@
+
+
+
+
+
+
diff --git a/identity-server/aspire/AppHosts/All/Program.cs b/identity-server/aspire/AppHosts/All/Program.cs
index fbf53fe58..06048654b 100644
--- a/identity-server/aspire/AppHosts/All/Program.cs
+++ b/identity-server/aspire/AppHosts/All/Program.cs
@@ -163,6 +163,11 @@ void ConfigureWebClients()
RegisterClientIfEnabled("mvc-jar-jwt");
RegisterClientIfEnabled("mvc-jar-uri-jwt");
RegisterClientIfEnabled("web");
+ RegisterTemplateIfEnabled("template-is", 7001);
+ RegisterTemplateIfEnabled("template-is-empty", 7002);
+ RegisterTemplateIfEnabled("template-is-inmem", 7003);
+ RegisterTemplateIfEnabled("template-is-aspid", 7004);
+ RegisterTemplateIfEnabled("template-is-ef", 7005);
}
void ConfigureConsoleClients()
@@ -224,15 +229,24 @@ bool ApiIsEnabled(string name)
return appConfig.UseApis.TryGetValue(name, out var enabled) && enabled;
}
-void RegisterClientIfEnabled(string name, bool explicitStart = false) where T : IProjectMetadata, new()
+IResourceBuilder? RegisterTemplateIfEnabled(string name, int port) where T : IProjectMetadata, new() =>
+ RegisterClientIfEnabled(name, useLaunchProfile: false)?.WithHttpsEndpoint(port: port, name: name);
+
+IResourceBuilder? RegisterClientIfEnabled(string name, bool explicitStart = false, bool useLaunchProfile = true) where T : IProjectMetadata, new()
{
if (ClientIsEnabled(typeof(T).Name))
{
- var resourceBuilder = builder.AddProject(name)
- .AddIdentityAndApiReferences(projectRegistry);
+ var resourceBuilder = useLaunchProfile ?
+ builder.AddProject(name) :
+ builder.AddProject(name, launchProfileName: null);
+ resourceBuilder.AddIdentityAndApiReferences(projectRegistry);
if (explicitStart)
{
resourceBuilder.WithExplicitStart();
}
+
+ return resourceBuilder;
}
+
+ return null;
}
diff --git a/identity-server/aspire/AppHosts/All/appsettings.json b/identity-server/aspire/AppHosts/All/appsettings.json
index 2b025dcd8..b0c269c4d 100644
--- a/identity-server/aspire/AppHosts/All/appsettings.json
+++ b/identity-server/aspire/AppHosts/All/appsettings.json
@@ -30,6 +30,11 @@
"ConsoleResourceOwnerFlowRefreshToken": false,
"ConsoleResourceOwnerFlowUserInfo": false,
"ConsoleScopesResources": false,
+ "IdentityServerTemplate": true,
+ "IdentityServerEmpty": true,
+ "IdentityServerInMem": true,
+ "IdentityServerAspNetIdentity": true,
+ "IdentityServerEntityFramework": true,
"JsOidc": false,
"MvcAutomaticTokenManagement": true,
"MvcCode": true,
diff --git a/identity-server/aspire/ServiceDefaults/IdentityServerAppHostRoutes.cs b/identity-server/aspire/ServiceDefaults/IdentityServerAppHostRoutes.cs
index cf13312e2..65099c2fb 100644
--- a/identity-server/aspire/ServiceDefaults/IdentityServerAppHostRoutes.cs
+++ b/identity-server/aspire/ServiceDefaults/IdentityServerAppHostRoutes.cs
@@ -24,6 +24,11 @@ public class IdentityServerAppHostRoutes : IAppHostServiceRoutes
AppHostServices.MvcJarJwt => "https://localhost:44304",
AppHostServices.MvcJarUriJwt => "https://localhost:44305",
AppHostServices.Web => "https://localhost:44306",
+ AppHostServices.TemplateIs => "https://localhost:7001",
+ AppHostServices.TemplateIsEmpty => "https://localhost:7002",
+ AppHostServices.TemplateIsInMem => "https://localhost:7003",
+ AppHostServices.TemplateIsAspid => "https://localhost:7004",
+ AppHostServices.TemplateIsEF => "https://localhost:7005",
_ => throw new InvalidOperationException("client not configured")
};
return new Uri(url);
@@ -40,4 +45,9 @@ public class AppHostServices
public const string MvcJarJwt = "mvc-jar-jwt";
public const string MvcJarUriJwt = "mvc-jar-uri-jwt";
public const string Web = "web";
+ public const string TemplateIs = "template-is";
+ public const string TemplateIsEmpty = "template-is-empty";
+ public const string TemplateIsInMem = "template-is-inmem";
+ public const string TemplateIsAspid = "template-is-aspid";
+ public const string TemplateIsEF = "template-is-ef";
}
diff --git a/identity-server/test/IdentityServer.EndToEndTests/IdentityServerTests.cs b/identity-server/test/IdentityServer.EndToEndTests/IdentityServerTests.cs
index 5f58aee6d..786de6519 100644
--- a/identity-server/test/IdentityServer.EndToEndTests/IdentityServerTests.cs
+++ b/identity-server/test/IdentityServer.EndToEndTests/IdentityServerTests.cs
@@ -10,17 +10,9 @@ using Xunit.Abstractions;
namespace Duende.IdentityServer.EndToEndTests;
[Collection(IdentityServerAppHostCollection.CollectionName)]
-public class IdentityServerTests : PlaywrightTestBase
+public class IdentityServerTests(ITestOutputHelper output, IdentityServerHostTestFixture fixture)
+ : PlaywrightTestBase(output, fixture)
{
- private readonly HttpClient _identityServerClient;
- private readonly HttpClient _webClient;
-
- public IdentityServerTests(ITestOutputHelper output, IdentityServerHostTestFixture fixture) : base(output, fixture)
- {
- _identityServerClient = CreateHttpClient(AppHostServices.IdentityServer);
- _webClient = CreateHttpClient(AppHostServices.Web);
- }
-
[Theory]
[InlineData(AppHostServices.MvcAutomaticTokenManagement)]
[InlineData(AppHostServices.MvcCode)]
@@ -29,7 +21,7 @@ public class IdentityServerTests : PlaywrightTestBase
[InlineData(AppHostServices.MvcJarJwt)]
[InlineData(AppHostServices.MvcJarUriJwt)]
[InlineData(AppHostServices.Web)]
- public async Task can_login_use_tokens_and_logout(string clientName)
+ public async Task clients_can_login_use_tokens_and_logout(string clientName)
{
await Page.GotoAsync(Fixture.GetUrlTo(clientName).ToString());
await Page.Login();
@@ -38,4 +30,18 @@ public class IdentityServerTests : PlaywrightTestBase
await Page.CallApi();
await Page.Logout();
}
+
+ [Theory]
+ [InlineData(AppHostServices.TemplateIs)]
+ [InlineData(AppHostServices.TemplateIsEmpty)]
+ [InlineData(AppHostServices.TemplateIsInMem)]
+ [InlineData(AppHostServices.TemplateIsAspid)]
+ // The EF template is disabled because we would need to run the migrations
+ // [InlineData(AppHostServices.TemplateIsEF)]
+ public async Task templates_can_serve_discovery(string templateName)
+ {
+ var client = CreateHttpClient(templateName);
+ var response = await client.GetAsync(".well-known/openid-configuration");
+ response.IsSuccessStatusCode.ShouldBeTrue();
+ }
}
diff --git a/shared/Xunit.Playwright/AppHostFixture.cs b/shared/Xunit.Playwright/AppHostFixture.cs
index 56aa0b77f..8e0b3e0cb 100644
--- a/shared/Xunit.Playwright/AppHostFixture.cs
+++ b/shared/Xunit.Playwright/AppHostFixture.cs
@@ -148,16 +148,16 @@ public class AppHostFixture(IAppHostServiceRoutes routes) : IAsyncLifetim
///
/// This method builds an http client.
///
- ///
+ ///
///
- public HttpClient CreateHttpClient(string clientName)
+ public HttpClient CreateHttpClient(string hostName)
{
HttpMessageHandler inner;
Uri? baseAddress;
if (UsingAlreadyRunningInstance)
{
- var url = GetUrlTo(clientName);
+ var url = GetUrlTo(hostName);
baseAddress = url;
inner = new SocketsHttpHandler
@@ -182,7 +182,7 @@ public class AppHostFixture(IAppHostServiceRoutes routes) : IAsyncLifetim
throw new NotSupportedException("App should not be null");
}
- var client = _app.CreateHttpClient(clientName);
+ var client = _app.CreateHttpClient(hostName);
baseAddress = client.BaseAddress;
// We can't directly use the HTTP Client, because we need cookie support, but if we
@@ -221,11 +221,11 @@ public class AppHostFixture(IAppHostServiceRoutes routes) : IAsyncLifetim
};
}
- public Uri GetUrlTo(string clientName)
+ public Uri GetUrlTo(string hostName)
{
if (UsingAlreadyRunningInstance)
{
- return routes.UrlTo(clientName);
+ return routes.UrlTo(hostName);
}
else
{
@@ -235,7 +235,7 @@ public class AppHostFixture(IAppHostServiceRoutes routes) : IAsyncLifetim
throw new NullReferenceException("App should not be null");
}
- return _app.GetEndpoint(clientName);
+ return _app.GetEndpoint(hostName);
#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. ");
return null!;
diff --git a/shared/Xunit.Playwright/IAppHostServiceRoutes.cs b/shared/Xunit.Playwright/IAppHostServiceRoutes.cs
index a759bbd8a..91757c934 100644
--- a/shared/Xunit.Playwright/IAppHostServiceRoutes.cs
+++ b/shared/Xunit.Playwright/IAppHostServiceRoutes.cs
@@ -9,5 +9,5 @@ namespace Duende.Xunit.Playwright;
public interface IAppHostServiceRoutes
{
public string[] ServiceNames { get; }
- public Uri UrlTo(string clientName);
+ public Uri UrlTo(string hostName);
}