You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ASP.NET MVC如何利用内置认证功能使用外部JWT实现身份验证

实现步骤

1. 配置MVC项目的JWT认证服务

在MVC项目的Program.cs中添加JWT认证服务配置,由于你的Web API返回的JWT由AzureAD签发,需配置用AzureAD公钥验证签名,并匹配签发者(Issuer)和受众(Audience):

using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.IdentityModel.Tokens;

var builder = WebApplication.CreateBuilder(args);

// 添加MVC服务
builder.Services.AddControllersWithViews();

// 配置JWT认证
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
    .AddJwtBearer(options =>
    {
        // 从配置文件读取AzureAD参数,避免硬编码
        options.Authority = builder.Configuration["AzureAD:Authority"]; // 示例:https://login.microsoftonline.com/你的租户ID
        options.Audience = builder.Configuration["AzureAD:Audience"]; // 你的Web API客户端ID
        
        // 验证规则配置
        options.TokenValidationParameters = new TokenValidationParameters
        {
            ValidateIssuer = true,
            ValidateAudience = true,
            ValidateLifetime = true,
            ValidateIssuerSigningKey = true,
            // AzureAD签名密钥会自动从Authority地址获取,无需手动指定
        };
    });

// 启用授权服务
builder.Services.AddAuthorization();

var app = builder.Build();

// 启用认证、授权中间件(顺序不能错)
app.UseAuthentication();
app.UseAuthorization();

app.MapControllerRoute(
    name: "default",
    pattern: "{controller=Home}/{action=Index}/{id?}");

app.Run();

2. 在MVC控制器中完成登录流程

创建登录控制器,调用Web API获取JWT,验证有效性后通过ASP.NET内置方法完成用户认证:

using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.IdentityModel.Tokens;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;

public class AccountController : Controller
{
    private readonly IHttpClientFactory _httpClientFactory;
    private readonly IConfiguration _configuration;

    public AccountController(IHttpClientFactory httpClientFactory, IConfiguration configuration)
    {
        _httpClientFactory = httpClientFactory;
        _configuration = configuration;
    }

    public IActionResult Login()
    {
        return View();
    }

    [HttpPost]
    public async Task<IActionResult> Login(LoginViewModel model)
    {
        if (!ModelState.IsValid) return View(model);

        // 调用Web API登录接口获取JWT
        var client = _httpClientFactory.CreateClient();
        var loginResponse = await client.PostAsJsonAsync("https://你的WebAPI地址/api/auth/login", model);
        if (!loginResponse.IsSuccessStatusCode)
        {
            ModelState.AddModelError(string.Empty, "登录失败");
            return View(model);
        }

        var jwtToken = await loginResponse.Content.ReadAsStringAsync();

        // 验证JWT有效性
        var tokenHandler = new JwtSecurityTokenHandler();
        var validationParams = new TokenValidationParameters
        {
            ValidateIssuer = true,
            ValidIssuer = _configuration["AzureAD:Authority"],
            ValidateAudience = true,
            ValidAudience = _configuration["AzureAD:Audience"],
            ValidateLifetime = true,
            ValidateIssuerSigningKey = true,
            Authority = _configuration["AzureAD:Authority"]
        };

        try
        {
            // 验证token并生成用户身份凭证
            var principal = tokenHandler.ValidateToken(jwtToken, validationParams, out _);
            
            // 配置会话持久化参数
            var authProperties = new AuthenticationProperties
            {
                IsPersistent = model.RememberMe,
                ExpiresUtc = DateTimeOffset.UtcNow.AddHours(1)
            };

            // 用JWT认证方案完成登录
            await HttpContext.SignInAsync(JwtBearerDefaults.AuthenticationScheme, principal, authProperties);

            return RedirectToAction("Index", "Home");
        }
        catch (SecurityTokenException ex)
        {
            ModelState.AddModelError(string.Empty, $"Token验证失败: {ex.Message}");
            return View(model);
        }
    }

    public async Task<IActionResult> Logout()
    {
        await HttpContext.SignOutAsync(JwtBearerDefaults.AuthenticationScheme);
        return RedirectToAction("Login");
    }
}

// 配套的登录视图模型
public class LoginViewModel
{
    public string Username { get; set; }
    public string Password { get; set; }
    public bool RememberMe { get; set; }
}

3. 保护需要认证的控制器/动作

在目标控制器或动作上添加[Authorize]标签(注意是Authorize而非Authentication),限制仅认证用户可访问:

[Authorize]
public class HomeController : Controller
{
    public IActionResult Index()
    {
        // 可直接获取当前用户的身份信息
        var userName = User.Identity.Name;
        var userClaims = User.Claims.ToList();
        return View();
    }
}

关键注意点

  • 确保MVC项目的AzureAD:Authority和AzureAD:Audience配置与Web API完全一致,否则JWT验证会失败。
  • 整个流程由后端处理JWT验证与身份创建,依赖ASP.NET内置认证中间件,无需前端手动管理Cookie(框架会自动生成认证Cookie维持会话)。
  • Web API返回的JWT中包含的自定义Claims会自动映射到User对象,可直接在控制器中调用使用。

内容的提问来源于stack exchange,提问作者krispig

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 05:45:42