4

我正在尝试为我的 Web 应用程序实现单点登录。我正在使用 gravitee.io 进行访问管理和令牌生成。我按照gravitees 快速入门教程中的步骤进行操作,现在我想验证我的 id_token。

为了做到这一点,我正在使用node-jsonwebtoken库。我正在使用total.js作为我的后端(这不应该那么重要,但我仍然想提一下)。

到目前为止我做了什么。我在 total.js 配置文件中有我的客户端 ID 和我的客户端密码以及我的域密码

./configs/myconfig.conf(密钥/秘密已更改)

url                 : https://sso.my-graviteeInstance.com/am
client-id           : myClientId
client-secret       : uBAscc-zd3yQWE1AsDfb7PQ7xyz
domain              : my_domain
domain-public-key   : EEEEEB3NzaC1yc2EAAAADAQABAAABAQCW4NF4R/sxG12WjioEcDIYwB2cX+IqFJXF3umV28UCHZRlMYoIFnvrXfIXObG7R9W7hk6a6wbtQWERTZxJ4LUQnfZrZQzhY/w1u2rZ3GEILtm1Vr1asDfAsdf325dfbuFf/RTyw666dFcCcpIE+yUYp2PFAqh/P20PsoekjvoeieyoUbNFGCgAoeovjyEyojvezxuTidqjaeJvU0gU4usiiDGIMhO3IPaiAud61CVtqYweTr2tX8KabeK9NNOXlTpLryBf3aTU1iXuU90mijwXZlmIzD28fWq+qupWbHcFZmmv3wADVddnxZHnFIN7DHGf5WVpb3eLvsGkIIQpGL/ZeASDFa

我添加了一个模型来处理 total.js 的登录工作流,以便通过 REST 调用从 gravitee 获取 jwt 令牌。到目前为止,一切都按预期工作。创建一个会话并将响应存储在其中。被邀请的响应是预期的 json,看起来像这样

{
  access_token: 'some-long-token',
  token_type: 'bearer',
  expires_in: 7199,
  scope: 'openid',
  refresh_token: 'another-long-token',
  id_token: 'last-long-token'
}

我将令牌拆分为单独的 cookie,因为当我尝试将它们保存为单个 cookie 时,我收到一条错误消息,告诉我 cookie 超出了 4096 长度限制。

到目前为止,一切正常。在前端 ajax 调用中将执行成功回调,只需设置window.location.href='/';调用我的应用程序的仪表板。我将此路由设置为仅在授权时可访问,这样当我的仪表板被调用时,totaljs 会调用 onAuthorize 函数。

F.onAuthorize = function (req, res, flags, callback) {
  let cookie = mergeCookies(req.cookie);
  
  // Check the cookie length
  if (!cookie || cookie.length < 20) {
    console.log(`cookie not defined or length to low`);
    return callback(false);
  }

  if (!cookie) {
    console.log(`cookie undefined`);
    return callback(false);
  }

  // Look into the session object whether the user is logged in
  let session = ONLINE[cookie.id];
  if (session) {
    console.log(`there is a session`);
    // User is online, so we increase his expiration of session
    session.ticks = F.datetime;

    jwt.verify(
      session.id_token, 
      Buffer.from(CONFIG('client-secret')).toString('base64'),
      function(err, decoded){
        if (err) {
          console.log(`jwt verify error: ${err}`);
          return callback(false);
        }
        console.log(`decoded token user id: ${decoded.sub}`);
        return callback(true, session);
      })
  }
  console.log(`false`);
  callback(false);
};

我也尝试只发送CONFIG('client-secret')而不缓冲。我也尝试发送CONFIG('domain-public-key'). 但我得到的错误总是一样的:

jwt verify error: JsonWebTokenError: invalid algorithm

当我将 id_token 复制并粘贴到 jwt.io 的调试器中时算法beeing 设置为 RS256,我将看到以下解码值:

// header
{
  "kid": "default",
  "alg": "RS256"
}

// payload
{
  "sub": "some-generated-id",
  "aud": "myClientId",
  "updated_at": 1570442007969,
  "auth_time": 1570784329896,
  "iss": "https://sso.my-graviteeInstance.com/am/my_domain/oidc",
  "preferred_username": "myUsername",
  "exp": 1570798729,
  "given_name": "Peter",
  "iat": 1570784329,
  "family_name": "Lustig",
  "email": "peter.lustig@domain.com"
}

我将我的域中的公钥复制到相应的文本字段中,并且我还尝试使用客户端密钥。无论我做什么,我在这里遇到的错误是

警告:您的 JWT 签名似乎未使用 base64url ( https://www.rfc-editor.org/rfc/rfc4648#section-5 ) 正确编码。请注意,必须根据 https://www.rfc-editor.org/rfc/rfc7515#section-2省略填充(“=”)

我不明白为什么当我尝试验证后端中的令牌时出现算法错误以及jwt.io调试器中的一些编码错误。

有人可以向我解释如何解决这个问题吗?提前感谢帕斯卡

编辑:更改标题

4

0 回答 0