JWT –生成和验证令牌–示例

本文介绍了如何使用Nimbus JOSE + JWT库来生成和验证JWT(JSON Web Tokens)。首先解释了JWT的基本概念,然后展示了如何生成RSA密钥对,并使用这些密钥对创建包含声明的JWT。最后,文章提到了JWT的验证过程,并提供了相关代码示例。
摘要由CSDN通过智能技术生成

JWT提供了一种非常有趣的方式来表示可以验证和信任的应用程序之间的声明。 我的目标是展示一个小的样本,它使用出色的Nimbus JOSE + JWT库来生成和验证令牌。

总览

进行介绍的最佳地点之一是这里 。 简而言之,要从jwt.io网站的资料中借用,声明将表示为一个编码的json,分为三部分,并用点(。)分隔。

header.payload.signature

标头是json,其中包含用于对内容进行签名的算法类型(在本例中为RSA),然后对内容进行url和Base64编码:

{
  "alg": "RS512"
}

负载是一个包含所有声明的json,有保留的声明,但也允许私有声明:

{
  "sub": "samplesubject",
  "name": "John Doe",
  "iss": "sampleissueer",
  "admin": true,
  "exp": 1451849539
}

这里的“ sub”(主题),“ iss”(发布者)和“ exp”(到期)是保留的权利要求,而“ name”和“ admin”是私人权利要求。 然后对内容进行Base64Url编码。

最后,标头和有效负载一起使用共享密钥或私钥进行签名,并且签名经过Base64 url​​编码,并使用(。)分隔符附加到令牌中。

生成密钥对

我的样本是基于RSA的样本,因此第一步是生成密钥对。 JWK是一种将密钥存储为JSON表示形式的灵巧方法,Nimbus库对此提供了支持:

import java.security.KeyPairGenerator
import java.security.interfaces.{RSAPrivateKey, RSAPublicKey}

import com.google.gson.{GsonBuilder, JsonElement, JsonParser}
import com.nimbusds.jose.Algorithm
import com.nimbusds.jose.jwk.{JWKSet, KeyUse, RSAKey}

object JWKGenerator {

  def make(keySize: Integer, keyUse: KeyUse, keyAlg: Algorithm, keyId: String) = {
    val generator = KeyPairGenerator.getInstance("RSA")
    generator.initialize(keySize)
    val kp = generator.generateKeyPair()
    val publicKey = kp.getPublic().asInstanceOf[RSAPublicKey]
    val privateKey = kp.getPrivate().asInstanceOf[RSAPrivateKey]
    new RSAKey.Builder(publicKey)
      .privateKey(privateKey)
      .keyUse(keyUse)
      .algorithm(keyAlg)
      .keyID(keyId)
      .build()
  }
 ...

}

给定这个密钥对,可以使用Gson从中生成一个JWK:

def generateJWKKeypair(rsaKey: RSAKey): JsonElement = {
    val jwkSet = new JWKSet(rsaKey)
    new JsonParser().parse(jwkSet.toJSONObject(false).toJSONString)
  }

  def generateJWKJson(rsaKey: RSAKey): String = {
    val jsonElement  = generateJWKKeypair(rsaKey)
    val gson = new GsonBuilder().setPrettyPrinting().create()
    gson.toJson(jsonElement)
  }

一个基于JWK的示例密钥对如下所示:

{
  "keys": [
    {
      "p": "2_Fb6K50ayAsnnQl55pPegE_JNTeAjpDo9HThZPp6daX7Cm2s2fShtWuM8JBv42qelKIrypAAVOedLCM75VoRQ",
      "kty": "RSA",
      "q": "ye5BeGtkx_9z3V4ImX2Pfljhye7QT2rMhO8chMcCGI4JGMsaDBGUmGz56MHvWIlcqBcYbPXIWORidtMPdzp1wQ",
      "d": "gSjAIty6uDAm8ZjEHUU4wsJ8VVSJInk9iR2BSKVAAxJUQUrCVN---DKLr7tCKgWH0zlV0DjGtrfy7pO-5tcurKkK59489mOD4-1kYvnqSZmHC_zF9IrCyZWpOiHnI5VnJEeNwRz7EU8y47NjpUHWIaLl_Qsu6gOiku41Vpb14QE",
      "e": "AQAB",
      "use": "sig",
      "kid": "sample",
      "qi": "0bbcYShpGL4XNhBVrMI8fKUpUw1bWghgoyp4XeZe-EZ-wsc43REE6ZItCe1B3u14RKU2J2G57Mi9f_gGIP_FqQ",
      "dp": "O_qF5d4tQUl04YErFQ2vvsW4QoMKR_E7oOEHndXIZExxAaYefK5DayG6b8L5yxMG-nSncZ1D9ximjYvX4z4LQQ",
      "alg": "RS512",
      "dq": "jCy-eg9i-IrWLZc3NQW6dKTSqFEFffvPWYB7NZjIVa9TlUh4HmSd2Gnd2bu2oKlKDs1pgUnk-AAicgX1uHh2gQ",
      "n": "rX0zzOEJOTtv7h39VbRBoLPQ4dRutCiRn5wnd73Z1gF_QBXYkrafKIIvSUcJbMLAozRn6suVXCd8cVivYoq5hkAmcRiy0v7C4VuB1_Fou7HHoi2ISbwlv-kiZwTmXCn9YSHDBVivCwfMI87L2143ZfYUcNxNTxPt9nY6HJrtJQU"
    }
  ]
}

生成JWT

现在我们有了一个很好的示例密钥对,请加载私钥和公钥:

import java.time.{LocalDateTime, ZoneOffset}
import java.util.Date

import com.nimbusds.jose._
import com.nimbusds.jose.crypto._
import com.nimbusds.jose.jwk.{JWKSet, RSAKey}
import com.nimbusds.jwt.JWTClaimsSet.Builder
import com.nimbusds.jwt._

object JwtSample {
  def main(args: Array[String]): Unit = {
    val jwkSet = JWKSet.load(JwtSample.getClass.getResource("/sample.json").toURI.toURL)
    val jwk = jwkSet.getKeyByKeyId("sample").asInstanceOf[RSAKey]

    val publicKey = jwk.toRSAPublicKey
    val privateKey = jwk.toRSAPrivateKey
 ...
}

构建有效负载,对其进行签名并生成JWT:

val claimsSetBuilder = new Builder()
      .subject("samplesubject")
      .claim("name", "John Doe")
      .claim("admin", true)
      .issuer("sampleissueer")
      .expirationTime(Date.from(LocalDateTime.now().plusHours(1).toInstant(ZoneOffset.UTC)))

    val signer = new RSASSASigner(privateKey)


    val signedJWT: SignedJWT = new SignedJWT(
      new JWSHeader(JWSAlgorithm.RS512),
      claimsSetBuilder.build())

    signedJWT.sign(signer)

    val s = signedJWT.serialize()

该JWT的使用者可以读取有效负载并使用公共密钥对其进行验证:

val cSignedJWT = SignedJWT.parse(s)

    val verifier = new RSASSAVerifier(publicKey)

    println(cSignedJWT.verify(verifier))
    println(signedJWT.getJWTClaimsSet().getSubject())

结论

该样本完全基于Nimbus JOSE + JWT网站上提供的样本,如果您有兴趣进一步研究此内容,则绝对应参考Nimbus网站。

翻译自: https://www.javacodegeeks.com/2016/01/jwt-generating-validating-token-samples.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值