我看到myapp
能够在服务器上正确处理OAuth2 JWT令牌,但它在本地主机上给出了令牌转换错误。
我的流程如下-
在服务器上,myapp
在我们的自定义api-gateway
后面
1.获取访问令牌-通过 Postman ,我点击了API-Gateway令牌端点,而后者又调用AuthServer令牌端点。我得到了OAuth JWT令牌作为响应。
总而言之, Postman
请求:--(Creds)-->api-ateway--(Samecreds)-->auth-server
**响应:**JWT TOKEN<--(同一JWT)--api-ateway<--(Jwt)--auth-server
1.接下来,我点击myapp
端点-再次通过 Postman ,我点击API-Gateway端点,这反过来又击中相应的myapp
端点。我得到了所需的回应。对于这个请求,在访问API-Gateway之前,我设置了标头Authorization: Bearer JWT from step1
作为myapp
开发人员,我知道API网关正在使用相同的头机制(即Authorization: Bearer JWT from step1
)将JWT令牌重新发送到myapp
。从日志中,我看到这与我在 Postman 中提供的api-gateway
相同的值
因此, Postman 请求:--(JWT)-->api-ateway--(同一JWT)-->myapp
回应是一些数据,这对这次讨论来说是微不足道的。
解码后的JWT有效载荷如下:
{
"app-userId": "c54a-4140-9fa0-0f39",
"user_name": "abc@xyz.com",
"scope": [
"all"
],
"exp": 1656929583,
"authorities": [
"app1_viewer",
"app1_modifier",
"app2_viewer",
"app2_blog_creator],
"client_id": "api-gw-client"
...
}
请注意上述有效载荷中的-"client_id": "api-gw-client"
字段。因此,身份验证服务器将令牌颁发给api-gateway
客户端。
现在,在运行在本地主机上的MyLocal dev env(即myapp
)上,我正在尝试实现与服务器上类似的流。
在本地主机上,myapp不是在API-Gateway后面运行,而是直接命中
1.获取访问令牌-通过 Postman ,我点击了API-Gateway(与上面的服务器流中的服务器示例相同。即API-Gateway/AUTH-SERVER不在本地主机上运行,而是在服务器上运行)令牌端点,令牌端点进而调用身份验证服务器令牌端点。我得到了OAuth JWT令牌作为响应。
因此, Postman 请求:--(Creds)-->api-ateway--(Samecreds)-->auth-server
返回:JWT TOKEN<--(相同JWT)--API-Gateway<--(JWT)--auth-server
可以,此令牌可以在服务器流步骤2中使用,并且可以正常工作。并且解码的JWT令牌有效负载与我之前发布的相同,即
{
"app-userId": "c54a-4140-9fa0-0f39",
"user_name": "abc@xyz.com",
"scope": [
"all"
],
"exp": 1656929583,
"authorities": [
"app1_viewer",
"app1_modifier",
"app2_viewer",
"app2_blog_creator],
"client_id": "api-gw-client"
...
}
请再次注意上述有效载荷中的-"client_id": "api-gw-client"
字段。因此,身份验证服务器将令牌颁发给api-gateway
客户端。我还不确定这个领域是微不足道的还是重要的。
1.接下来,我再次通过 Postman 点击**myapp
本地主机端点**,但我直接点击了myapp
端点(不是通过在本地主机上运行的API-网关)。对于这个请求,在点击之前,我设置了标头Authorization: Bearer JWT from step1
。
但这一次我收到错误:
P.A.OAuth2AuthationProcessingFilter:身份验证请求失败:错误=“INVALID_TOKEN”,ERROR_DESCRIPTION=“无法将访问令牌转换为JSON”
我想知道是什么导致了这个错误。我不认为这是client_id: api-gw-client
造成的。无论如何,我使用client_id: myapp
创建了一个签名的JWT令牌,并在请求中使用了它。但我还是收到了相同的错误。
我在本地主机上使用的key
与身份验证服务器用来签名的key
匹配(对应)。我又查了一遍。所以这肯定不是key
的问题。
我需要基于本地主机的设置工作,这样我就可以在本地测试我的API,而不需要部署到服务器(在我的情况下,部署到服务器相当耗时)。因此,这种设置对我在最后期限内完成任务非常重要。我们非常感谢您的回答/建议。
我的项目中使用的Spring OAuth2库如下-
1.org.springframework.security:spring-security-oauth2-jose:5.4.2
1.org.springframework.cloud:spring-cloud-starter-oauth2:2.1.3.RELEASE
1条答案
按热度按时间bt1cpqcv1#
抱歉,我不会回答您的问题(@Toerkumlare是对的,您的安全配置缺失),但我会尝试解释为什么我不会将API网关作为OAuth2客户端。
简单地说,API网关的角色是系统资源的黑匣子,这可以使它被视为资源服务器,但在我看来,它应该对OAuth2(和其他身份验证机制)保持透明。让事情保持简单:
在你的指南针里:
api-gw-client
作为客户端ID,您的授权服务器如何实现基于客户端的处理(如检查请求的作用域对于客户端是否合法,或向访问令牌添加客户端授权)?R1
和R2
资源-网关后面的服务器需要来自不同颁发者的身份,或者C1
和C2
客户端不根据相同的授权服务器对用户进行身份验证)?此外,您的客户端还必须知道每个API端点接受和生成的媒体类型(XML、JSON、PDF、MULTART等)。并相应地设置
Content-type
和Accept
报头。为什么Authorization
标头会有所不同?在我看来,如果您想节省时间和精力,请使用您的API网关来代理仅您的资源服务器。离开授权-服务器离开。对于您不维护但您的客户端需要的外部API(推特提要、Google API等)也是如此。
This is how I always configure my resource-servers:
Authorization
头丢失或无效(格式错误、过期、发行者错误、受众不佳等)=>401(未经授权),而不是302(重定向至登录)在多租户场景下,为什么资源服务器要费心去计算重定向到哪个授权服务器?
对于不是在浏览器中运行的客户端,如移动应用,重定向应该是什么意思?
Authorization
标头有效,但关联的声明无法通过访问控制(例如,错误的权限或不是预期的主体)=>403(禁止)客户端应该知道如何获取所需的访问令牌,以及在发送请求时如何设置
Authorization
头(这就是您目前使用Postman所做的)。它甚至可以拦截401以触发用户认证,然后重试失败的资源访问。严肃的OAuth2客户端库(如angular-auth-oidc-client代表Angular )提供了这样的功能。有了这样的客户端,网关可以充当您的资源服务器(以及授权服务器或外部API,如果您喜欢,但为什么?)的门面,转发
Authorization
头并完全忽略用户登录。