Blazor应用集成JWT认证需要同时处理后端API的Token生成逻辑和前端应用的认证状态管理,整体分为服务端配置、前端Token处理、认证状态同步三个核心环节。

一、后端ASP.NET Core API配置JWT生成
首先需要在后端项目中安装JWT相关的NuGet包,然后配置认证服务与Token生成逻辑。
1. 安装依赖包
在ASP.NET Core项目中执行以下命令安装所需包:
Install-Package Microsoft.AspNetCore.Authentication.JwtBearer Install-Package System.IdentityModel.Tokens.Jwt
2. 配置JWT服务
在Program.cs中添加JWT认证服务配置,设置密钥、发行者、受众等参数:
using Microsoft.IdentityModel.Tokens;
using System.Text;
var builder = WebApplication.CreateBuilder(args);
// 配置JWT参数
var jwtSettings = builder.Configuration.GetSection("JwtSettings");
var key = Encoding.ASCII.GetBytes(jwtSettings["Key"]);
builder.Services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(options =>
{
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuerSigningKey = true,
IssuerSigningKey = new SymmetricSecurityKey(key),
ValidateIssuer = true,
ValidIssuer = jwtSettings["Issuer"],
ValidateAudience = true,
ValidAudience = jwtSettings["Audience"],
ValidateLifetime = true,
ClockSkew = TimeSpan.Zero
};
});
builder.Services.AddControllers();
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
var app = builder.Build();
// 启用认证中间件
app.UseAuthentication();
app.UseAuthorization();
app.MapControllers();
app.Run();
3. 实现登录接口生成Token
创建登录接口,验证用户凭证后生成JWT Token返回给前端:
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.IdentityModel.Tokens;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Text;
[ApiController]
[Route("api/[controller]")]
public class AuthController : ControllerBase
{
private readonly IConfiguration _configuration;
public AuthController(IConfiguration configuration)
{
_configuration = configuration;
}
[HttpPost("login")]
[AllowAnonymous]
public IActionResult Login([FromBody] LoginRequest request)
{
// 这里替换为实际的用户验证逻辑
if (request.Username == "admin" && request.Password == "123456")
{
var jwtSettings = _configuration.GetSection("JwtSettings");
var key = Encoding.ASCII.GetBytes(jwtSettings["Key"]);
var tokenHandler = new JwtSecurityTokenHandler();
var tokenDescriptor = new SecurityTokenDescriptor
{
Subject = new ClaimsIdentity(new Claim[]
{
new Claim(ClaimTypes.Name, request.Username),
new Claim(ClaimTypes.Role, "Admin")
}),
Expires = DateTime.UtcNow.AddHours(2),
Issuer = jwtSettings["Issuer"],
Audience = jwtSettings["Audience"],
SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(key), SecurityAlgorithm.HmacSha256Signature)
};
var token = tokenHandler.CreateToken(tokenDescriptor);
var tokenString = tokenHandler.WriteToken(token);
return Ok(new { Token = tokenString });
}
return Unauthorized("用户名或密码错误");
}
}
public class LoginRequest
{
public string Username { get; set; }
public string Password { get; set; }
}
同时在appsettings.json中添加JWT配置:
{
"JwtSettings": {
"Key": "YourSuperSecretKeyHere1234567890",
"Issuer": "BlazorDemo",
"Audience": "BlazorClient"
}
}
二、Blazor前端处理JWT Token
Blazor应用需要存储后端返回的Token,并在后续请求中携带Token完成认证。
1. 创建Token存储服务
创建专门的服务用于管理Token的本地存储与读取,这里使用浏览器的localStorage存储Token:
using Microsoft.JSInterop;
public class TokenService
{
private readonly IJSRuntime _jsRuntime;
public TokenService(IJSRuntime jsRuntime)
{
_jsRuntime = jsRuntime;
}
public async Task SaveTokenAsync(string token)
{
await _jsRuntime.InvokeVoidAsync("localStorage.setItem", "jwt_token", token);
}
public async Task<string> GetTokenAsync()
{
return await _jsRuntime.InvokeAsync<string>("localStorage.getItem", "jwt_token");
}
public async Task RemoveTokenAsync()
{
await _jsRuntime.InvokeVoidAsync("localStorage.removeItem", "jwt_token");
}
}
2. 封装带Token的HTTP请求
创建自定义的HttpMessageHandler,在发送请求时自动添加Authorization请求头:
using System.Net.Http.Headers;
public class AuthHeaderHandler : DelegatingHandler
{
private readonly TokenService _tokenService;
public AuthHeaderHandler(TokenService tokenService)
{
_tokenService = tokenService;
}
protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
var token = await _tokenService.GetTokenAsync();
if (!string.IsNullOrEmpty(token))
{
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", token);
}
return await base.SendAsync(request, cancellationToken);
}
}
在Program.cs中注册相关服务:
using Microsoft.AspNetCore.Components.Web;
using Microsoft.AspNetCore.Components.WebAssembly.Hosting;
var builder = WebAssemblyHostBuilder.CreateDefault(args);
builder.RootComponents.Add<App>("#app");
builder.RootComponents.Add<HeadOutlet>("head::after");
// 注册Token服务
builder.Services.AddScoped<TokenService>();
// 注册带认证头的HttpClient
builder.Services.AddScoped<AuthHeaderHandler>();
builder.Services.AddScoped(sp =>
{
var handler = sp.GetRequiredService<AuthHeaderHandler>();
handler.InnerHandler = new HttpClientHandler();
return new HttpClient(handler)
{
BaseAddress = new Uri("http://localhost:5000/")
};
});
await builder.Build().RunAsync();
三、Blazor认证状态管理
需要实现自定义的AuthenticationStateProvider,让Blazor能够识别用户的认证状态。
1. 自定义认证状态提供器
using System.Security.Claims;
public class JwtAuthenticationStateProvider : AuthenticationStateProvider
{
private readonly TokenService _tokenService;
public JwtAuthenticationStateProvider(TokenService tokenService)
{
_tokenService = tokenService;
}
public override async Task<AuthenticationState> GetAuthenticationStateAsync()
{
var token = await _tokenService.GetTokenAsync();
if (string.IsNullOrEmpty(token))
{
return new AuthenticationState(new ClaimsPrincipal(new ClaimsIdentity()));
}
// 这里简单解析Token,实际项目可以验证Token有效性
var claims = new List<Claim>
{
new Claim(ClaimTypes.Name, "当前用户")
};
var identity = new ClaimsIdentity(claims, "jwt");
var user = new ClaimsPrincipal(identity);
return new AuthenticationState(user);
}
public void NotifyUserAuthentication(string token)
{
var claims = new List<Claim>
{
new Claim(ClaimTypes.Name, "当前用户")
};
var identity = new ClaimsIdentity(claims, "jwt");
var user = new ClaimsPrincipal(identity);
var authState = Task.FromResult(new AuthenticationState(user));
NotifyAuthenticationStateChanged(authState);
}
public void NotifyUserLogout()
{
var authState = Task.FromResult(new AuthenticationState(new ClaimsPrincipal(new ClaimsIdentity())));
NotifyAuthenticationStateChanged(authState);
}
}
在Program.cs中注册该服务:
builder.Services.AddScoped<AuthenticationStateProvider, JwtAuthenticationStateProvider>(); builder.Services.AddAuthorizationCore();
2. 实现登录与登出逻辑
创建登录页面,调用后端登录接口存储Token并更新认证状态:
@page "/login"
@inject TokenService TokenService
@inject JwtAuthenticationStateProvider AuthStateProvider
@inject HttpClient Http
@inject NavigationManager Navigation
<h3>用户登录</h3>
<EditForm Model="@loginRequest" OnValidSubmit="HandleLogin">
<DataAnnotationsValidator />
<ValidationSummary />
<div class="mb-3">
<label>用户名</label>
<InputText class="form-control" @bind-Value="loginRequest.Username" />
</div>
<div class="mb-3">
<label>密码</label>
<InputText type="password" class="form-control" @bind-Value="loginRequest.Password" />
</div>
<button type="submit" class="btn btn-primary">登录</button>
</EditForm>
@code {
private LoginRequest loginRequest = new();
private async Task HandleLogin()
{
var response = await Http.PostAsJsonAsync("api/auth/login", loginRequest);
if (response.IsSuccessStatusCode)
{
var result = await response.Content.ReadFromJsonAsync<LoginResult>();
await TokenService.SaveTokenAsync(result.Token);
AuthStateProvider.NotifyUserAuthentication(result.Token);
Navigation.NavigateTo("/");
}
else
{
// 处理登录失败逻辑
}
}
public class LoginResult
{
public string Token { get; set; }
}
}
登出逻辑只需要清除本地Token并更新认证状态:
private async Task HandleLogout()
{
await TokenService.RemoveTokenAsync();
AuthStateProvider.NotifyUserLogout();
Navigation.NavigateTo("/login");
}
四、路由权限控制
使用Blazor内置的<AuthorizeRouteView>和<AuthorizeView>组件实现路由和页面元素的权限控制。
在App.razor中修改路由配置:
<Router AppAssembly="@typeof(App).Assembly">
<Found Context="routeData">
<AuthorizeRouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)">
<NotAuthorized>
<p>你没有权限访问该页面,请先<a href="/login">登录</a>。</p>
</NotAuthorized>
<Authorizing>
<p>正在验证身份...</p>
</Authorizing>
</AuthorizeRouteView>
</Found>
<NotFound>
<LayoutView Layout="@typeof(MainLayout)">
<p>抱歉,找不到你请求的页面。</p>
</LayoutView>
</NotFound>
</Router>
在需要权限控制的页面上添加<Authorize>特性:
@page "/admin" @attribute [Authorize(Roles = "Admin")] <h3>管理员页面</h3> <p>只有管理员角色可以访问该页面</p>
也可以在页面内部使用<AuthorizeView>组件控制元素显示:
<AuthorizeView Roles="Admin">
<Authorized>
<p>管理员可见内容</p>
</Authorized>
<NotAuthorized>
<p>你不是管理员,无法查看该内容</p>
</NotAuthorized>
</AuthorizeView>
BlazorJWT认证ASP.NET_Core身份认证Token验证修改时间:2026-07-10 19:18:46