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

如何在Identity Server4、Angular SPA与非.NET Core WebApi中通过OIDC实现自定义Claims?

解决方案:在非.NET Core WebApi中添加应用专属自定义Claims

嘿,我之前也踩过类似的坑,给你梳理下怎么搞定这个问题,应该能帮你解决困扰:

首先得明确一个关键点:非.NET Core的Web API如果是处理客户端传来的Bearer Access Token,用UseJwtBearerAuthentication比UseOpenIdConnectAuthentication更合适——后者更多是给需要交互式登录跳转的Web应用用的。不过我两种场景都给你讲清楚:

场景1:Web API用JwtBearer验证令牌并添加自定义Claims

这是Web API最常用的方式,配置步骤如下:

  1. 配置JwtBearer中间件
app.UseJwtBearerAuthentication(new JwtBearerAuthenticationOptions
{
    AuthenticationMode = AuthenticationMode.Active,
    // 令牌验证核心参数,必须和IdentityServer4的配置匹配
    TokenValidationParameters = new TokenValidationParameters
    {
        ValidateIssuer = true,
        ValidIssuer = "https://你的IdentityServer4地址", // 比如https://idsrv.example.com
        ValidateAudience = true,
        ValidAudience = "你的API的Audience", // 比如"api1"
        ValidateIssuerSigningKey = true,
        // 如果IdentityServer用对称加密签名,填对应的密钥;非对称的话可以从Discovery端点获取公钥
        IssuerSigningKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes("你的签名密钥")),
        NameClaimType = JwtClaimTypes.Name,
        RoleClaimType = JwtClaimTypes.Role
    },
    // 在令牌验证通过后添加自定义Claims
    Provider = new OAuthBearerAuthenticationProvider
    {
        OnValidateIdentity = async context =>
        {
            // 获取当前用户的ClaimsIdentity
            var identity = context.Ticket.Identity;
            
            // 从你的应用专属数据源获取自定义信息(比如用户在这个应用里的权限、配置等)
            var userId = identity.FindFirst(JwtClaimTypes.Subject).Value;
            var appSpecificData = await GetYourAppCustomData(userId); // 替换成你的业务方法
            
            // 添加应用专属自定义Claim
            identity.AddClaim(new Claim("app_custom_permission", appSpecificData));
            
            // 更新AuthenticationTicket,让新Claim生效
            context.Ticket = new AuthenticationTicket(identity, context.Ticket.Properties);
        }
    }
});

场景2:如果确实要用UseOpenIdConnectAuthentication(比如Web应用风格的API)

如果你的API需要支持交互式登录跳转,那用UseOpenIdConnectAuthentication,添加自定义Claims的关键是利用SecurityTokenValidated事件:

app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions
{
    ClientId = "你的API客户端ID",
    Authority = "https://你的IdentityServer4地址",
    RedirectUri = "https://你的API地址/signin-oidc", // 登录回调地址
    ResponseType = "id_token token",
    Scope = "openid profile api1", // 包含需要的Scope
    TokenValidationParameters = new TokenValidationParameters
    {
        ValidateIssuer = true,
        ValidIssuer = "https://你的IdentityServer4地址",
        ValidateAudience = true,
        ValidAudience = "api1",
        NameClaimType = JwtClaimTypes.Name,
        RoleClaimType = JwtClaimTypes.Role
    },
    UseTokenLifetime = true,
    // 令牌验证通过后添加自定义Claims
    Notifications = new OpenIdConnectAuthenticationNotifications
    {
        SecurityTokenValidated = async n =>
        {
            var identity = n.AuthenticationTicket.Identity;
            // 同样从应用专属数据源获取信息
            var userId = identity.FindFirst(JwtClaimTypes.Subject).Value;
            var appCustomClaimValue = await GetAppSpecificData(userId);
            
            identity.AddClaim(new Claim("app_custom_setting", appCustomClaimValue));
            
            // 更新票据
            n.AuthenticationTicket = new AuthenticationTicket(identity, n.AuthenticationTicket.Properties);
        }
    }
});

注意事项

  • 数据源独立性:应用专属的自定义Claims不要依赖IdentityServer4返回的内容,应该从你这个Web API自己的数据库/服务里获取,这样才是真正的应用专属逻辑。
  • Claim命名冲突:自定义Claim的名称最好加上应用前缀(比如app_xxx),避免和IdentityServer返回的标准Claim重名。
  • 令牌验证正确性:一定要确保ValidIssuer、ValidAudience和签名密钥和IdentityServer4的配置完全匹配,否则中间件会直接拒绝令牌,后续的Claim添加也不会执行。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 08:36:49