| layout | post |
|---|---|
| title | Blazor with JWT Authentication | Syncfusion® |
| description | Guide to setting up JWT authentication for Syncfusion® Blazor DataGrid with secure API access and token handling. |
| platform | Blazor |
| control | Common |
| documentation | ug |
This guide shows how to secure the Syncfusion® Blazor DataGrid in a Blazor Web App with Interactive Server using JWT (JSON Web Token) authentication.
A JSON Web Token (JWT) is a compact, digitally signed string that identifies a user and authorizes API calls. It has three parts:
- Header – specifies the token type and the signing algorithm used.
- Payload – contains claims (e.g.,
sub,name,role,exp). - Signature – computed using the header, payload, and secret (or private key) to prevent tampering.
Syncfusion® Blazor components make HTTP requests to your API internally. JWT allows each request to carry a trusted identity and prevents unauthorized access without relying on server-side session state.
Benefits of using JWT in Blazor applications
JWT allows users to log in once and securely access APIs, controls features based on user roles, maintain authentication while navigating between pages, ensure secure communication between client and server, and supports large‑scale applications without storing login sessions on the server.
Configure JWT based authorization to secure backend APIs used by the Syncfusion® Blazor DataGrid in a Blazor App, ensuring that each DataGrid request includes a valid bearer token for authorized access.
If you already have a Blazor project configured, you can skip this section and proceed to Install required packages.
Otherwise, create a new Blazor application by following the Syncfusion getting started guides Blazor Web App (Interactive Server)
Ensure that HTTPS is enabled during project creation, as JWT based authorization requires secure communication.
Open the NuGet Package Manager in Visual Studio from (Tools → NuGet Package Manager → Manage NuGet Packages for Solution), and install the required package.
Syncfusion packages:
JWT package:
Open the ~/_Imports.razor file and import the Syncfusion® namespaces.
{% tabs %} {% highlight razor tabtitle="~/_Imports.razor" %}
@using Syncfusion.Blazor @using Syncfusion.Blazor.Grids @using Syncfusion.Blazor.Data
{% endhighlight %} {% endtabs %}
Include the Syncfusion® theme stylesheet, required script references, and configure Interactive Server rendering in the App.razor file.
{% tabs %} {% highlight razor tabtitle="App.razor" %}
<script src="_content/Syncfusion.Blazor.Core/scripts/syncfusion-blazor.min.js" type="text/javascript"></script>{% endhighlight %} {% endtabs %}
The JWT configuration specifies how the server signs and validates authentication tokens.
{% tabs %} {% highlight json tabtitle="appsettings.json" %}
{ "Jwt": { "Key": "REPLACE_WITH_A_LONG_RANDOM_SECRET_32+_CHARS", "Issuer": "BlazorJWT", "Audience": "BlazorJWTClient" } }
{% endhighlight %} {% endtabs %}
N> For production environments, do not store secrets directly in appsettings.json. Use environment variables or a secure secret store such as Azure Key Vault to protect sensitive information.
This section demonstrates how to generate a JWT token on the server by using a custom TokenService class.
{% tabs %} {% highlight c# tabtitle="Services/TokenService.cs" %}
using System.IdentityModel.Tokens.Jwt; using System.Security.Claims; using System.Text; using Microsoft.IdentityModel.Tokens; using Microsoft.Extensions.Configuration;
namespace YourProjectName.Services { public class TokenService { private readonly IConfiguration _config; public TokenService(IConfiguration config) => _config = config;
public string IssueToken(string subjectUserId, string? name = null)
{
var issuer = _config["Jwt:Issuer"]!;
var audience = _config["Jwt:Audience"]!;
var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_config["Jwt:Key"]!));
var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
var claims = new List<Claim>
{
new(JwtRegisteredClaimNames.Sub, subjectUserId),
new(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()),
};
if (!string.IsNullOrWhiteSpace(name))
{
claims.Add(new Claim(ClaimTypes.Name, name));
}
var token = new JwtSecurityToken(
issuer: issuer,
audience: audience,
claims: claims,
notBefore: DateTime.UtcNow.AddMinutes(-1),
expires: DateTime.UtcNow.AddMinutes(30),
signingCredentials: creds);
return new JwtSecurityTokenHandler().WriteToken(token);
}
}
}
{% endhighlight %} {% endtabs %}
This section describes how the application issues a JSON Web Token (JWT) for authenticated access. The AuthController class provides an API endpoint that generates and returns a JWT for the requesting user.
{% tabs %} {% highlight c# tabtitle="~/Controllers/AuthController.cs" %}
using YourProjectName.Services; using Microsoft.AspNetCore.Mvc;
namespace YourProjectName.Controllers;
[ApiController] [Route("api/[controller]")] public class AuthController : ControllerBase { private readonly TokenService _tokenService; public AuthController(TokenService tokenService) => _tokenService = tokenService;
[HttpPost("token")]
public IActionResult Token([FromQuery] string user = "user123")
{
var jwt = _tokenService.IssueToken(user, name: user);
return Ok(new { token = jwt });
}
}
{% endhighlight %} {% endtabs %}
Register JWT authentication and authorization middleware to validate incoming API requests. Add these configurations in Program.cs.
{% tabs %} {% highlight razor tabtitle="~/Program.cs" %}
using System.Text; using YourProjectName.Components; using YourProjectName.Services; using Microsoft.AspNetCore.Authentication.JwtBearer; using Microsoft.IdentityModel.Tokens; using Syncfusion.Blazor;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorComponents() .AddInteractiveServerComponents(); builder.Services.AddControllers(); builder.Services.AddHttpClient();
// Register the Syncfusion® Blazor service builder.Services.AddSyncfusionBlazor();
var jwtKey = builder.Configuration["Jwt:Key"] ?? throw new InvalidOperationException("Jwt:Key missing");
builder.Services .AddAuthentication(JwtBearerDefaults.AuthenticationScheme) .AddJwtBearer(options => { options.TokenValidationParameters = new TokenValidationParameters { ValidateIssuer = true, ValidateAudience = true, ValidateIssuerSigningKey = true, ValidateLifetime = true, ClockSkew = TimeSpan.FromMinutes(5), ValidIssuer = builder.Configuration["Jwt:Issuer"], ValidAudience = builder.Configuration["Jwt:Audience"], IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(jwtKey)) }; });
builder.Services.AddAuthorization(); builder.Services.AddSingleton();
var app = builder.Build();
app.UseHttpsRedirection(); app.UseStaticFiles(); app.UseAuthentication(); app.UseAuthorization(); app.UseAntiforgery(); app.MapControllers(); app.MapRazorComponents() .AddInteractiveServerRenderMode(); app.Run();
{% endhighlight %} {% endtabs %}
Create sample records for the DataGrid in ~/Models/OrdersDetails.cs file.
{% tabs %} {% highlight c# tabtitle="~/Models/OrdersDetails.cs" %}
namespace YourProjectName.Models;
public class OrdersDetails { public int OrderID { get; set; } public string? CustomerID { get; set; } public string? ShipCity { get; set; } public string? ShipCountry { get; set; } private static List? _data; public static List GetAllRecords() { if (_data is null) { _data = Enumerable.Range(1, 50).Select(i => new OrdersDetails { OrderID = i, CustomerID = $"CUST-{i:000}", ShipCity = i % 2 == 0 ? "Chennai" : "Bengaluru", ShipCountry = "India" }).ToList(); } return _data; } }
{% endhighlight %} {% endtabs %}
This section explains how the Syncfusion® Blazor DataGrid API endpoint is secured to allow access only to authenticated requests. The Authorize attribute enforces token based access to Grid data.
{% tabs %} {% highlight c# tabtitle="~/Controllers/GridController.cs" %}
using YourProjectName.Models;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Syncfusion.Blazor;
using Syncfusion.Blazor.Data;
namespace YourProjectName.Controllers;
[ApiController] [Route("api/[controller]")] [Authorize] [IgnoreAntiforgeryToken] // DataManager uses bearer token authentication; antiforgery tokens are not applicable for API endpoints using JWT. public class GridController : ControllerBase { [HttpPost] public IActionResult Post([FromBody] DataManagerRequest dm) { var data = OrdersDetails.GetAllRecords().AsQueryable(); var total = data.Count(); return Ok(new { result = data.ToList(), count = total }); } }
{% endhighlight %} {% endtabs %}
This example demonstrates how a JWT token is retrieved from the server and attached to the Syncfusion® Blazor DataManager as an HTTP Authorization header. This ensures that the DataGrid loads data only from a secured API after the user has been authenticated.
{% tabs %} {% highlight razor tabtitle="Home.razor" %}
@page "/" @using Syncfusion.Blazor @using Syncfusion.Blazor.Grids @using Syncfusion.Blazor.Data @using YourProjectName.Models @inject HttpClient Http @inject NavigationManager Nav
<button class="btn btn-primary" style="margin-bottom: 15px" @onclick="LoadGridWithToken">Load GridData
<SfGrid TValue="OrdersDetails" @ref="grid" AllowPaging="true" AllowSorting="true" Width="100%"> @* Only render the DataManager after the token is fetched. *@ @if (isDataManagerEnabled) { }
@code { private SfGrid? grid; // DataManager is enabled only after token is retrieved. private bool isDataManagerEnabled = false; private string? jwt; private string? error; private IDictionary<string, string> HeaderData => new Dictionary<string, string> { ["Authorization"] = string.IsNullOrEmpty(jwt) ? "" : $"Bearer {jwt}" }; // Ensure jwt is set before the DataManager is rendered; otherwise headers may be empty. private async Task LoadGridWithToken() { error = null; try { var baseUri = new Uri(Nav.BaseUri); var tokenRes = await Http.PostAsync(new Uri(baseUri, "api/auth/token?user=username"), content: null); tokenRes.EnsureSuccessStatusCode(); var json = await tokenRes.Content.ReadFromJsonAsync<Dictionary<string, string>>(); jwt = json!["token"]; isDataManagerEnabled = true; StateHasChanged(); await Task.Yield(); if (grid is not null) { await grid.Refresh(); // Triggers the first data request using the DataManager and headers. } } catch (Exception ex) { error = ex.Message; isDataManagerEnabled = false; } } }
{% endhighlight %} {% endtabs %}
When the Load GridData button is clicked, the application first authenticates the request using JWT. After successful authentication, the secured API is accessed and the DataGrid data is loaded.
