Bridging the Gap: Connecting React (Azure SWA) to a Secured .NET 8 API


Deploying a modern full-stack web application into production requires a clean separation of concerns. In Part 1, we hardened a .NET 8 Minimal API backend using Role-Based Access Control (RBAC) and deployed it to Azure App Service via GitHub Actions.

Today, we take the architecture full-stack by introducing a highly responsive React user interface styled with Material-UI, hosted globally via Azure Static Web Apps (SWA), and bound directly to our live Azure cloud engine.

This is Part 2 of a two-part series. Start with Part 1 — Hardening .NET Minimal APIs: Shifting from Local Dev to Azure-backed RBAC — to follow the backend setup from scratch.


The Full-Stack Demo

The integrated environment is live and communicating across cloud domains. Explore the running build or inspect the split-repository source pipelines below:


Distributed Cloud Architecture

To maximize efficiency and eliminate unnecessary server overhead, we decoupled our client layers from our logic compute blocks. The system operates across two isolated Azure environments:

graph LR
    subgraph Client Space (CDN Edge)
        A[React SWA UI] -->|HTTPS Requests + Credentials| B(.NET 8 App Service)
    end
    subgraph Compute Space (Azure Core)
        B -->|Validates Session| C[Secure Endpoints]
        B -.->|SameSite=None Cookie| A
    end
    style A fill:#61dafb,stroke:#333,stroke-width:2px,color:#000
    style B fill:#512bd4,stroke:#333,stroke-width:2px,color:#fff

Because our frontend and backend run on distinct Azure service structures, they communicate across entirely separate domains. By default, standard security contexts block authentication tokens from tracking across unmapped endpoints.

To overcome this without resorting to unsecure local storage tokens, we shifted our .NET architecture to enforce explicit trust guidelines:

SameSiteMode.None + forced SSL to permit cross-domain browser cookie persistence.

AllowCredentials() within CORS to authorize Axios asynchronous calls to inherit background session authorization rules natively.

    1. Updating the .NET Security Gates To safely handshake with our remote React build, we modified Program.cs to handle incoming cross-origin headers gracefully:
builder.Services.AddCors(options =>
{
    options.AddPolicy("ReactAppPolicy", policy =>
    {
        policy.WithOrigins("[https://your-react-app-name.azurestaticapps.net](https://your-react-app-name.azurestaticapps.net)")
              .AllowAnyHeader()
              .AllowAnyMethod()
              .AllowCredentials(); // Essential for cross-origin cookie passing
    });
});

builder.Services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
    .AddCookie(options =>
    {
        options.Cookie.Name = "GatekeeperSession";
        options.Cookie.HttpOnly = true;
        options.Cookie.SameSite = SameSiteMode.None; // Required for cross-domain
        options.Cookie.SecurePolicy = CookieSecurePolicy.Always; // Required for SameSite=None
    });
    1. Injecting Compilation Variables via GitHub Actions Because static web environments compile application scripts completely down to minimized browser assets prior to runtime distribution, standard server-side configuration mapping is unreachable. Instead, we injected our backend variables directly into our delivery pipelines via encrypted GitHub Repository Secrets.

Our automated workflow file (.github/workflows/azure-static-web-apps.yml) intercepts these fields smoothly during build execution:

      - name: Build And Deploy
        id: builddeploy
        uses: Azure/static-web-apps-deploy@v1
        with:
          azure_static_web_apps_api_token: $
          action: "upload"
          app_location: "/"
          output_location: "build"
        env:
          REACT_APP_API_BASE: $

Now, when our Axios wrapper calls process.env.REACT_APP_API_BASE, it hooks directly into our cloud architecture instantly.

Key Takeaways

By isolating our stateless UI layers from our analytical engines, we achieve:

  • Near-Zero Hosting Costs: Running client distributions globally over free CDN edges.

  • Hardened Security: Retaining stateful cookie boundaries while preventing manual script intervention or security leaks.

  • Continuous Delivery: Automated pipeline testing maps, builds, and distributes downstream adjustments every single time code drops onto a tracked repository.


The Full Series

Part 1: Hardening .NET Minimal APIs: Shifting from Local Dev to Azure-backed RBAC — RBAC middleware, cookie auth, and GitHub Actions deployment to Azure App Service.

Part 2: You are here — React on Azure SWA, CORS configuration, and cross-domain cookie authentication.




Enjoy Reading This Article?

Here are some more articles you might like to read next:

  • Migrating marketingPy from Docker Compose to AWS Lambda
  • Hardening .NET Minimal APIs: Shifting from Local Dev to Azure-backed RBAC
  • Google Calendar API Bidirectionally with Full Calendar in a Multi-Tenant Booking Engines
  • How to restrict Multi-Tenant Bookings + Google Accounts Separation
  • Setting Up Google Calendar API & OAuth 2.0 for Multi-Tenant Booking Engines