mirror of
https://github.com/fiodarsazanavets/aspire-13-examples.git
synced 2026-06-20 12:23:14 +00:00
Add MailDev components
This commit is contained in:
@@ -0,0 +1,52 @@
|
||||
using Microsoft.AspNetCore.Authentication;
|
||||
using Microsoft.AspNetCore.Authentication.JwtBearer;
|
||||
using Microsoft.IdentityModel.Tokens;
|
||||
|
||||
namespace OnlineShop.ApiService
|
||||
{
|
||||
public static class AuthExtensions
|
||||
{
|
||||
public static void ConfigureApiJwt(this AuthenticationBuilder authentication)
|
||||
{
|
||||
// Named options
|
||||
authentication.Services
|
||||
.AddOptions<JwtBearerOptions>(
|
||||
JwtBearerDefaults.AuthenticationScheme)
|
||||
.Configure<
|
||||
IConfiguration,
|
||||
IHttpClientFactory,
|
||||
IHostEnvironment>(Configure);
|
||||
|
||||
// Unnamed options
|
||||
authentication.Services.AddOptions<JwtBearerOptions>()
|
||||
.Configure<
|
||||
IConfiguration,
|
||||
IHttpClientFactory,
|
||||
IHostEnvironment>(Configure);
|
||||
|
||||
static void Configure(
|
||||
JwtBearerOptions options,
|
||||
IConfiguration configuration,
|
||||
IHttpClientFactory httpClientFactory,
|
||||
IHostEnvironment hostEnvironment)
|
||||
{
|
||||
var backchannelHttpClient =
|
||||
httpClientFactory.CreateClient(
|
||||
"OidcBackchannel");
|
||||
|
||||
options.Backchannel = backchannelHttpClient;
|
||||
options.Authority =
|
||||
backchannelHttpClient
|
||||
.GetIdpAuthorityUri().ToString();
|
||||
options.RequireHttpsMetadata =
|
||||
!hostEnvironment.IsDevelopment();
|
||||
options.MapInboundClaims = false;
|
||||
options.TokenValidationParameters =
|
||||
new TokenValidationParameters
|
||||
{
|
||||
ValidateAudience = false
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -11,6 +11,7 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="10.0.0" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="10.0.0" />
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
@@ -1,17 +1,31 @@
|
||||
using Microsoft.AspNetCore.Authentication.JwtBearer;
|
||||
using OnlineShop.ApiService;
|
||||
|
||||
var builder = WebApplication.CreateBuilder(args);
|
||||
|
||||
// Add service defaults & Aspire client integrations.
|
||||
builder.AddServiceDefaults();
|
||||
|
||||
// Add services to the container.
|
||||
builder.Services.AddProblemDetails();
|
||||
|
||||
// Learn more about configuring OpenAPI at https://aka.ms/aspnet/openapi
|
||||
builder.Services.AddOpenApi();
|
||||
|
||||
builder.Services.AddHttpClient(
|
||||
"OidcBackchannel", o => o.BaseAddress = new("http://idp"));
|
||||
|
||||
builder.Services.AddAuthentication(options =>
|
||||
{
|
||||
options.DefaultAuthenticateScheme =
|
||||
JwtBearerDefaults.AuthenticationScheme;
|
||||
options.DefaultChallengeScheme =
|
||||
JwtBearerDefaults.AuthenticationScheme;
|
||||
|
||||
})
|
||||
.AddJwtBearer()
|
||||
.ConfigureApiJwt();
|
||||
|
||||
|
||||
var app = builder.Build();
|
||||
|
||||
// Configure the HTTP request pipeline.
|
||||
app.UseExceptionHandler();
|
||||
|
||||
if (app.Environment.IsDevelopment())
|
||||
|
||||
@@ -1,13 +1,17 @@
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using OnlineShop.AppHost.Extensions;
|
||||
using OnlineShop.MailDev.Hosting;
|
||||
|
||||
var builder = DistributedApplication.CreateBuilder(args);
|
||||
|
||||
var maildev = builder.AddMailDev("maildev");
|
||||
|
||||
var idp = builder.AddKeycloakContainer(
|
||||
"idp", tag: "23.0")
|
||||
.ImportRealms("Keycloak")
|
||||
.WithExternalHttpEndpoints();
|
||||
|
||||
var cache = builder.AddRedis("cache");
|
||||
|
||||
var apiService = builder.AddProject<Projects.OnlineShop_ApiService>("apiservice")
|
||||
.WithHttpHealthCheck("/health")
|
||||
@@ -21,7 +25,9 @@ var webFrontend = builder
|
||||
.WithHttpHealthCheck("/health")
|
||||
.WithReference(apiService)
|
||||
.WithReference(idp, env: "Identity__ClientSecret")
|
||||
.WaitFor(idp);
|
||||
.WaitFor(idp)
|
||||
.WithReference(cache)
|
||||
.WaitFor(cache);
|
||||
|
||||
if (builder.Environment.IsDevelopment())
|
||||
{
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<Project Sdk="Aspire.AppHost.Sdk/13.0.1">
|
||||
<Project Sdk="Aspire.AppHost.Sdk/13.0.1">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
@@ -8,11 +8,20 @@
|
||||
<UserSecretsId>2f2ef062-99af-422f-b6a5-1094759553e7</UserSecretsId>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Aspire.Hosting.Redis" Version="13.0.1" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\OnlineShop.ApiService\OnlineShop.ApiService.csproj" />
|
||||
<ProjectReference Include="..\OnlineShop.Web\OnlineShop.Web.csproj" />
|
||||
<ProjectReference
|
||||
Include="..\OnlineShop.MailDev.Hosting\OnlineShop.MailDev.Hosting.csproj"
|
||||
IsAspireProjectResource="false" />
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
|
||||
<ItemGroup>
|
||||
<None Update="Keycloak\import.json">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
namespace OnlineShop.MailDev.Hosting;
|
||||
|
||||
internal static class MailDevContainerImageTags
|
||||
{
|
||||
internal const string Registry = "docker.io";
|
||||
|
||||
internal const string Image = "maildev/maildev";
|
||||
|
||||
internal const string Tag = "2.1.0";
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
using Aspire.Hosting.ApplicationModel;
|
||||
|
||||
namespace OnlineShop.MailDev.Hosting;
|
||||
|
||||
public sealed class MailDevResource(string name) :
|
||||
ContainerResource(name), IResourceWithConnectionString
|
||||
{
|
||||
internal const string SmtpEndpointName = "smtp";
|
||||
internal const string HttpEndpointName = "http";
|
||||
|
||||
private EndpointReference? _smtpReference;
|
||||
|
||||
public EndpointReference SmtpEndpoint =>
|
||||
_smtpReference ??= new(this, SmtpEndpointName);
|
||||
|
||||
public ReferenceExpression ConnectionStringExpression =>
|
||||
ReferenceExpression.Create(
|
||||
$"smtp://{SmtpEndpoint.Property(EndpointProperty.Host)}:{SmtpEndpoint.Property(EndpointProperty.Port)}"
|
||||
);
|
||||
}
|
||||
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
using Aspire.Hosting;
|
||||
using Aspire.Hosting.ApplicationModel;
|
||||
|
||||
namespace OnlineShop.MailDev.Hosting;
|
||||
|
||||
public static class MailDevResourceBuilderExtensions
|
||||
{
|
||||
public static IResourceBuilder<MailDevResource> AddMailDev(
|
||||
this IDistributedApplicationBuilder builder,
|
||||
string name,
|
||||
int? httpPort = null,
|
||||
int? smtpPort = null)
|
||||
{
|
||||
MailDevResource resource = new(name);
|
||||
|
||||
return builder.AddResource(resource)
|
||||
.WithImage(MailDevContainerImageTags.Image)
|
||||
.WithImageRegistry(MailDevContainerImageTags.Registry)
|
||||
.WithImageTag(MailDevContainerImageTags.Tag)
|
||||
.WithHttpEndpoint(
|
||||
targetPort: 1080,
|
||||
port: httpPort,
|
||||
name: MailDevResource.HttpEndpointName)
|
||||
.WithEndpoint(
|
||||
targetPort: 1025,
|
||||
port: smtpPort,
|
||||
name: MailDevResource.SmtpEndpointName);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net10.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Aspire.Hosting" Version="13.0.1" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
@@ -0,0 +1,55 @@
|
||||
using Microsoft.AspNetCore.Authentication;
|
||||
using Microsoft.AspNetCore.Authentication.OpenIdConnect;
|
||||
using Microsoft.IdentityModel.Protocols.OpenIdConnect;
|
||||
|
||||
namespace OnlineShop.Web;
|
||||
|
||||
public static class AuthExtensions
|
||||
{
|
||||
public static void ConfigureWebAppOpenIdConnect(this AuthenticationBuilder authentication)
|
||||
{
|
||||
// Named options
|
||||
authentication.Services
|
||||
.AddOptions<OpenIdConnectOptions>(
|
||||
OpenIdConnectDefaults.AuthenticationScheme)
|
||||
.Configure<
|
||||
IConfiguration,
|
||||
IHttpClientFactory,
|
||||
IHostEnvironment>(Configure);
|
||||
|
||||
// Unnamed options
|
||||
authentication.Services.AddOptions<OpenIdConnectOptions>()
|
||||
.Configure<
|
||||
IConfiguration,
|
||||
IHttpClientFactory,
|
||||
IHostEnvironment>(Configure);
|
||||
|
||||
static void Configure(
|
||||
OpenIdConnectOptions options,
|
||||
IConfiguration configuration,
|
||||
IHttpClientFactory httpClientFactory,
|
||||
IHostEnvironment hostEnvironment)
|
||||
{
|
||||
var backchannelHttpClient =
|
||||
httpClientFactory.CreateClient(
|
||||
"OidcBackchannel");
|
||||
|
||||
options.Backchannel = backchannelHttpClient;
|
||||
options.Authority =
|
||||
backchannelHttpClient
|
||||
.GetIdpAuthorityUri().ToString();
|
||||
options.ClientId = "webapp";
|
||||
options.ClientSecret =
|
||||
Environment
|
||||
.GetEnvironmentVariable(
|
||||
"Identity__ClientSecret");
|
||||
options.ResponseType =
|
||||
OpenIdConnectResponseType.Code;
|
||||
options.SaveTokens = true;
|
||||
options.RequireHttpsMetadata =
|
||||
!hostEnvironment.IsDevelopment();
|
||||
options.MapInboundClaims = false;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -6,6 +6,11 @@
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Aspire.StackExchange.Redis.OutputCaching" Version="13.0.1" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Authentication.OpenIdConnect" Version="10.0.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\OnlineShop.ServiceDefaults\OnlineShop.ServiceDefaults.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
@@ -1,30 +1,45 @@
|
||||
using Microsoft.AspNetCore.Authentication.Cookies;
|
||||
using Microsoft.AspNetCore.Authentication.OpenIdConnect;
|
||||
using OnlineShop.Web;
|
||||
using OnlineShop.Web.Components;
|
||||
|
||||
var builder = WebApplication.CreateBuilder(args);
|
||||
|
||||
// Add service defaults & Aspire client integrations.
|
||||
builder.AddRedisOutputCache("cache");
|
||||
|
||||
builder.AddServiceDefaults();
|
||||
|
||||
// Add services to the container.
|
||||
builder.Services.AddRazorComponents()
|
||||
.AddInteractiveServerComponents();
|
||||
|
||||
builder.Services.AddOutputCache();
|
||||
|
||||
builder.Services.AddHttpClient(
|
||||
"OidcBackchannel", o => o.BaseAddress = new("http://idp"));
|
||||
|
||||
builder.Services.AddHttpClient<WeatherApiClient>(client =>
|
||||
{
|
||||
// This URL uses "https+http://" to indicate HTTPS is preferred over HTTP.
|
||||
// Learn more about service discovery scheme resolution at https://aka.ms/dotnet/sdschemes.
|
||||
client.BaseAddress = new("https+http://apiservice");
|
||||
});
|
||||
|
||||
builder.Services.AddAuthentication(options =>
|
||||
{
|
||||
options.DefaultScheme =
|
||||
CookieAuthenticationDefaults.AuthenticationScheme;
|
||||
options.DefaultChallengeScheme =
|
||||
OpenIdConnectDefaults.AuthenticationScheme;
|
||||
})
|
||||
.AddCookie(
|
||||
CookieAuthenticationDefaults.AuthenticationScheme)
|
||||
.AddOpenIdConnect()
|
||||
.ConfigureWebAppOpenIdConnect();
|
||||
|
||||
|
||||
var app = builder.Build();
|
||||
|
||||
if (!app.Environment.IsDevelopment())
|
||||
{
|
||||
app.UseExceptionHandler("/Error", createScopeForErrors: true);
|
||||
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
|
||||
app.UseHsts();
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
<Solution>
|
||||
<Project Path="OnlineShop.ApiService/OnlineShop.ApiService.csproj" />
|
||||
<Project Path="OnlineShop.AppHost/OnlineShop.AppHost.csproj" />
|
||||
<Project Path="OnlineShop.MailDev.Hosting/OnlineShop.MailDev.Hosting.csproj" Id="bcd7a762-a5a4-4043-9990-a00cca6b4a91" />
|
||||
<Project Path="OnlineShop.ServiceDefaults/OnlineShop.ServiceDefaults.csproj" />
|
||||
<Project Path="OnlineShop.Web/OnlineShop.Web.csproj" />
|
||||
</Solution>
|
||||
|
||||
Reference in New Issue
Block a user