mirror of
https://github.com/DuendeSoftware/products
synced 2026-05-24 09:28:24 +00:00
fix blazor samples (#1742)
* fix blazor samples * fixed blazor client project * tests now use a constant * fix wireup
This commit is contained in:
parent
53b57ff304
commit
39abeb8bf5
9 changed files with 107 additions and 53 deletions
|
|
@ -148,7 +148,6 @@ csharp_preserve_single_line_statements=true
|
|||
csharp_style_namespace_declarations=file_scoped:silent
|
||||
|
||||
[*]
|
||||
charset=utf-8
|
||||
end_of_line=lf
|
||||
trim_trailing_whitespace=false
|
||||
insert_final_newline=false
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ using System;
|
|||
using System.Threading;
|
||||
using Duende.Bff;
|
||||
using Duende.Bff.Yarp;
|
||||
using Hosts.ServiceDefaults;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
|
@ -58,7 +59,7 @@ internal static class Extensions
|
|||
// Normally, here you simply configure the authority. But here we want to
|
||||
// use service discovery, because aspire can change the url's at run-time.
|
||||
// So, it needs to be discovered at runtime.
|
||||
var authority = DiscoverAuthorityByName(getServiceProvider, "identity-server");
|
||||
var authority = DiscoverAuthorityByName(getServiceProvider, AppHostServices.IdentityServer);
|
||||
options.Authority = authority;
|
||||
|
||||
// confidential client using code flow + PKCE
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk.BlazorWebAssembly">
|
||||
<Project Sdk="Microsoft.NET.Sdk.BlazorWebAssembly">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net9.0</TargetFramework>
|
||||
|
|
@ -8,6 +8,9 @@
|
|||
<StaticWebAssetProjectMode>Default</StaticWebAssetProjectMode>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly"/>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.Authentication" />
|
||||
|
|
|
|||
|
|
@ -3,8 +3,16 @@ using Microsoft.AspNetCore.Components.WebAssembly.Hosting;
|
|||
|
||||
var builder = WebAssemblyHostBuilder.CreateDefault(args);
|
||||
|
||||
|
||||
builder.Services
|
||||
.AddBffBlazorClient() // Provides auth state provider that polls the /bff/user endpoint
|
||||
.AddCascadingAuthenticationState();
|
||||
|
||||
builder.Services.AddScoped(sp =>
|
||||
new HttpClient
|
||||
{
|
||||
BaseAddress = new Uri(builder.HostEnvironment.BaseAddress),
|
||||
DefaultRequestHeaders = { {"x-csrf", "1" }}
|
||||
});
|
||||
|
||||
await builder.Build().RunAsync();
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<Sdk Name="Aspire.AppHost.Sdk" Version="9.0.0" />
|
||||
|
||||
|
|
@ -15,6 +15,10 @@
|
|||
<PackageReference Include="Aspire.Hosting.AppHost" Version="9.0.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Hosts.ServiceDefaults\Hosts.ServiceDefaults.csproj" IsAspireProjectResource="false" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\migrations\UserSessionDb\UserSessionDb.csproj" />
|
||||
<ProjectReference Include="..\Apis\Api.DPoP\Api.DPoP.csproj" />
|
||||
|
|
|
|||
|
|
@ -1,47 +1,56 @@
|
|||
using Hosts.ServiceDefaults;
|
||||
using Projects;
|
||||
|
||||
var builder = DistributedApplication.CreateBuilder(args);
|
||||
|
||||
var idServer = builder.AddProject<Projects.IdentityServer>("identity-server");
|
||||
var idServer = builder.AddProject<Projects.IdentityServer>(AppHostServices.IdentityServer);
|
||||
|
||||
var api = builder.AddProject<Projects.Api>("api");
|
||||
var isolatedApi = builder.AddProject<Projects.Api_Isolated>("api-isolated");
|
||||
var api = builder.AddProject<Projects.Api>(AppHostServices.Api);
|
||||
var isolatedApi = builder.AddProject<Projects.Api_Isolated>(AppHostServices.IsolatedApi);
|
||||
|
||||
var bff = builder.AddProject<Projects.Bff>("bff")
|
||||
var bff = builder.AddProject<Projects.Bff>(AppHostServices.Bff)
|
||||
.WithExternalHttpEndpoints()
|
||||
.WithAwaitedReference(idServer)
|
||||
.WithAwaitedReference(isolatedApi)
|
||||
.WithAwaitedReference(api)
|
||||
;
|
||||
|
||||
builder.AddProject<Projects.Bff_EF>("bff-ef")
|
||||
var bffEf = builder.AddProject<Projects.Bff_EF>(AppHostServices.BffEf)
|
||||
.WithExternalHttpEndpoints()
|
||||
.WithAwaitedReference(idServer)
|
||||
.WithAwaitedReference(isolatedApi)
|
||||
.WithAwaitedReference(api);
|
||||
|
||||
builder.AddProject<Projects.WebAssembly>("bff-webassembly-per-component")
|
||||
var bffBlazorWebAssembly = builder.AddProject<Projects.WebAssembly>(AppHostServices.BffBlazorWebassembly)
|
||||
.WithExternalHttpEndpoints()
|
||||
.WithAwaitedReference(idServer)
|
||||
.WithAwaitedReference(isolatedApi)
|
||||
.WithAwaitedReference(api);
|
||||
|
||||
|
||||
|
||||
builder.AddProject<Projects.PerComponent>("bff-blazor-per-component")
|
||||
var bffBlazorPerComponent = builder.AddProject<Projects.PerComponent>(AppHostServices.BffBlazorPerComponent)
|
||||
.WithExternalHttpEndpoints()
|
||||
.WithAwaitedReference(idServer)
|
||||
.WithAwaitedReference(isolatedApi)
|
||||
.WithAwaitedReference(api);
|
||||
|
||||
var apiDPop = builder.AddProject<Projects.Api_DPoP>("api-dpop");
|
||||
var apiDPop = builder.AddProject<Projects.Api_DPoP>(AppHostServices.ApiDpop);
|
||||
|
||||
builder.AddProject<Projects.Bff_DPoP>("bff-dpop")
|
||||
var bffDPop = builder.AddProject<Projects.Bff_DPoP>(AppHostServices.BffDpop)
|
||||
.WithExternalHttpEndpoints()
|
||||
.WithAwaitedReference(idServer)
|
||||
.WithAwaitedReference(apiDPop);
|
||||
|
||||
builder.AddProject<Projects.UserSessionDb>("migrations");
|
||||
builder.AddProject<Projects.UserSessionDb>(AppHostServices.Migrations);
|
||||
|
||||
idServer.WithReference(bff);
|
||||
idServer
|
||||
.WithReference(bff)
|
||||
.WithReference(bffEf)
|
||||
.WithReference(bffBlazorPerComponent)
|
||||
.WithReference(bffBlazorWebAssembly)
|
||||
.WithReference(apiDPop)
|
||||
.WithReference(bffDPop)
|
||||
;
|
||||
|
||||
builder.Build().Run();
|
||||
|
||||
|
|
|
|||
34
bff/samples/Hosts.ServiceDefaults/AppHostServices.cs
Normal file
34
bff/samples/Hosts.ServiceDefaults/AppHostServices.cs
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Hosts.ServiceDefaults;
|
||||
public static class AppHostServices
|
||||
{
|
||||
public const string IdentityServer = "identity-server";
|
||||
public const string Api = "api";
|
||||
public const string IsolatedApi = "api-isolated";
|
||||
public const string Bff = "bff";
|
||||
public const string BffEf = "bff-ef";
|
||||
public const string BffBlazorWebassembly = "bff-blazor-webassembly";
|
||||
public const string BffBlazorPerComponent = "bff-blazor-per-component";
|
||||
public const string ApiDpop = "api-dpop";
|
||||
public const string BffDpop = "bff-dpop";
|
||||
public const string Migrations = "migrations";
|
||||
|
||||
public static string[] All => [
|
||||
IdentityServer,
|
||||
Api,
|
||||
IsolatedApi,
|
||||
Bff,
|
||||
BffEf,
|
||||
BffBlazorWebassembly,
|
||||
BffBlazorPerComponent,
|
||||
ApiDpop,
|
||||
BffDpop,
|
||||
Migrations
|
||||
];
|
||||
|
||||
}
|
||||
|
|
@ -1,4 +1,5 @@
|
|||
using Aspire.Hosting;
|
||||
using Hosts.ServiceDefaults;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
#if !DEBUG_NCRUNCH
|
||||
|
|
@ -81,33 +82,16 @@ public class AppHostFixture : IAsyncLifetime
|
|||
await (await appHost.BuildAsync()).StartAsync();
|
||||
|
||||
// Wait for all the services so that their logs are mostly written.
|
||||
await resourceNotificationService.WaitForResourceAsync(
|
||||
"bff",
|
||||
KnownResourceStates.Running
|
||||
)
|
||||
.WaitAsync(TimeSpan.FromSeconds(30));
|
||||
|
||||
await resourceNotificationService.WaitForResourceAsync(
|
||||
"bff-ef",
|
||||
KnownResourceStates.Running
|
||||
)
|
||||
.WaitAsync(TimeSpan.FromSeconds(30));
|
||||
foreach (var resource in AppHostServices.All)
|
||||
{
|
||||
await resourceNotificationService.WaitForResourceAsync(
|
||||
resource,
|
||||
KnownResourceStates.Running
|
||||
)
|
||||
.WaitAsync(TimeSpan.FromSeconds(30));
|
||||
}
|
||||
|
||||
await resourceNotificationService.WaitForResourceAsync(
|
||||
"bff-webassembly-per-component",
|
||||
KnownResourceStates.Running
|
||||
)
|
||||
.WaitAsync(TimeSpan.FromSeconds(30));
|
||||
await resourceNotificationService.WaitForResourceAsync(
|
||||
"bff-dpop",
|
||||
KnownResourceStates.Running
|
||||
)
|
||||
.WaitAsync(TimeSpan.FromSeconds(30));
|
||||
await resourceNotificationService.WaitForResourceAsync(
|
||||
"migrations",
|
||||
KnownResourceStates.Running
|
||||
)
|
||||
.WaitAsync(TimeSpan.FromSeconds(30));
|
||||
|
||||
#endif //#DEBUG_NCRUNCH
|
||||
}
|
||||
|
|
@ -166,7 +150,9 @@ public class AppHostFixture : IAsyncLifetime
|
|||
// so build a http client that directly points to this host.
|
||||
var url = clientName switch
|
||||
{
|
||||
"bff" => "https://localhost:5002",
|
||||
AppHostServices.Bff => "https://localhost:5002",
|
||||
AppHostServices.BffBlazorPerComponent => "https://localhost:5105",
|
||||
AppHostServices.BffBlazorWebassembly => "https://localhost:5005",
|
||||
_ => throw new InvalidOperationException("client not configured")
|
||||
};
|
||||
baseAddress = new Uri(url);
|
||||
|
|
|
|||
|
|
@ -1,9 +1,10 @@
|
|||
// // Copyright (c) Duende Software. All rights reserved.
|
||||
// // Copyright (c) Duende Software. All rights reserved.
|
||||
// // See LICENSE in the project root for license information.
|
||||
|
||||
using Duende.IdentityModel;
|
||||
using Duende.IdentityServer.Models;
|
||||
using Duende.IdentityServer.Stores;
|
||||
using Hosts.ServiceDefaults;
|
||||
using Microsoft.Extensions.ServiceDiscovery;
|
||||
|
||||
namespace IdentityServer;
|
||||
|
|
@ -32,7 +33,11 @@ public class ServiceDiscoveringClientStore(ServiceEndpointResolver resolver) : I
|
|||
return;
|
||||
}
|
||||
// Get the BFF URL from the service discovery system. Then use this for building the redirect urls etc..
|
||||
var bffUrl = (await resolver.GetEndpointsAsync("https://bff", CancellationToken.None)).Endpoints.First().EndPoint.ToString();
|
||||
var bffUrl = await GetUrlAsync(AppHostServices.Bff);
|
||||
var bffDPopUrl = await GetUrlAsync(AppHostServices.BffDpop);
|
||||
var bffEfUrl = await GetUrlAsync(AppHostServices.BffEf);
|
||||
var bffBlazorPerComponentUrl = await GetUrlAsync(AppHostServices.BffBlazorPerComponent);
|
||||
var bffBlazorWebAssemblyUrl = await GetUrlAsync(AppHostServices.BffBlazorWebassembly);
|
||||
|
||||
_clients = [
|
||||
new Client
|
||||
|
|
@ -69,9 +74,9 @@ public class ServiceDiscoveringClientStore(ServiceEndpointResolver resolver) : I
|
|||
OidcConstants.GrantTypes.TokenExchange
|
||||
},
|
||||
|
||||
RedirectUris = { "https://localhost:5003/signin-oidc" },
|
||||
FrontChannelLogoutUri = "https://localhost:5003/signout-oidc",
|
||||
PostLogoutRedirectUris = { "https://localhost:5003/signout-callback-oidc" },
|
||||
RedirectUris = { $"{bffDPopUrl}signin-oidc" },
|
||||
FrontChannelLogoutUri = $"{bffDPopUrl}signout-oidc",
|
||||
PostLogoutRedirectUris = { $"{bffDPopUrl}signout-callback-oidc" },
|
||||
|
||||
AllowOfflineAccess = true,
|
||||
AllowedScopes = { "openid", "profile", "api", "scope-for-isolated-api" },
|
||||
|
|
@ -89,10 +94,10 @@ public class ServiceDiscoveringClientStore(ServiceEndpointResolver resolver) : I
|
|||
GrantType.ClientCredentials,
|
||||
OidcConstants.GrantTypes.TokenExchange
|
||||
},
|
||||
RedirectUris = { "https://localhost:5004/signin-oidc" },
|
||||
FrontChannelLogoutUri = "https://localhost:5004/signout-oidc",
|
||||
BackChannelLogoutUri = "https://localhost:5004/bff/backchannel",
|
||||
PostLogoutRedirectUris = { "https://localhost:5004/signout-callback-oidc" },
|
||||
RedirectUris = { $"{bffEfUrl}signin-oidc" },
|
||||
FrontChannelLogoutUri = $"{bffEfUrl}signout-oidc",
|
||||
BackChannelLogoutUri = $"{bffEfUrl}bff/backchannel",
|
||||
PostLogoutRedirectUris = { $"{bffEfUrl}signout-callback-oidc" },
|
||||
|
||||
AllowOfflineAccess = true,
|
||||
AllowedScopes = { "openid", "profile", "api", "scope-for-isolated-api" },
|
||||
|
|
@ -112,10 +117,10 @@ public class ServiceDiscoveringClientStore(ServiceEndpointResolver resolver) : I
|
|||
OidcConstants.GrantTypes.TokenExchange
|
||||
},
|
||||
|
||||
RedirectUris = { "https://localhost:5005/signin-oidc", "https://localhost:5105/signin-oidc" },
|
||||
RedirectUris = { $"{bffBlazorWebAssemblyUrl}signin-oidc", $"{bffBlazorPerComponentUrl}signin-oidc" },
|
||||
PostLogoutRedirectUris =
|
||||
{
|
||||
"https://localhost:5005/signout-callback-oidc", "https://localhost:5105/signout-callback-oidc"
|
||||
$"{bffBlazorWebAssemblyUrl}signout-callback-oidc", $"{bffBlazorPerComponentUrl}signout-callback-oidc"
|
||||
},
|
||||
|
||||
AllowOfflineAccess = true,
|
||||
|
|
@ -132,6 +137,11 @@ public class ServiceDiscoveringClientStore(ServiceEndpointResolver resolver) : I
|
|||
|
||||
}
|
||||
|
||||
private async Task<string> GetUrlAsync(string serviceName)
|
||||
{
|
||||
return (await resolver.GetEndpointsAsync("https://" + serviceName, CancellationToken.None)).Endpoints.First().EndPoint.ToString();
|
||||
}
|
||||
|
||||
|
||||
public async Task<Client> FindClientByIdAsync(string clientId)
|
||||
{
|
||||
|
|
|
|||
Loading…
Reference in a new issue