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

IdentityServer4同站点权限分离:如何判断用户认证所用客户端

解决同一站点区分IdentityServer4客户端并控制访问权限的问题

首先,核心思路是利用IdentityServer4在认证令牌中自带的client_id Claim来区分用户/请求来自哪个客户端,然后通过自定义授权策略实现权限隔离。下面一步步拆解实现方案:

一、关键原理:client_id Claim的存在

IdentityServer4在生成ID Token和Access Token时,会自动把当前请求的客户端ID以client_id的Claim形式嵌入令牌中:

  • 通过mvc客户端登录的站内用户,其Cookie认证的Claims里会包含client_id: mvc
  • 通过sapi客户端调用API的请求,其JWT令牌里会包含client_id: sapi

我们只需要基于这个Claim做权限判断即可。

二、配置自定义授权策略

在你的.NET Core站点的Startup.cs(.NET Core 2.x)中,添加针对应用和API的不同授权策略:

services.AddAuthorization(options =>
{
    // 仅允许mvc客户端的用户访问应用页面
    options.AddPolicy("MvcClientOnly", policy =>
    {
        policy.RequireClaim("client_id", "mvc");
    });

    // 允许mvc和sapi客户端访问API
    options.AddPolicy("ApiAccess", policy =>
    {
        policy.RequireClaim("client_id", "mvc", "sapi");
    });
});

三、为应用和API分别应用策略

1. 站内应用页面(MVC控制器)

给需要登录才能访问的应用控制器/Action加上[Authorize]并指定MvcClientOnly策略:

[Authorize(Policy = "MvcClientOnly")]
public class HomeController : Controller
{
    // 站内用户才能访问的应用页面逻辑
}

这样一来,即使外部应用拿到了合法令牌,也无法访问这些页面——因为它们的client_id是sapi,不满足策略要求。

2. API接口

给API控制器指定ApiAccess策略,同时注意指定JWT认证方案(因为API用Bearer令牌认证,和MVC的Cookie认证区分开):

[Authorize(AuthenticationSchemes = "Bearer", Policy = "ApiAccess")]
[Route("api/[controller]")]
public class ValuesController : ControllerBase
{
    // 站内用户和外部应用都能访问的API逻辑
}

四、代码中手动判断客户端ID(可选)

如果需要在业务逻辑里主动区分客户端来源,可以直接从当前用户的Claims中提取:

var clientId = User.Claims.FirstOrDefault(c => c.Type == "client_id")?.Value;

if (clientId == "mvc")
{
    // 处理站内用户的专属逻辑
}
else if (clientId == "sapi")
{
    // 处理外部应用的专属逻辑
}

五、补充:确保站点的认证中间件配置正确

因为你的站点同时承载MVC应用和API,需要分别配置两种认证方案:

// MVC应用的Cookie+OIDC认证
services.AddAuthentication(options =>
{
    options.DefaultScheme = "Cookies";
    options.DefaultChallengeScheme = "oidc";
})
.AddCookie("Cookies")
.AddOpenIdConnect("oidc", options =>
{
    options.Authority = "http://localhost:5000"; // 你的IdentityServer地址
    options.ClientId = "mvc";
    options.ClientSecret = "secret";
    options.ResponseType = "code id_token";
    options.SaveTokens = true;
    options.Scope.Add("sapi");
    options.Scope.Add("offline_access");
});

// API的JWT Bearer认证
services.AddAuthentication("Bearer")
    .AddJwtBearer("Bearer", options =>
    {
        options.Authority = "http://localhost:5000";
        options.RequireHttpsMetadata = false;
        options.Audience = "sapi";
    });

这样配置后,就能完美实现你的需求:同一URL下,站内用户通过mvc客户端登录后可访问应用和API,外部应用通过sapi客户端只能访问API,无法进入应用页面。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 07:54:23