JWT授权用于离线后端和在线身份服务器。

huangapple go评论60阅读模式
英文:

JWT authorization for offline backend and online identity server

问题

以下是翻译好的部分:

我正在处理一个项目,其中要求如下:

  1. 身份验证服务器在线
  2. 具有需要授权的控制器操作的C# Web API后端位于离线机器上
  3. 客户端(浏览器)位于具有互联网访问权限且与后端位于同一网络的机器上

工作流程大致如下:

  1. 客户端发送请求到身份验证服务器,提供凭据以获取JWT令牌
  2. JWT令牌被添加为请求的标头,该请求发送到后端以进行授权

如果我允许后端机器具有互联网访问权限,这个方法效果很好。但是当我不允许后端机器访问互联网时,授权就会失败。我认为这是因为后端需要与身份验证服务器通信以获取签名的公钥。公钥是从身份验证服务器获取的,位于http://identityserver/.well-known/openid-configuration/jwks

我知道我可以创建一个证书,并将该证书与身份验证服务器和后端一起使用,但我不想这样做,因为一旦部署后端,我就无法控制证书 - 如果我更改身份验证服务器证书,将破坏我的设置(而且传递证书听起来也不太好)。

我的想法和思路是:

http://identityserver/.well-known/openid-configuration/jwks是对公众开放的,这正是后端所需要的密钥。客户端机器具有互联网访问权限。有没有任何理由我不应该使用客户端从身份验证服务器端点获取公钥,并将其放入我的需要授权的后端请求的标头中(后端是离线但位于同一网络上)?然后,在后端,我使用了一些我编写的中间件,其中我解析标头以获取公共签名密钥,并在那里动态设置了JwtBearerOptions.TokenValidationParameters.IssuerSigningKey(实际上我使用IssuerSigningKeyResolver来执行此操作)。尽管有很多文章/问题涉及到离线授权,但我没有看到有人使用这种方法。

英文:

I am working on a project where the requirement is that:

  1. The identity server is online
  2. The c# web api backend that has controller actions that require authorization is on a machine that is offline
  3. The client (browser) is on a machine that has internet access and is on the same network as the backend

The workflow is something like:

  1. Client makes a request to identity server, providing credentials, to obtain a jwt token
  2. The jwt token is added as a header to the request that is made to the back end so that it can be authorized

This works well, if I allow the backend machine to have internet access. When I don't allow internet access on the backend machine, the authorization fails. This I believe is because the backend needs to communicate with the identity server to obtain the public key for signing. The public key is obtained from the identity server, at http://identityserver/.well-known/openid-configuration/jwks

I know that I could create a certificate and use that certificate with both the identity server and the back end, but I don't want to do that because once the backend is deployed I have no control over the certificate - if I change the identity server certificate it will break my set up (and also shipping out certificates doesn't sound good).

My idea and thinking:

The http://identityserver/.well-known/openid-configuration/jwks is open to the public and that's the key that the backend needs. The client machine has internet access. Is there any reason why I shouldn't use the client to grab the public key from the identity server end point and put it in a header for my request to the backend that requires authorization (and is offline but on the network)? Then, in the backend, I dynamically set the JwtBearerOptions.TokenValidationParameters.IssuerSigningKey (I am actually using the IssuerSigningKeyResolver to do this) using some middleware I wrote where I parse the header to grab the public signing key. I don't see this approach used anywhere even though there are a number of articles / questions asking about offline authorization.

答案1

得分: 2

以下是翻译好的部分:

有趣的是要知道为什么API服务器离线。有时,IT管理员会执行此类操作,而不了解安全性和复杂性的影响。

更好的选择是使API服务器在线,但默认情况下阻止所有外部路由,例如通过某种防火墙。然后仅将授权服务器URL列入白名单。然后安全性按标准方式运作。

通常,API到授权服务器的JWKS端点的URL表示API信任的对象。不要允许可能恶意的客户端覆盖信任。例如,攻击者可以轻松地生成一对密钥并发送恶意JWT和公共JWK。

另一个可能的(但更复杂的)选择是使用self-contained JWTs,如果您的授权服务器支持的话。这涉及从授权服务器部署一个长期有效的根证书颁发机构(例如10年)到您的API。然后,接收的访问令牌的JWT标头包含一个x5c字段,其中包含令牌签名的公钥作为X509证书。在每个请求中,API必须检查此证书是否具有预期的名称,并链接到其部署的根证书颁发机构,然后才能使用接收到的公钥验证令牌。这样可靠地处理了授权服务器上的令牌签名密钥更新。

英文:

It is interesting to know why the API server is offline. Sometimes IT administrators do this type of thing, without realising the security and complexity impact.

A better option is for the API server to be online but all external routes blocked by default, eg by some kind of firewall. Then whitelist only the authorization server URL. Security then works in a standard way.

Generally the URL from the API to the JWKS endpoint of the authorization server represents who the API trusts. Do not allow a possibly malicious client to override trust. Eg it would be easy for an attacker to spin up a keypair and send a malicious JWT and public JWK.

Another possible (but more complex) option is to use self-contained JWTs, if your authorization server supports it. This involves deploying a long lived root certificate authority (eg 10 years) from the authorization server with your API.

The JWT header of received access tokens then includes an x5c field including the token signing public key as an X509 certificate. On each request, the API must check that this has the expected name and chains up to its deployed CA before using the received public key to vaidate tokens. This copes reliably with token signing key renewal at the authorization server.

huangapple
  • 本文由 发表于 2023年6月29日 17:20:57
  • 转载请务必保留本文链接:https://go.coder-hub.com/76579742.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定