elsa-core icon indicating copy to clipboard operation
elsa-core copied to clipboard

[Elsa 3.x] Elsa Server in Blazor server app

Open Defkon1 opened this issue 7 months ago • 1 comments

I'm trying to expose Elsa Server API in a Blazor server app, but localhost:<myport>/elsa/api always give 404... what's wrong with my configuration?

//[omiss using]

var builder = WebApplication.CreateBuilder(args);

builder.Host.UseSerilog((hostingContext, services, loggerConfiguration) =>
{
    loggerConfiguration
        .ReadFrom.Configuration(hostingContext.Configuration)
                .ReadFrom.Services(services)
                .Enrich.FromLogContext()
                .WriteTo.Console();
});

builder.Services.AddRazorPages();
builder.Services.AddRazorComponents()
    .AddInteractiveServerComponents();

builder.Services.AddDbContext<DataContext>(options =>
{
    // omissis
}, ServiceLifetime.Transient);

// omissis

builder.Services
    .AddElsa(elsa => elsa
        .UseIdentity(identity =>
        {
            identity.TokenOptions = options => options.SigningKey = "large-signing-key-for-signing-JWT-tokens";
            identity.UseAdminUserProvider();
        })
        .UseDefaultAuthentication()
        .UseWorkflowManagement(management => management.UseEntityFrameworkCore(ef => ef.UsePostgreSql(builder.Configuration.GetConnectionString("PgConnection"))))
        .UseWorkflowRuntime(runtime => runtime.UseEntityFrameworkCore(ef => ef.UsePostgreSql(builder.Configuration.GetConnectionString("PgConnection"))))
        .UseScheduling()
        .UseJavaScript()
        .UseLiquid()
        .UseCSharp()
        .UseHttp(http => http.ConfigureHttpOptions = options => builder.Configuration.GetSection("Elsa:Server").Bind(options))
        .UseWorkflowsApi()
        .UseWorkflows()
        .UseRealTimeWorkflows()
        .AddActivitiesFrom<Program>()
        .AddWorkflowsFrom<Program>()
    );

builder.Services.AddCors(cors => cors
    .AddDefaultPolicy(policy => policy
        .AllowAnyOrigin() // For demo purposes only. Use a specific origin instead.
        .AllowAnyHeader()
        .AllowAnyMethod()
        .WithExposedHeaders("x-elsa-workflow-instance-id")));

builder.Services.AddHealthChecks();

var app = builder.Build();

// Configure the HTTP request pipeline.
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();
}

app.UseCors();

app.UseHttpsRedirection();

app.UseAuthentication();
app.UseAuthorization();
app.UseAntiforgery();

app.MapStaticAssets();
app.MapRazorComponents<App>()
    .AddInteractiveServerRenderMode();

app.UseWorkflowsApi();
app.UseWorkflows();

app.Run();

Thanks in advance for any hints!

Defkon1 avatar Apr 10 '25 14:04 Defkon1

Nothing jumps out at me - you are correctly calling app.UseWorkflowsApi(). If you want, you can attach a (simplified) project to this issue and I can take a look. Also, it would be a nice sample t add to the elsa-samples repository's blazor folder.

sfmskywalker avatar Apr 13 '25 19:04 sfmskywalker

@sfmskywalker , I have similar issue, but I want to address something different in details. My existing Blazor Sever project is already using Microsoft Entra as OpenId Connect identity provider, just like:

builder.Services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme).AddCookie("MicrosoftOidc")
    .AddMicrosoftIdentityWebApp(oidcOptions =>
    {
        builder.Configuration.Bind("AzureAd", oidcOptions);
        oidcOptions.ResponseType = OpenIdConnectResponseType.Code;
        oidcOptions.MapInboundClaims = false;
        oidcOptions.GetClaimsFromUserInfoEndpoint = false;
        oidcOptions.TokenValidationParameters.NameClaimType = JwtRegisteredClaimNames.Name;
        oidcOptions.TokenValidationParameters.RoleClaimType = "role";
        oidcOptions.Events.OnTokenValidated += OpenIdConnectEventsHandler.OnTokenValidatedFunc;
    })
    .EnableTokenAcquisitionToCallDownstreamApi()
    .AddMicrosoftGraph(builder.Configuration.GetSection("DownstreamApi"))
    .AddInMemoryTokenCaches();

So I want the Token issued against Blazor Server would also be available for Elsa Workflow API integrated in the same Blazor Server project, so I wonder there shall be something different in UserIdentity method to set-up correctly.

I don't know how to do it though.

LinQiaoPorco avatar Aug 12 '25 10:08 LinQiaoPorco