For the complete documentation index, see llms.txt. This page is also available as Markdown.

Elsa Studio

In this topic, we will create a separate ASP.NET Blazor Webassembly app and turn it into an Elsa Studio that connects to an Elsa Server.

Elsa Studio is a Blazor application that let's you manage workflows through a UI. The application is essentially a SPA that connects to an Elsa Server as its back-end.

Setup

To setup Elsa Studio, we'll go through the following steps:

  1. Create a New Blazor Webassembly App

    Execute the following command in the terminal:

    dotnet new blazorwasm -n "ElsaStudioBlazorWasm" --framework net10.0

    \

  2. Add Elsa Studio Packages

    Navigate to the root directory of your project and integrate the following Elsa Studio packages:

    cd ElsaStudioBlazorWasm
    dotnet add package Elsa.Studio --version 3.9.0
    dotnet add package Elsa.Studio.Authentication.UI --version 3.9.0
    dotnet add package Elsa.Studio.Core.BlazorWasm --version 3.9.0
    dotnet add package Elsa.Studio.Authentication.ElsaIdentity.BlazorWasm --version 3.9.0
    dotnet add package Elsa.Studio.Authentication.ElsaIdentity.UI --version 3.9.0
    dotnet add package Elsa.Studio.Authentication.OpenIdConnect.BlazorWasm --version 3.9.0
    dotnet add package Elsa.Studio.Localization.BlazorWasm --version 3.9.0
    dotnet add package Elsa.Api.Client --version 3.9.0
    dotnet add package Microsoft.AspNetCore.Components.WebAssembly --version 10.0.8
    dotnet add package Microsoft.AspNetCore.Components.WebAssembly.Authentication --version 10.0.8
  3. Modify Program.cs

    Open the Program.cs file and replace its existing content with the code provided below:

    Program.cs

    using Elsa.Studio.Authentication.Abstractions.Models;
    using Elsa.Studio.Authentication.UI.Extensions;
    using Elsa.Studio.Authentication.ElsaIdentity.BlazorWasm.Extensions;
    using Elsa.Studio.Authentication.ElsaIdentity.HttpMessageHandlers;
    using Elsa.Studio.Authentication.ElsaIdentity.UI.Extensions;
    using Elsa.Studio.Authentication.OpenIdConnect.BlazorWasm.Extensions;
    using Elsa.Studio.Authentication.OpenIdConnect.HttpMessageHandlers;
    using Elsa.Studio.Contracts;
    using Elsa.Studio.Core.BlazorWasm.Extensions;
    using Elsa.Studio.Dashboard.Extensions;
    using Elsa.Studio.Extensions;
    using Elsa.Studio.Localization.BlazorWasm.Extensions;
    using Elsa.Studio.Localization.Models;
    using Elsa.Studio.Models;
    using Elsa.Studio.Shell;
    using Elsa.Studio.Shell.Extensions;
    using Elsa.Studio.Workflows.Designer.Extensions;
    using Elsa.Studio.Workflows.Extensions;
    using Microsoft.AspNetCore.Components.Web;
    using Microsoft.AspNetCore.Components.WebAssembly.Hosting;
    
    // Build the host.
    var builder = WebAssemblyHostBuilder.CreateDefault(args);
    var configuration = builder.Configuration;
    
    // Register root components.
    builder.RootComponents.Add<App>("#app");
    builder.RootComponents.Add<HeadOutlet>("head::after");
    builder.RootComponents.RegisterCustomElsaStudioElements();
    
    // Choose authentication provider.
    // Supported values: "OpenIdConnect" or "ElsaIdentity".
    var authProvider = configuration["Authentication:Provider"];
    if (string.IsNullOrWhiteSpace(authProvider))
        authProvider = "ElsaIdentity";
    
    if (!Enum.TryParse<StudioAuthenticationProvider>(authProvider, true, out var selectedAuthProvider))
        throw new InvalidOperationException($"Unsupported authentication provider: {authProvider}");
    builder.Services.AddStudioAuthenticationMode(options => options.Provider = selectedAuthProvider);
    
    Type authenticationHandler;
    
    if (authProvider.Equals("ElsaIdentity", StringComparison.OrdinalIgnoreCase))
    {
        // Elsa Identity (username/password against Elsa backend) + login UI at /login.
        builder.Services.AddElsaIdentity();
        builder.Services.AddElsaIdentityUI();
        authenticationHandler = typeof(ElsaIdentityAuthenticatingApiHttpMessageHandler);
    }
    else if (authProvider.Equals("OpenIdConnect", StringComparison.OrdinalIgnoreCase))
    {
        // OpenID Connect.
        builder.Services.AddOpenIdConnectAuth(options =>
        {
            configuration.GetSection("Authentication:OpenIdConnect").Bind(options);
        });
        authenticationHandler = typeof(OidcAuthenticatingApiHttpMessageHandler);
    }
    else
    {
        throw new InvalidOperationException($"Unsupported Authentication:Provider value '{authProvider}'. Supported values are 'OpenIdConnect' and 'ElsaIdentity'.");
    }
    
    // Register shell services and modules.
    var backendApiConfig = new BackendApiConfig
    {
        ConfigureBackendOptions = options => builder.Configuration.GetSection("Backend").Bind(options),
        ConfigureHttpClientBuilder = options => options.AuthenticationHandler = authenticationHandler
    };
    
    var localizationConfig = new LocalizationConfig
    {
        ConfigureLocalizationOptions = options => configuration.GetSection("Localization").Bind(options)
    };
    
    builder.Services.AddCore();
    builder.Services.AddShell();
    builder.Services.AddAuthenticationUI(); // Registers the shared /login page and its services.
    builder.Services.AddRemoteBackend(backendApiConfig);
    builder.Services.AddDashboardModule(backendApiConfig);
    builder.Services.AddWorkflowsModule();
    builder.Services.AddLocalizationModule(localizationConfig);
    
    // Build the application.
    var app = builder.Build();
    
    await app.UseElsaLocalization();
    
    // Run each startup task.
    var startupTaskRunner = app.Services.GetRequiredService<IStartupTaskRunner>();
    await startupTaskRunner.RunStartupTasksAsync();
    
    // Run the application.
    await app.RunAsync();

