问题描述
就像 AzureAD 一样,我们有我们自己的自定义 Firm ActiveDirectory,我们使用 OpenIdConnect(AddOpenIdConnect 扩展方法)从 UI 以及 .NetCore 中的身份验证 API 进行连接。 在我在 UI 端进行身份验证后的用例中,我需要从我添加“OnTokenValidated”的自定义数据库中获得其他特定于应用程序的声明 - 这是隐藏或公开基于角色和声明的 UI 元素所必需的。
OnTokenValidated = async ctx =>
{
//Get user's immutable object id from claims that came from Azure AD
string oid = ctx.Principal.FindFirstValue("http://schemas.microsoft.com/identity/claims/objectidentifier");
//Get EF context
var db = ctx.HttpContext.RequestServices.GetrequiredService<AuthorizationDbContext>();
//Check is user a super admin
bool isSuperAdmin = await db.SuperAdmins.AnyAsync(a => a.ObjectId == oid);
if (isSuperAdmin)
{
//Add claim if they are
var claims = new List<Claim>
{
new Claim(ClaimTypes.Role,"superadmin")
};
var appIdentity = new ClaimsIdentity(claims);
ctx.Principal.AddIdentity(appIdentity);
}
}
现在在 API 端再次验证令牌后,我必须调用自定义数据库来获取应用程序特定的角色。是否可以将这些角色包含在 JWT 令牌本身中,以便在 API 端所有角色和声明(AD + 自定义数据库)都存在。或者我不必在 API 中再次调用 CustomDB 的任何其他方式。
解决方法
向访问令牌添加自定义声明是授权服务器 (AS) 的一项功能,并非所有授权服务器都支持此功能 - 尽管它们应该支持,因为这是一项重要功能。如果您能准确说出您使用的是哪个提供商,我或许可以告诉您这是否可行。
以下是需要考虑的因素:
-
了解 AS 是否可以在令牌发行时联系并获得自定义声明,如 this Curity article。
-
注意不要将详细的 JWT 返回给 Internet 客户端,而应将它们保留在您的后端。不透明令牌可以帮助解决这个问题,如 this other Curity article
-
如果您的提供者无法使用自定义声明,那么您可以在首次收到访问令牌时在您的 API 中查找它们,然后将声明缓存在内存中。这会导致更复杂的 API 代码,但对于某些提供商来说是必需的。