文章导读
一、创建安全的微服务
在微服务架构中实现可靠且强大的安全实现非常重要。微服务的体系结构向应用程序公开了多个入口点,并且通信可能需要多个网络跃点,因此未授权访问的风险很高。这需要比传统应用程序更多的计划。此外,由于REST服务的以下功能,使用REST端点的微服务中的安全性很难实现:
REST没有定义传输敏感数据的独特标准方法:至少有三种方法可以在REST中以安全的方式传输信息,包括OAuth2,OpenID Connect(OIDC)和JSON Web令牌(JWT)。
为避免互操作性问题和所提到的复杂性,请使用MicroProfile JWT规范来保护在您的微服务之间传递的信息。
该规范使用JSON Web令牌(JWT),这是一种基于令牌的身份验证,它定义了一种算法,以保证在基于REST的应用程序中以可靠和安全的方式传输任何敏感信息。
基于令牌的身份验证工作流涉及以下实体:
Issuer
在声明身份后发出安全令牌。 这通常是一个独特的微服务,作为身份提供者,提供JWT令牌生成器。
Client
从发行者请求令牌的微服务。
Subject
令牌中的信息所指的个人,系统或实体。
Resource Server
消耗令牌的微服务。
资源服务器使用以下令牌工作流:
1 从名为Authorization的字段中的标头中提取安全性令牌。
2 验证令牌检查签名,加密和到期检查。
3 提取有关主题的信息。
4 为主题创建安全上下文。
二、JWT内容完整性
为了避免任何数据操作并确保从发送方到最终目的地的消息的完整性,JWT规范要求JWT数据必须经过签名或加密。
JWT结构
生成的JWT内容使用以下格式进行组织:
xxxxxxxx.yyyyyyyyy.zzzzzzzzz
所有块都使用base64编码进行编码,以使其不易被人们阅读,以避免不需要的用户解析信息。
First Block xxxxxxxx
表示包含用于处理第二个块的信息的JWT标头,例如散列算法和令牌类型,即JWT。
Second Block yyyyyyyyy
表示包含添加到JWT的所有声明的JWT有效内容。 如果邮件已加密,则会对内容进行加密,然后使用base64编码进行编码。
Third Block zzzzzzzzz
表示标头和有效负载的签名,保证在传输过程中没有任何更改。
在下面的示例中,您有一个JWT,三个块中的每一个都用点分隔。
1. JWT头,包含散列算法和base64中编码的令牌类型。
2来自JWT的有效载荷,采用base64编码格式
3标头和有效载荷的签名在base64中编码。
三、在REST端点中传输JWT
需要发送敏感信息的REST端点必须首先向JWT令牌提供程序请求令牌。 在下图中,Microservice A使用JWT微服务提供程序进行身份验证。 验证身份验证后,JWT微服务提供程序返回一个JWT字符串,微服务A可以使用该字符串进行微服务B的身份验证.Microsvice Service A使用Authorization HTTP头字段发送JWT值。 为了被微服务B接受,Authorization头字段必须包含Bearer前缀,后跟JWT字符串。
四、用Java创建JWT
为了与每个服务提供单一功能的微服务架构保持一致,您可以创建一个微服务,为需要利用令牌的所有其他微服务提供JWT。 这种微服务被称为JWT提供商。 Java提供了诸如Auth0,Jose4J和Nimbus JOSE JWT之类的库来创建JWT。 本文使用Nimbus JOSE JWT实现。 在实现JWT生成器之后,生成的字符串用于访问安全的微服务,这将在后面的部分中讨论。 以下示例使用此库创建JWT:
1将声明创建为JSON对象,并使用声明枚举值定义已声明的声明和默认声明。
2实例化签署有效负载的对象。 您必须提供使用ssh-keygen命令创建的私钥,以实例化JWSSigner对象以对声明进行签名。
3将声明解析为JWTClaimsSet对象。
4使用适当的算法实例化JWSHeader对象。
5签署声明和标题:
6创建遵循JWT结构的base64编码内容。
7创建表示JWT结构的String。
四、实验展现:部署JSON Web令牌生成器
检查负责为微服务提供JSON Web令牌(JWT)的REST端点。
首先通过JBDS导入一个已有的maven项目:
通过展开左窗格JBoss Developer Studio中Project Explorer选项卡中的microservice-authz项打开AuthzResource类,然后单击microservice-authz→Java Resources→src / main / java→io.microprofile.showcase.tokens将其展开。 双击AuthzResource.java文件。
检查从端口捕获请求中的用户名和密码的REST端点。 createTokenForCredentials方法使用请求处理的Credentials对象访问用户名和密码。
检查将upn和preferred_username缺省声明添加到HashMap实例的REST端点,稍后将使用该实例生成JWT字符串。 HashMapobject作为参数传递给TokenUtils实用程序类,TokenUtils用于构建令牌字符串。
将自定义声明添加到应用程序使用的JWT字符串。
通过展开JBoss Developer Studio左侧窗格中Project Explorer选项卡中的microservice-authz项打开TokenUtils类,然后单击microservice-authz→Java Resources→src / main / java→io.microprofile.showcase.tokens将其展开。 双击TokenUtils.java文件。
在generateTokenString方法中,将名为dvlpr_nm的新声明添加到jwtContent对象。 使用您的姓名作为来源:
编译运行:
通过http工具发送用户名和密码:
在Headers选项卡中验证状态代码是否为200 OK。
得到token: