JWT 子声明在验证期间被忽略

Posted

技术标签:

【中文标题】JWT 子声明在验证期间被忽略【英文标题】:JWT sub claim gets ignored during verification 【发布时间】:2019-08-20 16:05:08 【问题描述】:

好吧,这个问题可能很幼稚,因为我是第一次在我的节点应用程序中实现 JWT,我对此有太多疑问。

首先我不清楚isssubaud 的说法。根据我的基本理解,我知道iss 是令牌的发行者,所以我可以假设它是应用程序的公司名称。 sub 是令牌的主题,或者简单来说可能是用户身份/用户名。最后,aud 是针对观众的,或者简单来说就是 api 服务器 url/资源服务器。请让我知道我是否正确理解了这些条款。

现在,以我有限的知识,我已经设置了基本的 JWT 签名和验证。一个小sn-p如下:

JWT.js

module.exports = 
sign: (payload, options) => 
    let signOptions = 
        issuer: config.JWT_ISSUER,
        subject: options.subject,
        audience: config.JWT_AUDIENCE,
        expiresIn: "24h",
    ;

    return jwt.sign(payload, config.JWT_SECRET, signOptions);
,
verify: (token, options) => 
    let verifyOptions = 
        issuer: config.JWT_ISSUER,
        subject: options.subject,
        audience: config.JWT_AUDIENCE,
        expiresIn: "24h",
    ;

    try 
        return jwt.verify(token, config.JWT_SECRET, verifyOptions);
    
    catch (err)
        return false;
    
,

现在代币发行如下:

// Issue JWT token
let userData = 
    user_name: user.userName,
    client_id: user.clientId
;
const token = jwt.sign( userData ,  subject: user.userName );

验证如下:

// Verify the token
const authData = jwt.verify(token,  subject: req.body.subject );  

主要问题

当我向 api 端点发送请求以进行验证时,如果我在正文中没有主题字段(发出的令牌带有子字段) ,令牌验证成功。但是,如果我在正文中发送带有正确/不正确值的主题字段,它将分别获得成功/禁止。

为什么会这样? 为什么请求中没有传递子字段时令牌不被禁止? 我需要手动验证吗?

【问题讨论】:

【参考方案1】:

根据JWT standard,

4.1.2。 “sub”(主题)声明

“子”(主体)声明标识了作为主体的主体 JWT 的主题。 JWT 中的声明通常是语句 关于主题。主题值必须被限定为 在发行人的上下文中是本地唯一的,或者是全球唯一的。 此声明的处理通常是特定于应用程序的。这 "sub" 值是包含 StringOrURI 的区分大小写的字符串 价值。使用此声明是可选的。

因此,当您没有它时,它会通过,但不正确的值会导致失败。 jwt 包遵循标准。

现在,如果您打算将其设为强制性,则必须对其进行自定义,但请注意,您可能无法使用不认为这是强制性的第 3 方身份验证(如果这是您的用例)。 (不知道现实生活中是不是这样)

【讨论】:

““sub”(主题)声明标识了作为 JWT 主题的主体。”- 我可以假设它是应用程序的特定用户吗?这个假设正确吗? 或者你能告诉我什么样的价值观适合 iss、sub 和 aud 的主张吗?

以上是关于JWT 子声明在验证期间被忽略的主要内容,如果未能解决你的问题,请参考以下文章

jwt验证

基于jwt的token验证

springboot之Jwt验证

如何在身份服务器 4/身份验证代码流中请求访问令牌的附加声明?

在测试期间使用 Django Rest + JWT 进行身份验证

验证期间访问 JWT Token