[安全 】JWT初学者入门指南

本文涉及的产品
密钥管理服务KMS,1000个密钥,100个凭据,1个月
简介: [安全 】JWT初学者入门指南

令牌身份验证,OAuth或JSON Web令牌的新手?这是一个很好的起点!

首先,什么是JSON Web令牌,或JWT(发音为“jot”)?简而言之,JWT是用于令牌认证的安全且值得信赖的标准。JWT允许您使用签名对信息(称为声明)进行数字签名,并且可以在以后使用秘密签名密钥进行验证。

什么是令牌认证?

应用程序确认用户身份的过程称为身份验证。传统上,应用程序通过会话cookie保持身份,这些cookie依赖于服务器端存储的会话ID。在此结构中,开发人员被迫创建独特且特定于服务器的会话存储,或实现为完全独立的会话存储层。

令牌认证是一种更现代的方法,设计解决了服务器端会话ID无法解决的问题。使用令牌代替会话ID可以降低服务器负载,简化权限管理,并提供更好的工具来支持分布式或基于云的基础架构。在此方法中,为用户提供可验证凭据后会生成令牌。初始身份验证可以是用户名/密码凭据,API密钥,甚至来自其他服务的令牌。(Stormpath的API密钥身份验证功能就是一个例子。)

有兴趣了解更多?查看此博客文章,了解如何使用令牌扩展用户管理或完整的产品文档。

JWT的剖析

如果您在野外遇到JWT,您会注意到它分为三个部分,标题,有效负载和签名。(随着我们剖析JWT的解剖结构,请关注Stormpath的开源Java JWT工具!)以下是典型JWT的示例:

eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9
.
eyJzdWIiOiJ1c2Vycy9Uek1Vb2NNRjRwIiwibmFtZSI6IlJvYmVydCBUb2tlbiBNYW4iLCJzY29wZSI6InNlbGYgZ3JvdXBzL2FkbWlucyIsImV4cCI6IjEzMDA4MTkzODAifQ
.
1pVOLQduFWW3muii1LExVBt2TK1-MdRI4QjhKryaDwc

在此示例中,第1节是描述令牌的标头。第2节是有效载荷,其中包含JWT的声明,第3节是签名散列,可用于验证令牌的完整性(如果您有用于签名的密钥)。

当我们解码有效载荷时,我们得到这个包含JWS声明的漂亮,整洁的JSON对象:

{
  "sub": "users/TzMUocMF4p",
  "name": "Robert Token Man",
  "scope": "self groups/admins",
  "exp": "1300819380"
}

要求(Cliam) 告诉你,至少:

  • 这个人是谁以及他们的用户资源的URI(子要求)
  • 此人可使用此令牌访问的内容(范围声明)
  • 令牌过期时您的API应在验证令牌时使用此功能。

因为令牌是使用密钥签名的,所以您可以验证其签名并隐含地信任所声称的内容。

JWE,JWS和JWT

根据JWT规范,“JWT将一组声明表示为以JWS和/或JWE结构编码的JSON对象。”术语“JWT”在技术上仅描述了无符号标记;我们称之为JWT的通常是JWS或JWS + JWE。

JWS - JSON Web签名

在JWS方案中,服务器对JWT进行签名并使用签名将其发送到客户端。签名保证了JWT要求没有被伪造或篡改。但是,JWT未加密(内容基本上是纯文本)。

JWE - JSON Web加密

另一方面,JWE方案在不签名的情况下加密内容。这为您的JWT带来了机密性,但不是JWE签名和封装JWE的安全性。

什么是OAuth?

OAuth 2.0是与可以委派身份验证或提供授权的服务进行交互的框架。它被广泛用于许多移动和Web应用程序。OAuth 2.0没有指定令牌格式,但JWT正在迅速成为业界的事实标准。

在OAuth范例中,有两种令牌类型:访问和刷新令牌。首次进行身份验证时,通常会为您的应用程序(以及您的用户)提供两个令牌,但访问令牌设置为在短时间后过期(此持续时间可在应用程序中配置)。初始访问令牌到期后,刷新令牌将允许您的应用程序获取新的访问令牌。刷新令牌具有设置的到期时间,允许无限制地使用,直到达到该到期点。Access和Refresh Tokens都具有内置安全性(签名时)以防止篡改,并且仅在特定持续时间内有效。

Stormpath使用OAuth,因为它是一个行业标准,任何兼容的库都可以利用它。Stormpath目前支持三种OAuth的授权类型:

  • 密码授予类型:提供基于用户名和密码获取访问令牌的功能
  • 刷新授权类型:提供基于特殊刷新令牌生成另一个访问令牌的功能
  • 客户端凭据授权类型:提供为访问令牌交换API密钥对的功能。这通过API密钥管理功能得到支持

用Java创建和验证JWT

所以,你在代币上出售,现在,你如何在你的应用程序中使用它们?

好吧,如果你是Java开发人员,你应该从JJWT开始。JJWT是一个Java库,提供由我们自己的Les Hazlewood开发并由开发人员社区维护的端到端JSON Web令牌创建和验证。永远免费和开源(Apache许可证,版本2.0),它设计了一个以构建者为中心的界面,隐藏了其大部分复杂性。

创建

由于JJWT的流畅界面,JWT的创建基本上分为三个步骤:

令牌的内部声明的定义,如Issuer,Subject,Expiration和ID。

密码签名JWT(制作JWS)

根据JWT Compact Serialization规则,将JWT压缩为URL安全字符串

最终的JWT将是一个由三部分组成的Base64编码字符串,使用提供的密钥使用指定的签名算法进行签名。在此之后,令牌已准备好与另一方共享。

这是使用JJWT库从上面创建JWT的示例:

String jwt = Jwts.builder()
  .setSubject("users/TzMUocMF4p")
  .setExpiration(new Date(1300819380))
  .claim("name", "Robert Token Man")
  .claim("scope", "self groups/admins")
  .signWith(
    SignatureAlgorithm.HS256,
    "secret".getBytes("UTF-8")
  )
  .compact();

证实

一旦拥有JWT,您通常会将其交还给请求它的客户端。然后,客户端将其存储并将请求中的令牌传递给您的应用程序。这通常使用HTTP中的cookie值或授权标头来完成。例如:

HTTP/1.1

 

GET /secure-resource

 

Host: https://yourapplication.com

 

Authorization: Bearer eyJraWQiOiIzMUUzRDZaM0xaMVdFSEJGWVRQRksxRzY4IiwiYWxnIjoiSFMyNTYifQ.eyJqdGkiOiI2a3NjVFMyUjZuYlU3c1RhZ0h0aWFXIiwiaWF0IjoxNDQ1ODU0Njk0LCJpc3MiOiJodHRwczovL2FwaS5zdG9ybXBhdGguY29tL3YxL2FwcGxpY2F0aW9ucy8zUUlNbEpLS04yd2hHQ1l6WFh3MXQ4Iiwic3ViIjoiaHR0cHM6Ly9hcGkuc3Rvcm1wYXRoLmNvbS92MS9hY2NvdW50cy8xeG15U0dLMXB5VVc1c25qOENvcmU1IiwiZXhwIjoxNDQ1ODU4Mjk0LCJydGkiOiI2a3NjVE9pTUNESVZWM05qVTIyUnlTIn0.VJyMOicMOdcOCtytsx4hoPHy3Hl3AfGNfi2ydy8AmG4

验证JWT允许您验证其真实性(通过检查其数字签名,您可以检查它是否已过期并验证它是否未被篡改)并获取有关发送令牌的用户的信息。

以下是验证我们在上面创建的JWT的示例:

String jwt = <jwt passed in from above>
Jws<Claims> claims = Jwts.parser()
  .setSigningKey("secret".getBytes("UTF-8"))
  .parseClaimsJws(jwt)
String scope = claims.getBody().get("scope")
assertEquals(scope, "self groups/admins");

如果签名不正确,则对parseClaimsJws的调用将抛出SignatureException。成功解析后,可以获取并检查单个声明,如下所示:String scope = claims.getBody()。get(“scope”)。

例外

JJWT在与JWT合作时进行了各种验证。所有与JJWT相关的异常都是RuntimeExceptions,以JwtException作为基类。

这些错误会导致抛出特定异常:

  • ClaimJwtException:在验证JWT声明失败后抛出
  • ExpiredJwtException:表示JWT在过期后被接受,必须被拒绝
  • MalformedJwtException:当JWT未正确构造并且应该被拒绝时抛出
  • PrematureJwtException:表示JWT在被允许访问之前被接受,必须被拒绝
  • SignatureException:表示计算签名或验证JWT的现有签名失败
  • UnsupportedJwtException:在接收到与应用程序预期格式不匹配的特定格式/配置的JWT时抛出。例如,如果在应用程序需要加密签名的声明JWS时解析无符号明文JWT,则会抛出此异常
  • JJWT使用了许多其他Exception类。它们都可以在JJWT源代码中的io.jsonwebtoken包中找到。

令牌安全吗?

这里真正的问题是,你安全地使用它们吗?在Stormpath,我们遵循这些最佳实践,并鼓励我们的客户也这样做:

  • 将您的JWT存储在安全的HttpOnly cookie中。这可以防止跨站点脚本(XSS)攻击。
  • 如果您使用cookie来传输JWT,CSRF保护非常重要!未经用户同意,向您的网站提出请求的其他域名可能会恶意使用您的Cookie。如果您的服务器盲目地对用户进行身份验证,只是因为他们有cookie,那么您遇到的问题比硬盘驱动器大。您还允许进行CSRF攻击,其他网站会在未经用户同意的情况下触发您服务器上的状态更改操作。这是可能的,因为浏览器将始终自动发送用户的cookie,无论请求是如何被触发的。使用众多CSRF预防措施之一来降低此风险。
  • 使用仅可用于身份验证服务的强密钥对您的令牌进行签名。每次使用令牌对用户进行身份验证时,您的服务器必须验证令牌是否已使用您的密钥签名。
  • 不要将任何敏感数据存储在JWT中。这些令牌通常被签名以防止操纵(未加密),因此可以容易地解码和读取权利要求中的数据。如果您必须在其中放入敏感的,不透明的信息,请加密您的令牌。秘密签名密钥只能由发行方和消费者访问;它不应该在这两方之外进行。
  • 如果您担心重播攻击,请在声明中包含nonce(jti声明),到期时间(exp声明)和创建时间(ifat声明)。这些在JWT规范中有明确定义。

JJWT,JSONWebToken.io和JWT Inspector

Stormpath支持开发几个与JWT相关的开源开发人员工具,包括:

JJWT

JJWT是一个易于使用的工具,供开发人员用Java创建和验证JWT。在Stormpath支持的许多库中,JJWT是完全免费和开源的(Apache License,Version 2.0),因此每个人都可以看到它的作用以及它是如何做到的。不要犹豫,报告任何问题,建议改进,甚至提交一些代码!

JSONWebToken.io

JSONwebtoken.io是我们创建的一个开发工具,可以轻松解码JWT。将现有JWT简单粘贴到适当的字段中以解码其标头,有效负载和签名。JSONWebToken.io由nJWT提供支持,nJWT是Node.js开发人员最干净的免费和开源(Apache License,Version 2.0)JWT库。

JWT检查器

JWT Inspector是一个开源的Chrome扩展程序,允许开发人员直接在浏览器中检查和调试JWT。JWT Inspector将在您的站点上发现JWT(在cookie,本地/会话存储和标题中),并通过导航栏和DevTools面板轻松访问它们。

想要了解有关JWT,令牌认证或用户身份管理的更多信息?以下是我们团队的一些进一步资源:

  • 单页应用程序的令牌认证
  • 使用Spring Boot和Stormpath进行OAuth令牌管理
  • Java应用程序的令牌认证
  • 使用JSON Web令牌构建安全的用户界面
  • OAuth不是单点登录
相关文章
|
存储 JSON 安全
解锁互联网安全的新钥匙:JWT(JSON Web Token)
解锁互联网安全的新钥匙:JWT(JSON Web Token)
249 0
|
5月前
|
JSON 安全 数据安全/隐私保护
Python安全新篇章:OAuth与JWT携手,开启认证与授权的新时代
【8月更文挑战第6天】随着互联网应用的发展,安全认证与授权变得至关重要。本文介绍OAuth与JWT两种关键技术,并展示如何结合它们构建安全系统。OAuth允许用户授权第三方应用访问特定信息,无需分享登录凭证。JWT是一种自包含的信息传输格式,用于安全地传递信息。通过OAuth认证用户并获取JWT,可以验证用户身份并保护数据安全,为用户提供可靠的身份验证体验。
66 6
|
6月前
|
存储 JSON 安全
OAuth2与JWT在API安全中的角色:技术深度解析
【7月更文挑战第20天】OAuth2和JWT作为两种重要的安全协议,在API安全中发挥着不可或缺的作用。OAuth2通过提供灵活的授权框架,实现了对资源的细粒度访问控制;而JWT则通过其紧凑性和自包含性,确保了身份验证和信息传输的安全性。在实际应用中,将OAuth2和JWT结合使用,可以构建出既强大又安全的API服务,为用户提供更加安全、可靠和便捷的数字体验。
|
5月前
|
安全 Nacos 数据安全/隐私保护
【技术干货】破解Nacos安全隐患:连接用户名与密码明文传输!掌握HTTPS、JWT与OAuth2.0加密秘籍,打造坚不可摧的微服务注册与配置中心!从原理到实践,全方位解析如何构建安全防护体系,让您从此告别数据泄露风险!
【8月更文挑战第15天】Nacos是一款广受好评的微服务注册与配置中心,但其连接用户名和密码的明文传输成为安全隐患。本文探讨加密策略提升安全性。首先介绍明文传输风险,随后对比三种加密方案:HTTPS简化数据保护;JWT令牌减少凭证传输,适配分布式环境;OAuth2.0增强安全,支持多授权模式。每种方案各有千秋,开发者需根据具体需求选择最佳实践,确保服务安全稳定运行。
453 0
|
5月前
|
JSON 安全 数据安全/隐私保护
🔒Python安全新纪元:揭秘OAuth与JWT如何守护你的认证王国👑
【8月更文挑战第4天】互联网应用的繁荣让数据安全与用户认证至关重要。在Python领域,OAuth与JWT成为保障认证安全的关键技术。OAuth作为授权框架,允许第三方应用安全地访问用户数据,无需暴露密码。JWT则是一种轻量级的信息交换标准,能安全地在客户端和服务端之间传递认证信息。结合二者,可以构建强大的认证体系,显著增强应用的安全性和用户体验。
40 0
|
8月前
|
JSON 安全 网络安全
超详细的用户认证、权限、安全原理详解(认证、权限、JWT、RFC 7235、HTTPS、HSTS、PC端、服务端、移动端、第三方认证等等)
超详细的用户认证、权限、安全原理详解(认证、权限、JWT、RFC 7235、HTTPS、HSTS、PC端、服务端、移动端、第三方认证等等)
1169 0
|
安全 Java 数据库
Spring Boot 3 + JWT + Security 联手打造安全帝国:一篇文章让你掌握未来!
`Spring Security`已经成为`java`后台权限校验的第一选择.今天就通过读代码的方式带大家深入了解一下Security,本文主要是基于开源项目[spring-boot-3-jwt-security](https://github.com/ali-bouali/spring-boot-3-jwt-security)来讲解Spring Security + JWT(Json Web Token).实现用户鉴权,以及权限校验. 所有代码基于`jdk17+`构建.现在让我们开始吧!
2647 1
 Spring Boot 3 + JWT + Security 联手打造安全帝国:一篇文章让你掌握未来!
|
存储 安全 前端开发
深入探讨安全验证:OAuth2.0、Cookie与Session、JWT令牌、SSO与开放授权平台设计
这篇文章讨论了认证和授权的概念,并探讨了设计权限认证框架的原则。它还比较了Cookie和Session的区别,并探讨了处理分布式部署时的Session保存问题。此外,文章还介绍了CSRF攻击及其防范方法,以及OAuth2.0、JWT令牌和SSO的概念。最后,文章提出了设计开放授权平台时需要考虑的因素。
232 0
深入探讨安全验证:OAuth2.0、Cookie与Session、JWT令牌、SSO与开放授权平台设计
|
SQL 存储 安全
AVA安全-JWT安全&预编译CASE注入
AVA安全-JWT安全&预编译CASE注入
106 0
|
安全 Java 数据安全/隐私保护

热门文章

最新文章