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

IdentityServer4 OIDC认证授权报错:Token未通过认证

问题:IdentityServer4本地API认证提示"invalid JWT token type"

我使用IdentityServer4实现OIDC认证,前端采用React框架。前端启动后可正常重定向到Razor登录页面,但当我为控制器添加Authorize特性时,出现错误提示“Token was not authenticated”,对应的日志信息为:

info: IdentityServer4.Hosting.LocalApiAuthentication.LocalApiAuthenticationHandler[7]
IdentityServerAccessToken was not authenticated. Failure message: invalid JWT token type

相关配置代码

Startup服务配置

services.AddIdentity<ApplicationUser, Role>()
        .AddDefaultTokenProviders()
        .AddDefaultUI()
        .AddEntityFrameworkStores<ApplicationDbContext>();

var clientUrl = GetClientUrl(configuration);

AddIdentityServer(services, clientUrl, configuration);

services.AddAuthentication(IdentityConstants.ApplicationScheme);

services.Configure<IdentityOptions>(options =>
{
    options.Password.RequireLowercase = true;
    options.Password.RequireUppercase = true;
    options.Password.RequireDigit = true;
    options.Password.RequireNonAlphanumeric = false;
    options.Password.RequiredLength = 6;
    options.Password.RequiredUniqueChars = 0;
});

services.AddLocalApiAuthentication();

AddCors(services, clientUrl);

services.AddScoped<ICurrentUserService, CurrentUserService>();

services.AddHttpContextAccessor();

services.AddControllers().AddNewtonsoftJson(options =>
{
    options.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore;
    options.SerializerSettings.Converters.Add(new DateOnlyJsonConverter());
    options.SerializerSettings.Converters.Add(new TimeOnlyJsonConverter());
});

services.AddControllersWithViews(); // Need views for IDserver pages

services.AddHealthChecks()
    .AddDbContextCheck<ApplicationDbContext>();

services.AddRazorPages();

services.AddScoped<FluentValidationSchemaProcessor>(provider =>
{
    var validationRules = provider.GetService<IEnumerable<FluentValidationRule>>();
    var loggerFactory = provider.GetService<ILoggerFactory>();

    return new FluentValidationSchemaProcessor(provider, validationRules, loggerFactory);
});

// Requests for unknown pages will be passed to the SPA
services.AddSpaStaticFiles(options => options.RootPath = "jsclient");

// Customise default API behaviour
services.Configure<ApiBehaviorOptions>(options =>
    options.SuppressModelStateInvalidFilter = true);

return services;
}
public static void AddIdentityServer(IServiceCollection services, string clientUrl, IConfiguration configuration)
{
    var idSrvConfig = new IdentityServerConfig(clientUrl);

    var migrationsAssembly = typeof(Program).Assembly.GetName().Name;
    string idServerConnectionString = configuration["DefaultConnection"];
    var builder = services.AddIdentityServer(options =>
    {
        options.Authentication.CookieSlidingExpiration = true;

        options.Events.RaiseErrorEvents = true;
        options.Events.RaiseInformationEvents = true;
        options.Events.RaiseFailureEvents = true;
        options.Events.RaiseSuccessEvents = true;

        options.EmitStaticAudienceClaim = true;
    })
        .AddInMemoryIdentityResources(idSrvConfig.IdentityResources)
        .AddInMemoryClients(idSrvConfig.Clients)
        .AddInMemoryApiScopes(idSrvConfig.ApiScopes)
        .AddAspNetIdentity<ApplicationUser>()
        .AddProfileService<AppProfileService>()
        .AddOperationalStore(options =>
        {
            options.EnableTokenCleanup = true;

            options.ConfigureDbContext = b => b.UseSqlServer(idServerConnectionString, sql => sql.MigrationsAssembly(migrationsAssembly));
        });

    builder.AddDeveloperSigningCredential();

}

Program端点配置

app.UseEndpoints(endpoints =>
{
    endpoints.MapControllers()
        // This will apply identityserver policy for authorization to all controllers
        // so the user must be logged in via identityserver to call api
        .RequireAuthorization(IdentityServer4.IdentityServerConstants.LocalApi.AuthenticationScheme);

    endpoints.MapRazorPages();
});

解决方案

1. 确认前端使用正确的令牌类型

LocalApi认证仅接受Access Token,而非ID Token。检查React前端代码,确保调用API时携带的是从IdentityServer获取的Access Token。

2. 修正认证方案配置

当前默认认证方案设置为Cookie,但LocalApi需要独立配置。修改认证服务注册代码:

services.AddAuthentication()
    .AddLocalApi(options =>
    {
        // 明确指定期望的令牌类型为access_token
        options.ExpectedTokenType = "access_token";
    })
    .AddCookie(IdentityConstants.ApplicationScheme);

或者在控制器的Authorize特性中明确指定认证方案:

[Authorize(AuthenticationSchemes = IdentityServer4.IdentityServerConstants.LocalApi.AuthenticationScheme)]

3. 验证客户端与API Scope配置

  • 检查IdentityServerConfig中的客户端配置,确保客户端请求了正确的API Scope,且AllowedGrantTypes包含适合前端的类型(如authorization_code)。
  • 确保API Scope已正确注册,令牌的scope字段包含对应的值。

4. 检查令牌内容

使用JWT解码工具查看令牌的typ字段是否为access_token,同时确认aud(受众)是否匹配API标识,scope是否包含所需的API权限。

内容的提问来源于stack exchange,提问作者Surya Partap Singh

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 00:16:00