Asp.Net Core中IdentityModel.AspNetCore自动注入Bearer Token失效问题
问题解决思路
我整理了几个关键点,你可以逐一排查:
1. 确认页面已启用用户授权
AddUserAccessTokenHandler只对已登录用户的请求生效,如果你的Razor Page没加授权,当前请求没有用户身份,处理器根本不会触发。
给你的Page模型类加上[Authorize]特性,确保只有登录用户能访问这个页面:
[Authorize] public class YourPageModel : PageModel { // ... 你的代码 }
2. 检查认证配置里的SaveTokens是否开启
这是最容易踩的坑——如果OpenID Connect配置没开SaveTokens = true,令牌不会存在HttpContext里,不管是手动GetTokenAsync还是自动处理器都拿不到令牌。
补全你的认证配置:
builder.Services.AddAuthentication(options => { options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme; options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme; }) .AddCookie() .AddOpenIdConnect(options => { options.Authority = builder.Configuration["OpenId:Authority"]; options.ClientId = "你的Web客户端ID"; options.ClientSecret = "你的Web客户端密钥"; options.ResponseType = "code"; options.Scope.Add("remoteapi"); // 必须请求API对应的scope options.SaveTokens = true; // 关键!把令牌存到Cookie里,供后续获取使用 });
3. 补全AccessTokenManagement的基础配置
虽然你加了AddAccessTokenManagement(),可以补充配置明确令牌来源,避免潜在的配置缺失:
builder.Services.AddAccessTokenManagement(options => { options.User.ClientId = "你的Web客户端ID"; options.User.ClientSecret = "你的Web客户端密钥"; });
4. 换一种HttpClient调用方式验证
你当前用的是Send方法发送HttpRequestMessage,可以先换成GetAsync这类扩展方法试试:
var content = await httpClient.GetStringAsync("api/WeatherForecast"); // 然后反序列化 WeatherForecasts = JsonSerializer.Deserialize<List<WeatherForecast>>(content, _jsonOptions);
如果这样能自动带上令牌,说明可能是手动创建HttpRequestMessage时,处理器的拦截逻辑有特殊情况,或者你需要确保请求地址和HttpClient的BaseAddress拼接正确。
5. 验证令牌本身的有效性
手动拿到令牌后,去你的IdentityServer的令牌验证端点(可从/.well-known/openid-configuration里查找)检查令牌的aud(受众)是不是remoteapi,有没有包含对应的scope。如果令牌受众不对,API肯定会返回Unauthorized,这时候要调整OpenID Connect的Scope配置,确保请求了正确的API权限。
6. 检查中间件顺序是否正确
确保你的中间件顺序符合规范:
var app = builder.Build(); // ... 其他中间件(比如静态文件) app.UseRouting(); // 认证和授权必须在路由之后,端点之前 app.UseAuthentication(); app.UseAuthorization(); app.UseEndpoints(endpoints => { endpoints.MapRazorPages(); });
内容的提问来源于stack exchange,提问作者Kman
相关产品推荐
相关产品推荐