AddDashboardModule() registers the Studio dashboard UI. The connected Elsa Server must also install Elsa.Dashboard.Api and Elsa.Workflows.Runtime.Dashboard at version 3.9.0, then enable UseDashboardApi() and UseWorkflowRuntimeDashboard() in its AddElsa configuration. Without those server modules, Studio can load but its operational dashboard has no workflow runtime data.

  1. Remove Unnecessary Files

    For a cleaner project structure, delete the following directories and files:

    • wwwroot/css

    • Pages

    • App.razor

    • MainLayout.razor

    • MainLayout.razor.css

    • _Imports.razor

  2. Generate appsettings.json

    Within the wwwroot directory, create a new appsettings.json file and populate it with the following content:

    wwwroot/appsettings.json

    The sample selects ElsaIdentity to use the configured server administrator. To use an external identity provider, set Provider to OpenIdConnect and replace the OpenID Connect placeholders.

    AuthenticationScopes are used during Studio sign-in. BackendApiScopes are used when Studio requests bearer tokens for Elsa Server API calls.

    Because this example is a Blazor WebAssembly host, register {studio-url}/authentication/login-callback as the redirect URI and {studio-url}/authentication/logout-callback as the logout callback URI. Studio initiates logout at {studio-url}/authentication/logout.

  3. Update index.html

    To conclude the setup, open the index.html file and replace its content with the code showcased below:

    wwwroot/index.html

Launch the Application

To see your application in action, execute the following command:

Your application is now accessible at https://localhost:6001.

The server controls the available users and roles. Configure an administrator through the server's identity provider before signing in; do not rely on a hard-coded admin/password pair. The Elsa Identity guide shows the configuration shape.

Source Code

The source code for this chapter can be found here

Last updated