java - 如何在 Spring Boot 微服务应用程序之间传递用户 ID

标签 java spring authentication oauth-2.0 microservices

我有三个服务:

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

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

资源服务器上的所有数据都通过服务器端生成的用户 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 服务器上的整个用户对象作为 map 返回 - 因为这是我在 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 token 使用 - 失败,因为我使用的是 JDBC token 存储,而且它似乎与 JWT 不兼容。此外,JWT token 不能被撤销,因为它们没有被存储并且必须通过短期访问/刷新 token 来处理。但如果没有别的办法,我愿意接受这种方法。
  2. 过滤器 - 我最喜欢的,我以为就是这样,但我无法让它工作 - 我收到了请求,例如OncePerRequestFilter 并解析数据。但是后来我无法将解析后的对象直接分发到 Controller 中。这似乎是解决方案,但我想这可能不是为了这个。

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

最佳答案

我会使用选项 2 和 OncePerRequestFilter。您可以解析一次并将结果存储在 ThreadLocalInheritableThreadLocal 中(如果您创建新线程)。

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

ThreadLocal :

Each thread holds an implicit reference to its copy of a thread-local variable as long as the thread is alive and the ThreadLocal instance is accessible; after a thread goes away, all of its copies of thread-local instances are subject to garbage collection (unless other references to these copies exist).

关于java - 如何在 Spring Boot 微服务应用程序之间传递用户 ID,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43208872/

相关文章:

java - 当比较 Java 和 C++ 的速度时,我应该使用 -O3 还是 -O2 编译 C++ 代码?

java - 使用 javaFX 对齐文本时遇到问题

java - Single Sign on Java and NodeJs (Share single session object between Java and Nodejs)

java - 我可以在 application.yml 中为实体写入表名吗?

java - 如何将 ASCII 转换为字符串

asp.net - 如果加载的页面具有 ASP.NET 身份验证 cookie,如何从 JavaScript 检查?

php - Symfony 自定义身份验证提供程序在请求重叠时注销

CakePHP 2 独立的登录表

java - 如何从java中的静态初始化 block 返回

Java如何有效地从列表中删除元素