【问题标题】:How to communicate user ID between Spring Boot microservice applications如何在 Spring Boot 微服务应用程序之间传递用户 ID
【发布时间】:2017-08-29 18:00:55
【问题描述】:

我有三个服务:

  1. Auth(OAuth2 令牌提供和用户名 + 密码,仅此而已)
  2. 与用户相关的资源(链接设备、出生日期等)
  3. 域数据

这三个都是 Spring Boot 应用程序。身份验证是通过 OAuth2 令牌供应完成的,使用 JDBC 令牌存储。登录,获取令牌运行良好,从其他两个资源服务器中的任何一个请求数据也运行良好。但是我对我的做法并不满意,因为它看起来有点笨拙:

资源服务器上的所有数据都通过服务器端生成的用户 ID 链接到用户。如果用户想要更改他/她的用户名,我认为将其链接到用户名是一个坏主意。现在,我获取用户 ID 的方式很简单:

@RequestMapping(method = RequestMethod.GET)
public ResponseEntity<SampleData> getData(OAuth2Authentication authentication) {
    Authentication auth = authentication.getUserAuthentication();
    final Map<String, Object> map = (Map) auth.getDetails();

    // parse user data from the map ...
}

getDetails 方法将 Auth 服务器上的整个 User 对象作为映射返回 - 因为这是我在 application.properties 文件中链接它的方式:

security.oauth2.resource.userInfoUri=http://localhost:9000/api-auth/user

但我无法接受这个解决方案,因为:

  1. 所有面向用户的方法都必须从这个解析开始,即使在我将它变成一个单独的类之后,每个方法仍然是相同的两行。
  2. 我觉得这些方法甚至不应该将对象 OAuth2Authentication authentication 作为输入 - 它应该在上面的一层而不是这里(不过可能是我的错误感觉)。

我的问题是 - 我可以更有效地做到这一点吗?以更清洁和可持续的方式?

我想要:

@RequestMapping(method = RequestMethod.GET)
public ResponseEntity<SampleData> getData(String userId) {
    // interact with data with the userId
}

而且绝对依赖于发送此数据的客户端 - 这必须来自 Auth 服务器。

我(迄今为止失败)的想法:

  1. JWT 令牌使用 - 因为我正在使用 JDBC 令牌存储并且这似乎与 JWT 不兼容而失败。 JWT 令牌也不能被撤销,因为它们没有被存储并且必须通过短期访问/刷新令牌来处理。但如果没有其他办法,我对这种方法持开放态度。
  2. 过滤器 - 我最喜欢的,我以为就是这样,但我无法让它工作 - 我收到请求,例如OncePerRequestFilter 并解析数据。但是后来我无法将解析的对象直接分发到控制器中。这似乎是解决方案,但我想这可能不是为了这个。

我是完全错误地接近这个问题,还是我错过了一些自动解决这个问题的 Spring Boot 细节?

【问题讨论】:

    标签: java spring authentication oauth-2.0 microservices


    【解决方案1】:

    我会将选项 2 与 OncePerRequestFilter 一起使用。如果您创建新线程,您可以对其进行一次解析并将结果存储在ThreadLocalInheritableThreadLocal 中。

    然后可以从您的控制器甚至更深的服务层访问线程本地数据。

    ThreadLocal:

    只要线程处于活动状态且 ThreadLocal 实例可访问,每个线程都持有对其线程局部变量副本的隐式引用;线程离开后,它的所有线程本地实例副本都将受到垃圾回收(除非存在对这些副本的其他引用)。

    【讨论】:

    • 喜欢这里的最后一个答案吗? stackoverflow.com/questions/35444633/… 这看起来很方便!唯一的问题是 - 手术后如何清理?我必须这样做还是 ThreadLocal 在请求后自动销毁?所以它不会干扰其他请求...
    • 这个问题来自 Marek Raszewski 的回答。无需清洁
    猜你喜欢
    • 2019-02-12
    • 2018-05-05
    • 2019-08-12
    • 1970-01-01
    • 2018-11-03
    • 2019-07-09
    • 1970-01-01
    • 2019-03-17
    • 2019-10-15
    相关资源
    最近更新 更多