Spring OAuth2-JWT令牌在服务器上工作,但在本地主机上不工作?

n7taea2i  于 2022-09-21  发布在  Spring
关注(0)|答案(1)|浏览(188)

我看到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

出现错误的类是:OAuth2AuthenticationProcessingFilter.java(API Doc)

bt1cpqcv

bt1cpqcv1#

抱歉,我不会回答您的问题(@Toerkumlare是对的,您的安全配置缺失),但我会尝试解释为什么我不会将API网关作为OAuth2客户端。

简单地说,API网关的角色是系统资源的黑匣子,这可以使它被视为资源服务器,但在我看来,它应该对OAuth2(和其他身份验证机制)保持透明。让事情保持简单:

  • 客户端**(UI)处理用户登录(需要时)
  • 资源服务器**控制对资源的访问
  • 网关**(如果有)应尽可能保持透明,只为所有资源提供单一入口点。

在你的指南针里:

  • 如果要求您实施多因素身份验证,您预计会发生什么情况:除了登录/密码之外,还需要生物识别、外部应用程序验证、Goolger验证器令牌等之一?除了授权服务器之外,您真的打算在网关中实现所有这些功能吗?
  • 如果总是以api-gw-client作为客户端ID,您的授权服务器如何实现基于客户端的处理(如检查请求的作用域对于客户端是否合法,或向访问令牌添加客户端授权)?
  • 多租户场景怎么办(R1R2资源-网关后面的服务器需要来自不同颁发者的身份,或者C1C2客户端不根据相同的授权服务器对用户进行身份验证)?
  • 如果某些客户端和资源服务器使用的不是OAuth2,该怎么办?

此外,您的客户端还必须知道每个API端点接受和生成的媒体类型(XML、JSON、PDF、MULTART等)。并相应地设置Content-typeAccept报头。为什么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头并完全忽略用户登录。

相关问题