我有三项服务:
这三个都是Spring Boot应用程序。使用JDBC令牌存储通过OAuth2令牌配置完成身份验证。登录,获取令牌效果很好,从其他两个资源服务器中的任何一个请求数据也很有效。但是我对我的表现并不满意,因为它看起来有点笨拙:
资源服务器上的所有数据都通过服务器端生成的用户ID链接到用户。如果用户想要更改他/她的用户名,我认为将其链接到用户名是一个坏主意。现在,我获取用户ID的方式很简单:
LocalDateTime
方法@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 ...
}
将Auth服务器上的整个User对象作为地图返回 - 因为这是我在 application.properties 文件中链接它的方式:
getDetails
但我不能让自己对这个解决方案感到满意,因为:
security.oauth2.resource.userInfoUri=http://localhost:9000/api-auth/user
作为输入 - 它应该在上面的一层而不是在这里(虽然可能是我错误的感觉)。我的问题是 - 我可以更有效地完成吗?以更清洁和可持续的方式?
我想:
OAuth2Authentication authentication
肯定不依赖于发送此数据的客户端 - 这必须来自Auth服务器。
我(迄今为止失败)的想法:
@RequestMapping(method = RequestMethod.GET)
public ResponseEntity<SampleData> getData(String userId) {
// interact with data with the userId
}
并解析数据。但后来我无法将解析后的对象直接分发到控制器中。这似乎是解决方案,但我想这可能不适合这个。我接近这个完全错误了还是我错过了一些自动解决这个问题的Spring Boot细节?
答案 0 :(得分:1)
我会将选项2与OncePerRequestFilter
一起使用。您可以解析一次,如果创建新线程,则将结果存储在ThreadLocal
或InheritableThreadLocal
中。
然后可以从控制器访问线程本地数据,甚至可以从服务层更深入地访问。
每个线程都拥有对其线程局部变量副本的隐式引用,只要该线程处于活动状态并且可以访问ThreadLocal实例;一个线程消失后,它的所有线程局部实例副本都会被垃圾收集(除非存在对这些副本的其他引用)。