简体   繁体   中英

How to use one JWT token to sign a second JWT token?

The Scenario: A web-app user wants to create an authorised view of a private asset. The user has authenticated and has a jwt token. The app wants to make a fresh secondary jwt token, which can be verified as having been created with the original token.

FYI: My use case is signing a url - adding the second jwt token to the url, to allow controlled public viewing of the private asset.

How should the app do that?

Eg is there a recommended way to set secret and alg for this 2nd token?

In theory, to use one jwt to sign another, you'd use the HS256 algorithm, with the first jwt as the secret. In practice, this approach leads to a couple of issues, outlined below:

Firstly, only the server and the original token-holder will be able to verify the authenticity of this token, and in order for the server to perform verification, you'll need to persist the original token somewhere. This is outside the scope of your question, but it does begin to complicate the implementation, since now both tokens mush share a lifespan, and the original token needs to be available wherever the second token might be used. That might not be an issue for your use case but it does somewhat limit portability, as well as future-proofing if, for example, another party needed to verify the token (such a use case can be achieved without too much overhead by using RS256 and asymmetric keys instead of the HS256/symmetric key method).

Secondly, JWTs are commonly transient values with short lifespan. This is usually due to the nature of their use: since they are shared between a client and server, they are not strictly speaking "secret" values, and the longer they live, the greater the chance that they may have been compromised. In using them as secret material for other tokens, you now require a longer lifespan for those tokens, and you are potentially introducing a security vulnerability wherein the "secondary" tokens could be spoofed by an attacker who gets their hands on one of these "primary" tokens. In order mitigate this specific threat, secret material should be something that is not transmitted over the network.

Perhaps you might consider using the same token generation procedure (same algorithm & secret) for both tokens, and simply include an identifier for the "issuer" (a unique identifier for the user who holds the original token) as part of the second token. Using this method, you don't need to worry about which verification process to use for a given token (since it's now the same for both), nor do you have to worry about token lifespan or key spoofing through a stolen token.

I think the best answer is You shouldn't , at least not on the client side. If you mean your back-end is node or something, you could do something like this.

  1. Have the client make an authenticated request to give me access to resource x.
  2. The server can at that point take any information from the original token to create a new JWT token, with the data below.
  3. Sign the jwt serverside with whatever method you prefer (I would always use RS256, with certificate).
  4. Respond the the client with, you can access the resource at protected/resource_x?key=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiJodHRwczovL3lvdXIud2ViLnNpdGUvcHJvdGVjdGV4L3Jlc291cmNlX3giLCJpc3MiOiJodHRwczovL3lvdXIud2ViLnNpdGUiLCJleHAiOjE2MTU4MTIyOTQ5ODMsInNjcCI6InByaXZhdGVfcmVzb3VyY2UiLCJzdWIiOiJvcmlnaW5hbC11c2VyLWlkLWZyb20tY2xpZW50LXRva2VuIn0.cga9CQ1IqUwzBRgYM3vlUN0g37yJWZREQQEExV29UWs

Your jwt can contain the following information:

{
  "aud": "https://your.web.site/protectex/resource_x",
  "iss": "https://your.web.site",
  "exp": 1615812294983,
  "scp": "private_resource",
  "sub": "original-user-id-from-client-token"
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM