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

借助Classic ASP站点JWT实现.NET 6 Web应用身份认证

实现Classic ASP作为JWT签发方的.NET 6身份认证方案

针对你逐步迁移Classic ASP站点到.NET 6的需求,以下是适配当前场景的具体实现步骤,核心是利用Classic ASP的会话Cookie获取JWT,再在.NET 6中完成认证:

1. 同步JWT签发与验证参数

首先确保Classic ASP生成JWT时的参数和.NET 6的验证参数完全一致,包括:

  • 签名密钥:必须使用相同的对称密钥(如HS256算法的密钥)
  • 发行者(Issuer):设为Classic ASP站点地址(https://localhost:44300)
  • 受众(Audience):设为.NET 6站点地址(如https://localhost:5001)
  • Token有效期:根据业务需求设置,比如1小时

2. 配置.NET 6的认证服务

在Program.cs中添加JWT验证和本地Cookie认证(避免每次请求都去ASP拿JWT):

var builder = WebApplication.CreateBuilder(args);

// 注册HttpClient工厂,用于请求ASP的JWT接口
builder.Services.AddHttpClient();

// 配置认证服务
builder.Services.AddAuthentication(options =>
{
    options.DefaultAuthenticateScheme = "CustomJwt";
    options.DefaultChallengeScheme = "CustomJwt";
})
// 添加JWT验证支持
.AddJwtBearer(JwtBearerDefaults.AuthenticationScheme, options =>
{
    options.TokenValidationParameters = new TokenValidationParameters
    {
        ValidateIssuer = true,
        ValidateAudience = true,
        ValidateLifetime = true,
        ValidateIssuerSigningKey = true,
        ValidIssuer = "https://localhost:44300",
        ValidAudience = "https://localhost:5001",
        IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("your-shared-secret-key"))
    };
})
// 添加本地Cookie认证,存储已验证的用户身份
.AddCookie("CustomJwt", options =>
{
    options.LoginPath = "/Account/Login"; // 未认证时跳转的入口
    options.Cookie.Name = ".Net6Auth";
    options.Cookie.Domain = "localhost"; // 和ASP会话Cookie同域,确保请求携带
    options.SlidingExpiration = true;
    options.ExpireTimeSpan = TimeSpan.FromHours(8);
});

// 添加授权服务
builder.Services.AddAuthorization();

builder.Services.AddControllersWithViews();

var app = builder.Build();

// 中间件顺序必须严格:认证在前,授权在后
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();

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

app.Run();

3. 实现JWT获取与登录逻辑

创建AccountController,处理跳转ASP登录、获取JWT并完成.NET 6本地认证:

public class AccountController : Controller
{
    private readonly IHttpClientFactory _httpClientFactory;

    public AccountController(IHttpClientFactory httpClientFactory)
    {
        _httpClientFactory = httpClientFactory;
    }

    // 未认证时跳转至此,引导用户到ASP登录页
    public IActionResult Login(string returnUrl = "/")
    {
        // ASP登录成功后,重定向回.NET 6的GetJwt端点
        var aspLoginUrl = $"https://localhost:44300/login.asp?returnUrl={Url.Encode($"/Account/GetJwt?returnUrl={returnUrl}")}";
        return Redirect(aspLoginUrl);
    }

    // 从ASP获取JWT并完成本地认证
    public async Task<IActionResult> GetJwt(string returnUrl = "/")
    {
        // 提取ASP的会话Cookie(替换为你实际的ASP会话Cookie名称,如ASPSESSIONIDXXXX)
        var aspSessionCookie = Request.Cookies["ASPSESSIONIDXXXX"];
        if (string.IsNullOrWhiteSpace(aspSessionCookie))
        {
            return RedirectToAction(nameof(Login), new { returnUrl });
        }

        // 创建携带ASP会话Cookie的HttpClient请求
        var handler = new HttpClientHandler
        {
            CookieContainer = new CookieContainer()
        };
        handler.CookieContainer.Add(new Uri("https://localhost:44300"), 
            new Cookie("ASPSESSIONIDXXXX", aspSessionCookie));

        using var client = new HttpClient(handler);
        var response = await client.GetAsync("https://localhost:44300/auth.asp");
        
        if (!response.IsSuccessStatusCode)
        {
            return RedirectToAction(nameof(Login), new { returnUrl });
        }

        var jwtToken = await response.Content.ReadAsStringAsync();
        if (string.IsNullOrWhiteSpace(jwtToken))
        {
            return RedirectToAction(nameof(Login), new { returnUrl });
        }

        // 验证JWT并生成用户身份
        var tokenHandler = new JwtSecurityTokenHandler();
        var validationParams = new TokenValidationParameters
        {
            ValidateIssuer = true,
            ValidateAudience = true,
            ValidateLifetime = true,
            ValidateIssuerSigningKey = true,
            ValidIssuer = "https://localhost:44300",
            ValidAudience = "https://localhost:5001",
            IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("your-shared-secret-key"))
        };

        try
        {
            var claimsPrincipal = tokenHandler.ValidateToken(jwtToken, validationParams, out _);
            // 登录到.NET 6的本地Cookie认证
            await HttpContext.SignInAsync("CustomJwt", claimsPrincipal);
            return Redirect(returnUrl);
        }
        catch
        {
            return RedirectToAction(nameof(Login), new { returnUrl });
        }
    }
}

4. 保护.NET 6资源

在需要认证的控制器或动作上添加[Authorize]特性:

[Authorize]
public class DashboardController : Controller
{
    public IActionResult Index()
    {
        // 获取当前用户信息
        var userId = User.FindFirstValue(ClaimTypes.NameIdentifier);
        var userName = User.FindFirstValue(ClaimTypes.Name);
        return View();
    }
}

关键注意事项

  • Cookie共享:确保Classic ASP的会话Cookie设置了Domain=localhost(如果是同域不同端口),这样浏览器会自动将Cookie携带到.NET 6的请求中
  • JWT内容:Classic ASP生成的JWT需包含必要的Claims,如sub(用户ID)、name(用户名)等,方便.NET 6获取用户信息
  • 跨域处理:如果ASP和.NET 6站点域名不同,需配置CORS并处理Cookie跨域传递(可参考SameSite=None和Secure属性)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 08:48:11