如何在多个微服务中管理安全上下文

Posted

技术标签:

【中文标题】如何在多个微服务中管理安全上下文【英文标题】:How to manage security context within multiple microservices 【发布时间】:2019-11-22 11:40:33 【问题描述】:

我正在开发一个依赖多个微服务来提供分析的系统。我有一个使用 OAuth2(资源所有者密码凭证)管理授权的微服务。我的目标是审核谁在嵌入列中创建/更新了某个实体,如下所示:

@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Embeddable
public class AuditEmbeddable implements Serializable 

    @CreatedBy
    @Builder.Default
    @Column(name = "created_by", nullable = false, length = 64, updatable = false)
    private String createdBy = "system";

    @CreatedDate
    @Builder.Default
    @Column(name = "created_at", nullable = false)
    private Instant createdAt = Instant.now();

    @LastModifiedBy
    @Column(name = "modified_by", length = 64)
    private String modifiedBy;

    @LastModifiedDate
    @Column(name = "modified_at")
    private Instant modifiedAt;

我确信令牌总是随请求一起发送,因为我们使用了一个对每个请求进行身份验证的大使网关。现在我正在使用非常古怪和错误(在我看来)的方法。我使用@RequestHeader("Authentication") 获取附加到请求的令牌,将请求发送到身份验证服务器以获取用户电子邮件(和角色)并作为参数传递给服务,该服务依次设置created_byupdated_by 列。有没有办法拦截并拥有某种上下文,我可以自动从中提取用户信息(使用 spring 为我调用身份验证服务)?

【问题讨论】:

您是否使用 JWT 作为身份验证令牌? 不,它的基本oauth。我想没关系。我只想从不对用户进行身份验证的微服务中获取用户信息。现在我正在使用 RestTemplate 。有没有更简单的方法? 我询问 JWT 的原因是因为它是一种标准格式,通常包含身份和声明。无论此令牌传递到何处,受信任的服务都可以验证和提取,而无需调用授权服务器。这解决了微服务中身份传播的主要问题。如今,使用 OAuth2 的主要令牌类型是 JWT。 你是对的,在这种情况下,我必须在每个微服务上存储解密机制,但在我看来,这是不好的做法。但这绝对是一个可能的解决方案,感谢您的帮助! 你帮了我很多,我会做进一步的阅读。如果你能回答我会很好,这样我就可以给你赏金,减少戳天空的次数。 【参考方案1】:

您的主要问题似乎是身份和声明跨微服务的传播,当然还有如何以最佳方式设计它。现在您似乎正在使用 OAuth2/OpenID。如果您使用 JWT 作为令牌,那么它是一个标准的自包含令牌,其中包含用户身份和声明。Spring 安全性中有标准类(ResourceServerConfigurerAdapter、TokenStore 等)可以在每个微服务中配置这些 JWT 令牌可以是通过所有微服务的通用逻辑提取。如果您的令牌不是 JWT,那么您将需要编写自定义逻辑来提取用户信息并进一步传递它。可以看到一些很好的设计参考 here 和 here。

【讨论】:

以上是关于如何在多个微服务中管理安全上下文的主要内容,如果未能解决你的问题,请参考以下文章

Symfony - 在控制台命令中模拟登录和安全上下文

第十单元文档2

什么是微服务上下文中的边车?

如何在安全上下文中使用不安全代码?

AngularJS:如何解决“尝试在安全上下文中使用不安全值”?

如何在 Spring MVC 中模拟安全上下文以进行测试