Next-Auth集成Azure AD获JWT调用.NET Core API报401错误求助
问题排查与解决方案
核心问题
你传递给API的是Azure AD颁发的access_token,而非NextAuth自行生成的JWT。Azure AD的令牌使用自身的非对称密钥签名,而非你的NEXTAUTH_SECRET,所以.NET Core用自定义对称密钥验证必然失败,出现signature key was not found错误。
具体修正步骤
1. 修正.NET Core Web API的认证配置
移除错误的自定义JWT验证逻辑,改用Microsoft.Identity.Web原生对接Azure AD,它会自动从Azure AD的OpenID元数据端点获取签名密钥、验证令牌合法性:
using Microsoft.AspNetCore.Authentication.JwtBearer; using Microsoft.Identity.Web; var builder = WebApplication.CreateBuilder(args); // 仅保留Azure AD认证配置,移除自定义AddJwtBearer builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) .AddMicrosoftIdentityWebApi(builder.Configuration.GetSection("AzureAd")); builder.Services.AddControllers(); builder.Services.AddEndpointsApiExplorer(); builder.Services.AddSwaggerGen(); builder.Services.AddCors(o => o.AddPolicy("default", builder => { builder.AllowAnyOrigin() .AllowAnyMethod() .AllowAnyHeader(); })); var app = builder.Build(); if (app.Environment.IsDevelopment()) { app.UseSwagger(); app.UseSwaggerUI(); app.UseDeveloperExceptionPage(); } app.UseHttpsRedirection(); app.UseAuthentication(); app.UseAuthorization(); app.MapControllers(); app.Run();
同时确保appsettings.json中的Azure AD配置正确(替换为你的实际值):
{ "AzureAd": { "Instance": "https://login.microsoftonline.com/", "Domain": "your-tenant-domain.com", "TenantId": "your-tenant-id", "ClientId": "your-api-client-id", // 注意:这里是API的客户端ID,不是Next.js应用的ID "Audience": "api://your-api-client-id" // 要和NextAuth scope中的API受众一致 } }
2. 修正NextAuth的回调配置
确保session回调将access_token传递到session中(可选,但方便前端直接使用):
// [...nextauth].ts callbacks: { async jwt({ token, account, profile, isNewUser }) { if (account) { token.access_token = account.access_token; token.expires_at = account.expires_at; } return token; }, async session({ session, token }) { // 将access_token添加到session对象中 (session as any).access_token = token.access_token; return session; }, },
3. 优化API调用逻辑
确保错误处理更清晰,避免静默失败:
// weather.ts import { getToken } from 'next-auth/jwt' import type { NextApiRequest, NextApiResponse } from "next" export default async function handler( req: NextApiRequest, res: NextApiResponse ) { try { const token = await getToken({ req, secret: process.env.NEXTAUTH_SECRET }) if (!token?.access_token) { return res.status(401).json({ error: '未获取到有效访问令牌' }) } const apiUrl = `${process.env.API_BASE_URL}/weatherForecast/get`; const response = await fetch(apiUrl, { method: "GET", headers: { Authorization: `Bearer ${token.access_token}`, "Content-Type": "application/json", } }); if (!response.ok) { const errorData = await response.json().catch(() => ({ status: response.status, statusText: response.statusText })); return res.status(response.status).json(errorData); } const json = await response.json(); res.json(json); } catch (e) { res.status(500).json({ error: '请求API时发生异常', details: (e as Error).message }); } }
关键注意事项
- 受众一致性:NextAuth中scope里的
api://{api-client-id}/access_as_user必须和.NET Core配置中的Audience完全匹配。 - 令牌类型:确保传递的是Azure AD的
access_token,而非NextAuth的id_token(id_token用于前端身份验证,不能用于API授权)。 - 权限配置:在Azure AD门户中,确保Next.js应用被授予了API的
access_as_user权限,并且已完成管理员同意(如果是租户级权限)。
内容的提问来源于stack exchange,提问作者Paul J
相关产品推荐
相关产品推荐

