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

.NET Framework客户端无法从IdentityServer4获取name声明

解决.NET Framework Owin OpenIdConnect无法获取name声明的问题

我之前在对接IdentityServer4和.NET Framework的Owin应用时,也碰到过一模一样的问题——.NET Core里的GetClaimsFromUserInfoEndpoint属性在Owin的OpenIdConnect组件里确实不存在,导致默认不会调用UserInfo端点,进而缺失name这类属于profile范围的声明。下面是亲测有效的解决方法:

手动调用UserInfo端点获取声明

我们可以通过OpenIdConnectAuthenticationNotifications里的SecurityTokenValidated事件,在令牌验证通过后手动请求IdentityServer的UserInfo端点,把获取到的声明添加到用户身份中。

步骤1:安装IdentityModel库

首先需要安装IdentityModel NuGet包,它提供了方便调用UserInfo端点的客户端:

Install-Package IdentityModel

步骤2:修改OpenIdConnect配置

在你的UseOpenIdConnectAuthentication配置中添加Notifications节点,实现SecurityTokenValidated事件:

app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions {
    AuthenticationType = "oidc",
    SignInAsAuthenticationType = "Cookies",
    Authority = identityServerUrl,
    RedirectUri = appUrl + "/signin-oidc",
    PostLogoutRedirectUri = appUrl + "/signout-callback-oidc",
    ClientId = "clientId",
    ClientSecret = @"secret",
    ResponseType = OpenIdConnectResponseTypes.CodeIdToken,
    Scope = "openid profile offline_access",
    UseTokenLifetime = false,
    // 添加以下Notifications配置
    Notifications = new OpenIdConnectAuthenticationNotifications
    {
        SecurityTokenValidated = async notification =>
        {
            // 从协议消息中获取访问令牌
            var accessToken = notification.ProtocolMessage.AccessToken;
            if (string.IsNullOrEmpty(accessToken))
            {
                return;
            }

            // 初始化UserInfo客户端,指向IdentityServer的UserInfo端点
            var userInfoClient = new UserInfoClient(
                new Uri($"{notification.Options.Authority}/connect/userinfo"),
                accessToken);

            // 请求UserInfo端点
            var userInfoResponse = await userInfoClient.GetAsync();
            if (userInfoResponse.IsError)
            {
                throw new InvalidOperationException($"获取用户信息失败: {userInfoResponse.Error}");
            }

            // 将UserInfo返回的声明添加到当前用户的身份中
            var identity = notification.AuthenticationTicket.Identity;
            identity.AddClaims(userInfoResponse.Claims);
        }
    }
});

关键检查点

除了上面的代码,还要确保以下几点:

  • 你的客户端Scope已经包含profile(从你的代码看已经加了,这是name声明所在的范围)
  • 在IdentityServer4的配置中,确保你的用户(或者IProfileService)正确返回了name声明。如果使用的是测试用户,要确认用户配置里包含该声明;如果是自定义ProfileService,要在GetProfileDataAsync方法中添加对应的声明。
  • 确认IdentityServer的UserInfo端点可以正常访问(可以通过携带有效令牌的请求测试端点可用性)

这样配置后,你的.NET Framework应用就能成功获取到name声明了,原理就是模拟.NET Core里GetClaimsFromUserInfoEndpoint=true的行为,手动触发UserInfo端点的调用并合并声明。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.08 07:37:30