[英]Protecting the service using OAuth2, JWT token not working Spring cloud
[英]Spring OAuth2 - JWT token working on server but not on localhost?
我看到myapp
能够在服务器上正确处理 OAuth2 JWT 令牌,但它在本地主机上给出令牌转换错误。
我的流程如下 -
在 Server上, myapp
位于我们自定义api-gateway
后面
所以,总而言之,postman
请求: --(creds)--> api-gateway --(samecreds)--> auth-server
响应: jwt 令牌 <-- (same jwt)-- api-gateway <--(jwt)-- auth-server
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 后面运行,而是直接命中
所以,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
客户端发出令牌。 我还不确定这个领域是微不足道的还是重要的。
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 库如下 -
org.springframework.security:spring-security-oauth2-jose:5.4.2
org.springframework.cloud:spring-cloud-starter-oauth2:2.1.3.RELEASE
并且给出错误的 class 是: OAuth2AuthenticationProcessingFilter.java ( API Doc )
抱歉,我不会回答您的问题(@Toerktumlare 是对的,您的安全配置丢失),而是会尝试解释为什么我不会将 API 网关设为 OAuth2 客户端。
简单地说,API 网关的作用是作为系统资源的黑匣子,这可以使其被视为资源服务器,但在我看来,它应该对 OAuth2(和其他身份验证机制)保持透明。 保持简单:
在您的场景中:
api-gw-client
作为客户端 ID,您的授权服务器如何实现基于客户端的处理(例如检查请求的范围对于客户端是否合法,或者将客户端权限添加到访问令牌)?R1
和R2
资源服务器期望来自不同颁发者的身份,或者C1
和C2
客户端不针对同一授权服务器对用户进行身份验证)呢? 此外,您的客户端必须知道在每个 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.