当前位置: 首页 > 后端技术 > Java

JWT学习笔记(一)

时间:2023-04-01 19:04:15 Java

这周在做单点登录。本次的用户信息单点登录分析是在JWT中分析用户信息,但是分析token是在第三方提供的文档中提供的,用于从JWT中分析用户信息。顺便解决不了,所以当时心态有点崩溃。后来查了一些资料,发现第三方给出的从JWT中解析用户信息的方式有问题,但是我对JWT还是不是很了解。所以打算系统的学习一下JWT。什么是JWT概述?学习新技术时,我一般喜欢简洁明了的官方文档。智威汤逊是智威汤逊的官方网站。JWT官网很好。乍一看,你想知道的是:JWT是JSON(不明白什么是JSON,可以看看我之前写的文章:一头雾水的JSON?)WEBToken(token)的缩写),所以从字面上我们可以把JWT理解为WEB中JSON形式的token,这个可以把token理解为通行证,进入系统的token。JSONWebToken(JWT)是一种开放标准(RFC7519),它定义了一种紧凑且独立的方式,用于在各方之间安全地传输信息作为JSON对象。JWT是RFC-7519在使用JSON在不同安全实体之间安全传输数据的一种(紧凑且自包含的)方法(或方式)中定义的开放标准。他的信息可以被验证和信任,因为它是经过数字签名的。JWT可以使用秘密(使用HMAC算法)或使用RSA或ECDSA的公钥/私钥对进行签名。信息可以被验证和信任。电子签名可以使用HMAC算法或RSA、ECDSA非对称加密的公私钥来实现。尽管可以对JWT进行加密以在各方之间提供保密性,但我们将重点关注已签名的令牌。签名令牌可以验证其中包含的声明的完整性,而加密令牌可以向其他方隐藏这些声明。当令牌是私有签名/使用私钥对时,签名还证明只有持有私钥的一方才是签名者。尽管JWT为两个安全实体之间的信息交换提供了安全性,因为它是加密的,但我们仍然专注于在令牌上签名。拥有签名令牌(或签名令牌)可验证其中包含的信息的完整性。加密令牌还隐藏了源信息。当令牌使用的签名方法持有公钥或私钥时,签名也可以验证持有私钥的一方是签署令牌的一方。什么是RFC?RFC是RequestforComments的缩写。在翻译中,可以理解为征求意见稿。互联网上有一系列的标准和协议,比如HTTP、TCP等,谁来推动或更新这些协议和标准呢?它由Internet工程任务组(IETF)推广和更新。RFC就像征求意见稿。每一次网络协议更新都会有相应的RFC,经过IETF审核通过后实施。1996年3月,清华大学提交的适应不同国家和地区中文编码的汉字统一传输标准被IETF采纳为RFC1922,成为中国大陆第一个被认可为RFC文档的提交协议。它可以用来做什么?授权:这是使用JWT最常见的场景。用户登录后,每个后续请求都将包含JWT,允许用户访问该令牌允许的路由、服务和资源。单点登录是如今广泛使用JWT的一项功能,因为它的开销很小并且能够轻松跨不同域使用。Authentication:这是JWT最常见的使用场景,只要用户成功登录一次,之后每次请求都携带JWT,就可以访问这个JWT允许访问的一切(我们可以理解为JWT是一个类似身份证的存在,服务器从请求中拿到JWT就可以知道当前登录的用户是谁,以及允许访问的资源)。如今,单点登录被广泛使用JWT实现,因为它的开销很低并且能够轻松地跨不同的安全实体使用。信息交换:JSONWebTokens是一种在各方之间安全传输信息的好方法。因为JWT可以签名——例如,使用公钥/私钥对——你可以确定发送者是他们所说的人。此外,由于签名是使用标头和有效负载计算的,因此您还可以验证内容是否未被篡改。信息交换:JWT是不同实体之间安全交换信息的一个很好的实现,因为JWT的签名,比如使用非对称加密,可以确定发送者的身份(防止第三方伪造),签名是计算出来的通过JWT的标头和负载。您可以使用它来验证信息是否已被修改。JWTcompositionheaderpayload可以理解为一个请求体,携带着要交换的信息。header携带的信息是加密的,也是用Base64URL加密的。JWT的三部分用.隔开,一个典型的JWT组成如下:xxxxx.yyyyy.zzzzz典型的header组成:{"alg":"HS256","typ":"JWT"}claimstoken的第二部分是有效负载,其中包含声明。声明是关于实体(通常是用户)和附加数据的声明。索赔分为三种类型:注册索赔、公共索赔和私人索赔。Payload携带交换的信息,交换的信息在声明中,交换的信息一般是一个实体(典型的是用户)和一些额外的数据,有三种类型的声明:Registeredclaims(定义的声明):这些是一组非强制性但推荐的预定义声明,以提供一组有用的、可互操作的声明。其中一些是:iss(发行者)、exp(到期时间)、sub(主题)、aud(受众)等。这些声明是预定义字段是可选的,但建议使用,用于提供一组有效的声明。一些比较典型的,比如iss(发行者),exp(过期时间),sub(主题主题)等等,为什么都是缩写呢?因为JWT要求紧凑。公共声明这些可以由使用JWT的人随意定义。但是为了避免冲突,它们应该在IANAJSONWeb令牌注册表中定义,或者定义为包含抗冲突名称空间的URI。这些可以由使用JWT的人自定义,但是为了避免冲突,定义后在IANAJSONWebTokenRegistry中注册,或者在URI中定义以避免冲突。私人声明:这些是为在同意使用它们的各方之间共享信息而创建的自定义声明,既不是注册声明也不是公共声明。我们可以把claims理解为字段,Registeredclaims理解为预定义的字段,Publicclaims理解为大家约定好的字段。有效负载也使用Base64加密。请注意,对于签名的令牌,此信息虽然受到防止篡改的保护,但任何人都可以读取。不要将秘密信息放在JWT的有效负载或标头元素中,除非它是加密的。如果信息没有加密,不建议在payload中放入机密信息,虽然可以对信息进行签名以保护其不被篡改,但任何人都可以阅读。有效负载示例:{"sub":"1234567890","name":"JohnDoe","admin":true}signature要创建签名部分,您必须采用编码标头、编码有效负载、秘密、指定算法在header中,然后对其进行签名。例如,如果要使用HMACSHA256算法,将通过以下方式创建签名:要创建签名部分,您需要根据请求标头中的加密算法。以下是使用HMACSHA256算法创建签名的典型示例:HMACSHA256(base64UrlEncode(header)+"."+base64UrlEncode(payload),secret)签名用于验证消息在传输过程中没有被更改,并且,在使用私钥签名的令牌的情况下,它还可以验证JWT的发送者是否是它所说的人。该签名的作用是验证信息在传输过程中是否被更改。在使用私钥签名的情况下,接下来我们可以验证发送方的身份。如何使用它?现在让我们尝试使用JWT。首先我们去maven私服找到对应的jar包:com.auth0java-jwt3.18.1生成JWT并解析JWTpublicclassTest{publicstaticvoidmain(String[]args){Stringstr=makeToken();解析令牌(str);}privatestaticvoidparseToken(Stringstr){//放入下发密钥并解密JWTJwtinfo=Jwts.parser().setSigningKey("changanbujian").parse(str);System.out.println(信息);}privatestaticStringmakeToken(){Mapheader=newHashMap<>();header.put("alg","HS256");header.put("typ","JWT");声明claims=newDefaultClaims();claims.setId("ccc").setSubject("aaa").setIssuer("bbb").setExpiration(新日期(System.currentTimeMillis()+1800*1000));Stringsecret="长安不间";//上面说了JWT需要Base64byt的形式e[]saltBase64=DatatypeConverter.parseBase64Binary(秘密);SignatureAlgorithmhs256=SignatureAlgorithm.HS256;SecretKeySpecsecretKeySpec=newSecretKeySpec(saltBase64,hs256.getJcaName());StringjwtToken=Jwts.builder().seter(claims).signWith(hs256,secretKeySpec).compact();返回jwtToken;}}总结一下,JWT是JSONWEBTOKEN的缩写,是token的一种形式,由三部分组成:header携带加密算法,payload携带信息签名,根据header和payload生成防止篡改并确认发送者的身份。在实际使用中,我们往往在原有JWT的基础上进行加密。只有加解密方法正确,才能从密文中解析出信息。参考文献JWT文档中英文翻译——简介JWT官网