Skip to content

App startup configure pipeline

This operation assembles the HTTP request pipeline for web applications: request buffering, session, error/debug handling, authentication, OIDC-related middleware, HSTS/HTTPS redirection, static files, routing, authorization, and application-specific UI wiring.

Field Value
Operation ID OP-15
Trigger The ASP.NET Core host calls Configure(IApplicationBuilder app, IWebHostEnvironment env) on an AppStartup-derived class.
Inputs The IApplicationBuilder; AppStartup's instance flags.
Outputs A fully composed HTTP request pipeline.
Primary components AppStartup.Configure
Entry point src/SAIF.NetCore.ServiceExtensions/SAIF.NetCore.ServiceExtensions/SAIF.NetCore.ServiceExtensions/Startup/AppStartup.cs (L144–190)

Steps

  1. Register a lambda that calls Request.EnableBuffering() for every request.
  2. If EnableSessionMiddleware: UseSession(), UseMiddleware<AspNetSessionIdMiddleware>() (BR-SE-17)
  3. See Legacy cookie gate middleware for AspNetSessionIdMiddleware's fail-open behavior.
  4. ConfigureErrorHandling().ConfigureDebugRequestHandling() wires Dynamic error handler invocation and Debug request handler invocation (BR-SE-13)
  5. UseAuthentication().
  6. If HostLocation == External: LowerCaseUrlMiddleware is wired only if AuthenticationChallengeType == OpenIdConnect; JwtClaimMiddleware is wired unconditionally (and runs after LowerCaseUrlMiddleware when both are present); RefreshJwtMiddleware is wired only if UseJwtRefreshMiddleware — the three conditions are independent, but pipeline order is fixed as lower-case URL, then JWT claims, then refresh (BR-SE-10)

Origin: JwtClaimMiddleware and RefreshJwtMiddleware's own request-handling logic is implemented in Sync JWT claims and Refresh tokens (SAIF.NetCore.OIDC); LowerCaseUrlMiddleware's logic is in Enforce URL casing. 6. UseHsts() always runs; if EnforceSslRedirect: UseHttpsRedirection() (BR-SE-19) 7. UseStaticFiles(), UseRouting(), ConfigureAuthorization() (virtual method, default implementation calls UseAuthorization()), ConfigureUI() (abstract — implemented by OidcMvcStartup/OidcRazorStartup, see OIDC MVC and Razor startup), then ConfigureSaifLogger() (IAppBuilderExtensions.cs), which resolves ISaifLogService, IEnvironmentClient, IHttpJsonClient, and IHttpContextAccessor from app.ApplicationServices and calls loggingService.Configure(environmentClient, apiLogClient, contextAccessor) synchronously, as the final step of Configure.

Origin: loggingService.Configure(...) resolves to SaifLog.Configure (SAIF.NetCore.Logging), whose own setup/override/correlation-ID machinery is documented in full on OP-01: Configure the web logger (SaifLog) and executed synchronously on behalf of this step. In outline: it resolves the base log threshold from the Environment API (falling back to tracingdefaults:logthreshold), builds the standard ApiLoggerConfig/EventLogConfig sink configurations and applies any SaifLogging:BaseLevel/SaifLogging:Loggers appsettings.json overrides, sets ExFormatService to a new ExceptionFormatServiceForWeb(environmentClient, httpContext) (the web-specific exception formatter this step's IHttpContextAccessor argument feeds), calls Log.CloseAndFlush() to close out any prior logger, reads tracingdefaults:loggingapiurl/logroute/logerrorroute from the Environment API and pushes them into the injected IHttpJsonClient, builds the Serilog logger (Event Log sink, LoggingApiSink, Console sink), and finally sets IsConfigured = true so subsequent log calls are accepted. The type-level reference is SaifLog (SAIF.NetCore.Logging).

Process flow

This diagram shows the request-pipeline assembly performed once, synchronously, by Configure during host startup — not per-request middleware execution order beyond what each Use* call wires in.

flowchart TD
    Start([Configure invoked]) --> S1[Enable request buffering]
    S1 --> S2{EnableSessionMiddleware?}
    S2 -->|Yes| S2a["UseSession + AspNetSessionIdMiddleware"]
    S2 -->|No| S3["ConfigureErrorHandling + ConfigureDebugRequestHandling"]
    S2a --> S3
    S3 --> S4[UseAuthentication]
    S4 --> S5{HostLocation == External?}
    S5 -->|Yes| S5b{AuthenticationChallengeType == OpenIdConnect?}
    S5b -->|Yes| S5c[LowerCaseUrlMiddleware]
    S5b -->|No| S5a["JwtClaimMiddleware (always)"]
    S5c --> S5a
    S5a --> S5d{UseJwtRefreshMiddleware?}
    S5d -->|Yes| S5e[RefreshJwtMiddleware]
    S5d -->|No| S6[UseHsts]
    S5e --> S6
    S5 -->|No| S6
    S6 --> S7{EnforceSslRedirect?}
    S7 -->|Yes| S7a[UseHttpsRedirection]
    S7 -->|No| S8["UseStaticFiles / UseRouting / ConfigureAuthorization /<br>ConfigureUI"]
    S7a --> S8
    S8 --> S9["ConfigureSaifLogger resolves services<br>and configures ISaifLogService"]
    S9 --> EndOk([Pipeline fully composed])

Failure and edge-case behavior

  • ConfigureAuthorization is virtual, so a derived Startup class can replace the default UseAuthorization() call.
  • ConfigureUI is abstract and must be implemented by the concrete Startup type (OIDC MVC and Razor startup).

Sources

  • src/SAIF.NetCore.ServiceExtensions/SAIF.NetCore.ServiceExtensions/SAIF.NetCore.ServiceExtensions/Startup/AppStartup.cs