简体   繁体   English

OAuth 用于带有 API 网关的微服务 - 架构

[英]OAuth for Microservices with API Gateway - architecture

In a microservice architecture, an API gateway lays in front of the API. The purpose of this is eg changing some request / response parameters, for single entry point or checking authentication etc. Now I would like to protect my API using OAuth2 flows to obtain an access token.在微服务架构中,API 网关位于 API 之前。这样做的目的是更改一些请求/响应参数,用于单个入口点或检查身份验证等。现在我想使用 OAuth2 流程保护我的 API 以获取访问令牌。 The problem is to decide who is the actual OAuth client, I will demonstrate it by using a SPA example:问题是决定谁是实际的 OAuth 客户端,我将使用 SPA 示例来演示它:


a) Is it the SPA that started the oauthorize request (to the api gateway) by using the implicit grant. a) 是否是 SPA 通过使用隐式授权启动了 oauthorize 请求(到 api 网关)。 Then, the Api gateway would simply route the request through to the OAuth authorization server, acting as a single entry point, with the /authorize stuff from the implicit flow然后,Api 网关会简单地将请求路由到 OAuth 授权服务器,充当单个入口点,使用隐式流中的 /authorize 内容

b) Is it the API Gateway itself, meaning the SPA sends the username and password of the enduser to the api gateway (of course, here the SPA needs to be trusted with the end users credentials), which then acts on its own as an oauth client using the resource owner password grant b) 是API Gateway本身吗,意思是SPA把终端用户的用户名和密码发给api网关(当然这里SPA需要用终端用户凭证来信任),然后SPA自己作为一个oauth 客户端使用资源所有者密码授予

c) dismiss the api gateway at all and create the oauth authorization server "parallel" to the api gateway, meaning you would loose the single entry point etc. c) 完全关闭 api 网关并创建与 api 网关“并行”的 oauth 授权服务器,这意味着您将失去单一入口点等。


The following picture demonstrate a very abstract architecture, and the question is about the numer "[2]", if this request is initiated by the SPA and passed through by the api gateway, or if the api gateway is intercepting the request and acting on its own as an oauth client?下图展示了一个很抽象的架构,问题是关于数字“[2]”,如果这个请求是由SPA发起并由api网关通过,或者api网关正在拦截请求并作用于它自己作为 oauth 客户端?

OAuth with API Gateway OAuth 与 API 网关

My guess is to always use the best fitting grant type for a specific client, regardless of an API gateway being in between or not.我的猜测是始终为特定客户端使用最合适的授权类型,无论 API 网关是否介于两者之间。 This would mean, that when it comes to OAuth, the API Gateway would simply pass the client authorization request through, whatever grant type it used.这意味着,当涉及到 OAuth 时,API 网关将简单地传递客户端授权请求,无论它使用什么授权类型。 Therefore, [2] in the picture would come from the client, and not from the API Gateway acting as the OAuth client.因此,图片中的 [2] 将来自客户端,而不是来自充当 OAuth 客户端的 API 网关。 Is this correct?这样对吗? As mentioned, this really gets tricky when it comes to first party apps as you probably could use the password credentials grant, which has huge drawbacks,eg no refreshing possible for SPAs.如前所述,对于第一方应用程序,这真的很棘手,因为您可能会使用密码凭据授予,但它有很大的缺点,例如,SPA 无法刷新。

Please bear in mind that this is a purely opinion based answer, because your question is pretty vague. 请记住,这是纯粹基于观点的答案,因为您的问题非常模糊。

I don't like the idea about using the API Gateway as the point which authenticates requests. 我不喜欢使用API​​网关作为对请求进行身份验证的观点。 I think that this defeats the Single Responsibility Principle. 我认为这违反了单一责任原则。 The gateways purpose usually is to expose your backend to external clients, perhaps change the contract for some specific clients, etc. But it shouldn't also authenticate calls. 网关的目的通常是将您的后端暴露给外部客户端,也许更改某些特定客户端的合同等。但是,它也不应该对呼叫进行身份验证。 Besides it would have to do so based on the data passed to it, which you would have to gather somewhere else anyway. 除此之外,它还必须基于传递给它的数据来执行此操作,无论如何,您都必须将其收集在其他位置。

Another thing which is I think undesirable, is that you're considering using the resource owner password grant for your SPA. 我认为不希望发生的另一件事是,您正在考虑为SPA使用资源所有者密码授予。 This is not the correct use case for this grant flow. 这不是此授予流程的正确用例。 You could look into this article, which explains it much better than I could: https://www.scottbrady91.com/OAuth/Why-the-Resource-Owner-Password-Credentials-Grant-Type-is-not-Authentication-nor-Suitable-for-Modern-Applications 您可以查看这篇文章,它比我能更好地解释它: https : //www.scottbrady91.com/OAuth/Why-the-Resource-Owner-Password-Credentials-Grant-Type-is-not-Authentication-也不适合现代应用

I would suggest you use the Implicit grant type and use the api gateway to only route calls to the backend, don't authenticate the calls on that layer. 我建议您使用Implicit授予类型,并使用api网关仅将调用路由到后端,而不对该层上的调用进行身份验证。

If you're using a spring cloud api gateway (essentially a zuul proxy), you will have to add proper configuration so that it forwards all security headers and redirects. 如果您使用的是Spring Cloud API网关(本质上是zuul代理),则必须添加适当的配置,以便它转发所有安全标头并重定向。 This example works for me: 这个例子对我有用:

server:
    use-forward-headers: true

zuul:
    addHostHeader: true
    routes:
        <your oauth server route>:
            url: <your oauth server url>
            path: <if youve got any prefix>
            sensitiveHeaders:
            stripPrefix: false

It doesn't matter, what Krzysztof Chris Mejka in previous answer like or dislike.没关系,Krzysztof Chris Mejka 在之前的回答中喜欢或不喜欢什么。 Take a look at BCP - https://datatracker.ietf.org/doc/html/draft-ietf-oauth-browser-based-apps#section-6看看 BCP - https://datatracker.ietf.org/doc/html/draft-ietf-oauth-browser-based-apps#section-6

Latest recommendation from oauth working group at IETF is to use a kind of Api gateway/reverse proxy, another words - you need to keep tokens out of js entirely. IETF oauth 工作组的最新建议是使用一种 Api 网关/反向代理,换句话说 - 你需要将令牌完全排除在 js 之外。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM