繁体   English   中英

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

[英]Spring OAuth2 - JWT token working on server but not on localhost?

我看到myapp能够在服务器上正确处理 OAuth2 JWT 令牌,但它在本地主机上给出令牌转换错误。

我的流程如下 -

在 Server上, myapp位于我们自定义api-gateway后面

  1. 获取访问令牌- 通过 postman,我点击了 api-gateway 令牌端点,该端点又调用了 authserver 令牌端点。 我得到 OAuth JWT 令牌作为响应。

所以,总而言之,postman
请求: --(creds)--> api-gateway --(samecreds)--> auth-server
响应: jwt 令牌 <-- (same jwt)-- api-gateway <--(jwt)-- auth-server

  1. 接下来,我点击myapp端点- 再次通过 postman,我点击 api-gateway 端点,而后者又点击相应的myapp端点。 我得到了所需的响应。 对于这个请求,在到达 api-gateway 之前,我设置了 header Authorization: Bearer JWT from step1

作为myapp开发人员,我知道 api-gateway 使用相同的 header 机制(即Authorization: Bearer JWT from step1 )将 JWT 令牌重新发送到myapp 从日志中,我看到这与我在访问api-gateway时在 postman 中提供的值相同

所以,postman 请求:--(jwt)--> api-gateway --(same jwt)--> myapp
并且响应是一些数据,这对于本次讨论来说是微不足道的。

解码后的 JWT Payload 如下:

{
  "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"字段。 所以 auth-server 正在向api-gateway客户端发出令牌。


现在在 mylocal dev env 上,即在 localhost 上运行的myapp - 我正在尝试实现与服务器上类似的流程。

在 localhost 上,myapp 不是在 api-gateway 后面运行,而是直接命中

  1. 获取访问令牌 - 通过 postman,我点击了 api-gateway(与上面的服务器流程相同的服务器实例。即 api-gateway/auth-server 未在 localhost 上运行,但在服务器上运行)令牌端点依次调用 authserver 令牌端点。 我得到 OAuth JWT 令牌作为响应。

所以,postman 请求:--(creds)--> api-gateway --(samecreds) --> auth-server
响应:jwt 令牌 <-- (same 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"字段。 所以 auth-server 正在向api-gateway客户端发出令牌。 我还不确定这个领域是微不足道的还是重要的。

  1. 接下来,我点击myapp localhost 端点- 再次通过 postman,但我直接点击myapp端点(不是通过在 localhost 上运行的 api-gateway)。 对于这个请求,在点击之前,我Authorization: Bearer JWT from step1

但是这次我得到了错误:

paOAuth2AuthenticationProcessingFilter:身份验证请求失败:error="invalid_token", error_description="Cannot convert access token to JSON"

我想知道是什么导致了这个错误。 我不认为client_id: api-gw-client导致了这种情况。 无论如何,我使用client_id: myapp创建了一个签名的 jwt 令牌并在请求中使用它。 但我仍然得到同样的错误。
我在 localhost 上使用的key与 auth-server 用于签名的密钥匹配(对应)。 我仔细检查了一遍。 所以它肯定不是一个key问题。

我需要基于 localhost 的设置工作,所以我可以在本地测试我的 api 而无需部署到服务器(在我的情况下部署到服务器非常耗时)。 所以这个设置对于我在最后期限之前完成非常重要。 非常感谢任何答案/建议。


我的项目中使用的 Spring OAuth2 库如下 -

  1. org.springframework.security:spring-security-oauth2-jose:5.4.2
  2. org.springframework.cloud:spring-cloud-starter-oauth2:2.1.3.RELEASE

并且给出错误的 class 是: OAuth2AuthenticationProcessingFilter.javaAPI Doc

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

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

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

在您的场景中:

  • 如果您被要求实施多因素身份验证,您期望会发生什么事情:除了登录名/密码之外,还需要生物识别、外部应用程序验证、Goolgle 身份验证器令牌或其他任何一项? 除了授权服务器之外,您真的打算在网关中实现所有这些吗?
  • 如果它总是将api-gw-client作为客户端 ID,您的授权服务器如何实现基于客户端的处理(例如检查请求的范围对于客户端是否合法,或者将客户端权限添加到访问令牌)?
  • 多租户场景(网关后面的R1R2资源服务器期望来自不同颁发者的身份,或者C1C2客户端不针对同一授权服务器对用户进行身份验证)呢?
  • 如果某些客户端和资源服务器使用 OAuth2 以外的东西怎么办?

此外,您的客户端必须知道在每个 API 端点(XML、JSON、PDF、multipart 等) Accept和生成的媒体类型并相应地设置Content-type 为什么Authorization header 会有所不同?

在我看来,如果您想节省时间和精力,请使用您的 API 网关仅代理您的资源服务器 离开授权服务器。 对于您不维护但您的客户需要的外部 API(如果有的话)也是如此(Tweeter feed、Google API 等)。

这就是我总是配置我的资源服务器的方式

  • Authorization header 丢失或无效(格式错误、过期、错误的颁发者、不良受众等)=> 401(未经授权)而不是 302(重定向到登录)
    • 在多租户场景中,为什么资源服务器要费心弄清楚要重定向到哪个授权服务器?
    • 对于不在浏览器中运行的客户端(例如移动应用程序),重定向的含义应该是什么?
  • Authorization header 有效,但相关声明未能通过访问控制(例如权限错误或不是预期主题)=> 403(禁止)

客户端应该知道如何获取所需的访问令牌以及如何在发送请求时设置Authorization header(这是您目前使用 Postman 所做的)。 它甚至可以拦截 401 触发用户认证,然后重试失败的资源访问。 严重的 OAuth2 客户端库(如 Angular的 angular-auth-oidc-client )提供了此类功能。

使用这样的客户端,网关可以充当您的资源服务器(以及授权服务器或外部 API,如果您愿意,但为什么呢?),转发Authorization header 并完全忽略用户登录。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM