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

求助:.NET Framework 4.8集成OpenIdentity4发起Get请求返回Unauthorized问题

排查.NET Framework 4.8中JWT授权返回Unauthorized的问题

看起来你的问题主要出在JWT验证配置不完整,以及IdentityServer和客户端之间的配置不匹配上。我来帮你一步步梳理并修复:

一、修复.NET Framework客户端的JwtBearerAuthentication配置

你手动获取了Discovery Document,但没有把它用到JwtBearer的配置里,导致验证令牌时缺少关键的签名密钥和颁发者信息。修改你的Startup.cs代码如下:

public void Configuration(IAppBuilder app) {
    var authority = "https://localhost:5001";

    app.UseJwtBearerAuthentication(
        new JwtBearerAuthenticationOptions {
            AuthenticationMode = AuthenticationMode.Active,
            Authority = authority, // 直接指定IdentityServer地址,让组件自动获取Discovery文档
            TokenValidationParameters = new TokenValidationParameters() {
                ValidateAudience = false, // 如果你的API不需要验证Audience可以保留,但建议根据实际配置调整
                ValidateIssuer = true, // 必须验证颁发者合法性
                ValidIssuer = authority, // 颁发者就是IdentityServer的地址
                // 自动从Discovery文档获取签名密钥,无需手动处理
                IssuerSigningKeyResolver = (token, securityToken, kid, validationParameters) => {
                    var configurationManager = new ConfigurationManager<OpenIdConnectConfiguration>(
                        authority + "/.well-known/openid-configuration",
                        new OpenIdConnectConfigurationRetriever(),
                        new HttpDocumentRetriever());
                    var discoveryDocument = Task.Run(() => configurationManager.GetConfigurationAsync()).GetAwaiter().GetResult();
                    return discoveryDocument.SigningKeys;
                }
            }
        });

    // 以下WebApi配置保持不变
    var config = new HttpConfiguration();
    config.MapHttpAttributeRoutes();
    config.Routes.MapHttpRoute(
        name: "RestAPI",
        routeTemplate: "api/{controller}/{id}",
        defaults: new { id = RouteParameter.Optional }
    );
    config.Formatters.Remove(config.Formatters.XmlFormatter);
    config.Formatters.JsonFormatter.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
    config.Formatters.JsonFormatter.SerializerSettings.DateTimeZoneHandling = Newtonsoft.Json.DateTimeZoneHandling.Utc;
    app.UseWebApi(config);
}

关键修改点:

  • 添加Authority参数:让JwtBearer组件自动与IdentityServer的Discovery端点交互,获取必要的验证信息
  • 启用ValidateIssuer并指定ValidIssuer:确保令牌是由你的IdentityServer颁发的
  • 添加IssuerSigningKeyResolver:从Discovery文档中获取IdentityServer的签名密钥,这是验证令牌合法性的核心步骤(你之前完全缺失了这部分)

二、验证IdentityServer的配置

你的IdentityServer代码里添加了ApiScope策略,但需要确保以下几点:

  1. ApiScopes定义正确:检查你的Config.ApiScopes是否包含对应的Scope,比如:
public static IEnumerable<ApiScope> ApiScopes =>
    new List<ApiScope>
    {
        new ApiScope("RestAPI", "My Rest API") // 这里的Name要和客户端请求的Scope一致
    };
  1. 客户端配置正确:检查Config.Clients中的客户端是否允许请求该Scope,并且配置了正确的授权类型:
public static IEnumerable<Client> Clients =>
    new List<Client>
    {
        new Client
        {
            ClientId = "your-client-id",
            ClientSecrets = { new Secret("your-client-secret".Sha256()) },
            AllowedGrantTypes = GrantTypes.ClientCredentials, // 根据你的场景选择合适的授权类型(比如密码模式、客户端凭证模式)
            AllowedScopes = { "RestAPI" } // 必须包含你的ApiScope名称
        }
    };
  1. 策略匹配:你添加的ApiScope策略要求RequireClaim("RestAPI", "APIRest"),但默认情况下IdentityServer不会自动添加这个自定义Claim到令牌中。如果不需要这个自定义Claim,建议修改为IdentityServer的标准验证方式:
services.AddAuthorization(options => {
    options.AddPolicy("ApiScope", policy => {
        policy.RequireAuthenticatedUser();
        policy.RequireScope("RestAPI"); // 使用RequireScope来验证令牌中的Scope,这是IdentityServer的标准做法
    });
});

三、确认请求中的令牌是否正确

调用API时,确保你在请求头中正确携带了Bearer令牌:

Authorization: Bearer <your-access-token>

你可以通过访问https://localhost:5001/.well-known/openid-configuration/jwks查看IdentityServer的公钥,然后用JWT解析工具(比如jwt.io)验证你的令牌是否有效,是否包含正确的iss(颁发者)、scope(权限范围)等Claims。

四、启用日志排查细节

如果问题依然存在,建议在客户端和IdentityServer中启用详细日志:

.NET Framework客户端添加日志

在Startup.cs中添加日志监听:

Trace.Listeners.Add(new ConsoleTraceListener());
System.Net.ServicePointManager.SecurityProtocol = System.Net.SecurityProtocolType.Tls12; // 确保TLS版本兼容IdentityServer

IdentityServer添加日志

修改appsettings.json启用详细日志:

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information",
      "IdentityServer4": "Debug"
    }
  }
}

通过日志可以看到验证过程中的具体错误,比如令牌签名不匹配、颁发者不正确、Scope缺失等细节。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.06 06:57:28