向从外部提供者检索到的 JWT 添加其他声明(例如角色)

Posted

技术标签:

【中文标题】向从外部提供者检索到的 JWT 添加其他声明(例如角色)【英文标题】:Add additional claims (such as roles) to JWT retrieved from external providers 【发布时间】:2021-10-12 00:57:23 【问题描述】:

我有一个 .NET Core Web API(无 UI),它接受从多个外部身份提供者(比如 Google、Facebook 等)检索到的令牌。

例如,我还有一个数据库来检查用户角色

username                 | role  
------------------------------------
anderson.silva@gmail.com | superuser
billy.gates@hotmail.com  | user

问题是从这些外部身份提供者检索到的声明没有这些信息,所以我最终在我的方法中做了这样的事情

        public async Task<IActionResult> Get(string id)
        
            var role = await _uow.User.GetRoleByUsername(_username);

            if (role != "superuser") return Unauthorized();

            var product = await _uow.Product.GetByIdAsync(id);
            var result = _mapper.Map<ProductDTO>(product);
            return Ok(result);
          

而不是

        [Authorize(Roles = "superuser")]
        public async Task<IActionResult> Get(string id)
        
            var product = await _uow.Product.GetByIdAsync(id);
            var result = _mapper.Map<ProductDTO>(product);
            return Ok(result);
          

那么是否可以向令牌添加额外的声明,这样我就不需要在每个方法中检查角色?我环顾了 *** 和 CMIIW,但似乎大多数类似的问题都是基于网络的,因此他们可以在登录后添加声明并将其保存在 cookie 中,但我的只是一个没有任何 UI 和令牌的 web-api来自多个我无法控制的外部 IdP。

任何回复将不胜感激

【问题讨论】:

【参考方案1】:

简答:

由于JWT Token的首要要求是防止他人篡改,所以答案是否定的,你不能做修改JWT Token之类的事情。

详细解释:

您提到的可以参考 Oauth 授权代码流程,在这种情况下将信任第三方身份提供商,例如 google、facebook、...

为了做到这一点,使用您自己的应用程序角色,所有第三方身份提供者都不知道......就是制作您自己的身份服务器。

现在.net生态系统中,一些广泛使用的是:

如果您对 .net core 3.1 没问题,请使用 Identity server 4,因为它是免费且开源的。 如果您觉得费用合适,那么this 基本上是身份服务器付费版本。 OpenIdDict 是作为 Identity Server 4 过去美好时光的完整免费计划。

您可以使用 JWT 令牌以及会话方法实现自己的,只需将第三方 Jwt 令牌转换为您自己的。

为了简单起见,如果您真的需要它们,您可以创建一个属性并将您的授权逻辑移到那里

[AttributeUsage(AttributeTargets.Class)]
public class ApplicationAuthorizeAttribute : Attribute, IAuthorizationFilter

    public void OnAuthorization(AuthorizationFilterContext context)
    
        // Implement your own authorization logic here!!!
    

然后像这样在控制器中使用它

[ApplicationAuthorize]
public class WeatherForecastController : ControllerBase


【讨论】:

以上是关于向从外部提供者检索到的 JWT 添加其他声明(例如角色)的主要内容,如果未能解决你的问题,请参考以下文章

JWT 如何添加自定义声明和解码声明

Spring JWT - 添加自定义声明

SVM:向从图像中提取的特征向量添加临床特征

在 ServiceStack 中,我如何使用外部发布的 JWT

.NET Core 2.1 中的 HttpContext.GetTokenAsync 无法检索 JWT

Microsoft.IdentityModel.Tokens:添加其他声明