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

IdentityServer4 Hybrid模式下多OpenIDConnect实例访问API问题

我之前也折腾过IdentityServer4 Hybrid模式扩展API的场景,给你梳理下完整的配置步骤,确保你的新.NET Core 2 Web API能被现有客户端正常访问:

1. 先在IdentityServer中注册新的Web API资源

首先得让IdentityServer识别这个新API是受保护的资源,同时授权现有Hybrid客户端访问它:

注册新的ApiResource

在IdentityServer的配置类(一般是Config.cs)里,给GetApiResources()方法添加新的API资源:

public static IEnumerable<ApiResource> GetApiResources()
{
    return new List<ApiResource>
    {
        // 保留原有的API资源
        new ApiResource("api1", "原有业务API"),
        // 新增你的.NET Core 2 Web API资源
        new ApiResource("new_api", "新的后台服务API")
        {
            // 按需添加需要传递给API的用户声明,比如姓名、邮箱
            UserClaims = { JwtClaimTypes.Name, JwtClaimTypes.Email }
        }
    };
}

授权客户端访问新API

同样在Config.cs的GetClients()方法里,给你的Hybrid客户端添加新API的访问权限:

public static IEnumerable<Client> GetClients()
{
    return new List<Client>
    {
        new Client
        {
            ClientId = "hybrid_client", // 你的客户端ID,保持和现有配置一致
            ClientName = "Hybrid模式客户端",
            AllowedGrantTypes = GrantTypes.Hybrid,
            ClientSecrets = { new Secret("your_client_secret".Sha256()) },
            // 保留原有的回调、退出地址配置
            RedirectUris = { "https://your-client-domain/signin-oidc" },
            PostLogoutRedirectUris = { "https://your-client-domain/signout-callback-oidc" },
            AllowedScopes = new List<string>
            {
                IdentityServerConstants.StandardScopes.OpenId,
                IdentityServerConstants.StandardScopes.Profile,
                "api1",
                "new_api" // 新增这个Scope,允许客户端访问新API
            },
            AllowOfflineAccess = true, // 如果需要刷新令牌,保持开启
            RequirePkce = false // Hybrid模式下通常关闭Pkce
        }
    };
}
2. 配置新的.NET Core 2 Web API

让新API信任你的IdentityServer,并验证请求中的令牌:

添加认证服务

在新API的Startup.cs的ConfigureServices方法中,配置JWT认证:

public void ConfigureServices(IServiceCollection services)
{
    services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);

    // 添加Bearer认证
    services.AddAuthentication("Bearer")
        .AddJwtBearer("Bearer", options =>
        {
            options.Authority = "https://your-identityserver-domain"; // 你的IdentityServer地址
            options.RequireHttpsMetadata = true; // 生产环境必须设为true
            options.Audience = "new_api"; // 必须和之前注册的ApiResource名称完全一致
        });
}

启用认证中间件

在Configure方法中,把认证中间件放在UseMvc之前:

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }
    else
    {
        app.UseHsts();
    }

    app.UseHttpsRedirection();
    app.UseAuthentication(); // 启用认证,必须在UseMvc之前
    app.UseMvc();
}

保护API接口

在需要保护的控制器或方法上添加[Authorize]特性:

[Authorize]
[Route("api/[controller]")]
[ApiController]
public class DataController : ControllerBase
{
    // 你的API业务方法
    [HttpGet]
    public IActionResult Get()
    {
        return Ok(new { message = "新API的受保护数据" });
    }
}
3. 在Hybrid客户端中配置访问逻辑

你的客户端是Angular+.NET Core的组合,需要确保客户端能获取到新API的访问令牌,并在调用时携带:

更新客户端的OpenIdConnect配置

在客户端的Startup.cs中,给OpenIdConnect配置添加新的Scope,并开启令牌保存:

services.AddAuthentication(options =>
{
    options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
    options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
})
.AddCookie()
.AddOpenIdConnect(options =>
{
    options.Authority = Configuration["IdentityServer:Authority"];
    options.ClientId = Configuration["IdentityServer:ClientId"];
    options.ClientSecret = Configuration["IdentityServer:ClientSecret"];
    options.ResponseType = "code id_token"; // Hybrid模式的标准响应类型
    // 添加需要的Scope
    options.Scope.Add("openid");
    options.Scope.Add("profile");
    options.Scope.Add("api1");
    options.Scope.Add("new_api"); // 新增新API的Scope
    options.Scope.Add("offline_access"); // 允许获取刷新令牌
    options.SaveTokens = true; // 将令牌保存到Cookie,方便后续获取
});

调用新API的示例代码

在客户端的后端(比如API控制器)中,获取令牌并调用新API:

private async Task<string> GetNewApiAccessToken()
{
    // 从Cookie中获取访问令牌
    var accessToken = await HttpContext.GetTokenAsync("access_token");
    // 如果有多个API,可指定Scope获取对应令牌:await HttpContext.GetTokenAsync("access_token", "new_api")
    return accessToken;
}

public async Task<IActionResult> FetchNewApiData()
{
    var token = await GetNewApiAccessToken();
    using var httpClient = new HttpClient();
    httpClient.SetBearerToken(token);
    var response = await httpClient.GetAsync("https://your-new-api-domain/api/data");
    
    if (response.IsSuccessStatusCode)
    {
        var data = await response.Content.ReadAsStringAsync();
        return Ok(data);
    }
    return BadRequest("调用新API失败");
}

如果是Angular前端直接调用新API,可通过oidc-client库从客户端直接管理令牌,在请求头中添加Authorization: Bearer {token}即可。

4. 验证配置

按以下顺序启动服务,验证是否正常工作:

  1. 启动IdentityServer
  2. 启动新的.NET Core 2 Web API
  3. 启动Hybrid客户端
    登录客户端后尝试访问新API,可通过https://your-identityserver-domain/.well-known/openid-configuration查看Discovery文档,确认new_api Scope已存在;用jwt.io解析令牌,确认aud字段包含new_api。

内容的提问来源于stack exchange,提问作者Tzvi Gregory Kaidanov

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 03:57:04