[英]Client Credentials Flow or Authorization Code Flow (with PCKE) for a trusted desktop client
I'm developing the authentication/authorization architecture for several APIs.我正在为多个 API 开发身份验证/授权架构。
I'm using IdentityServer4 as a Security Token Service (STS).我使用 IdentityServer4 作为安全令牌服务 (STS)。
From what I've read from "Dominick Baier" (one of the persons that built IdentitySever4), there are only two types of Flows that should be used :根据我从“Dominick Baier”(构建 IdentitySever4 的人之一)中读到的内容,只有两种类型的流应该使用:
I have several C# Web API's that will communicate with each (Machine-To-Machine), and I will use the Client Credentials Flow.我有几个 C# Web API 将与每个(机器对机器)通信,我将使用客户端凭据流。
But then there are some WPF Desktop Applications, that will need to access some APIs, and don't have a user.但是还有一些 WPF 桌面应用程序需要访问一些 API,并且没有用户。 Which flow should be used?
应该使用哪个流?
I've read that: Desktop/Native & Mobile Applications should use Authorization with Authorization Code Flow (with Public Client and PKCE), since they are hosted on the Client side, and the Client/Secret is can be leaked (maybe on a Desktop application we can Encrypt the Secret? But then will need to manage a way how to store the secret that decrypts that right?)我已经读过:桌面/本机和移动应用程序应该使用授权代码流(使用公共客户端和 PKCE),因为它们托管在客户端,并且客户端/秘密可能被泄露(可能在桌面上应用程序我们可以加密秘密吗?但是需要管理一种方法来存储解密的秘密吗?)
Then I've read: "Anytime you have a system that isn't concerned with the end-user identity (and just needs to authenticate the system), use the OAuth2 Client Credential Grant."然后我读到:“只要您有一个不关心最终用户身份的系统(并且只需要对系统进行身份验证),请使用 OAuth2 客户端凭据授予。”
For now, this is my case, I'm not concerned with the end-user identity (but maybe in a near future I will).目前,这是我的情况,我不关心最终用户的身份(但也许在不久的将来我会关心)。
So since the above points conflict with each other: - Which flow should I use?因此,由于上述几点相互冲突: - 我应该使用哪个流程? - Can I have a Desktop Client using Clients Credential Flow and be safe?
- 我可以拥有使用客户端凭据流的桌面客户端并且安全吗?
Also, I've read a bit about Mutual TLS, If I use that, does this change which flow should I use?另外,我读过一些关于 Mutual TLS 的文章,如果我使用它,这会改变我应该使用哪个流程吗?
You can't trust a client because you can't be sure a request originates from the client.您不能信任客户端,因为您无法确定请求来自客户端。 And another problem is that clients are not good in keeping secrets.
还有一个问题是客户不善于保守秘密。 But there are different types of clients.
但是有不同类型的客户。
Clients that run on servers often having a single task, like synchronizing data which is user independent, are suitable to use the client credentials flow.在服务器上运行的客户端通常具有单个任务,例如同步与用户无关的数据,适合使用客户端凭据流。 To some degree they can keep a secret (running on a server).
在某种程度上,他们可以保守秘密(在服务器上运行)。
You can use unique credentials for each instance but that doesn't make it safer.您可以为每个实例使用唯一凭据,但这并不能使其更安全。 It helps you to identify the client, but doesn't add security.
它可以帮助您识别客户端,但不会增加安全性。 Security is about monitoring behaviour and detecting anomalies.
安全是关于监控行为和检测异常。 Or perhaps narrowing access by filtering on ip address.
或者可能通过过滤 ip 地址来缩小访问范围。
But you are not limited to use the two flows you've mentioned.但是您不限于使用您提到的两个流程。 Being a token provider, you can extend IdentityServer with custom flows using extension grants .
作为令牌提供者,您可以使用扩展授权扩展 IdentityServer 和自定义流。
Without user the client credentials are somewhat similar to the resource owner password credentials (ROPC) flow (another option that is no longer covered in the grant type documentation but still exists, see the old docs ).如果没有用户,客户端凭据有点类似于资源所有者密码凭据 (ROPC) 流程(授权类型文档中不再涵盖但仍然存在的另一个选项,请参阅旧文档)。 Neither are really safe in the sense that both can be automated.
从两者都可以自动化的意义上说,两者都不是真正安全的。 The user factor can be eliminated since user interaction isn't required for these flows.
由于这些流程不需要用户交互,因此可以消除用户因素。
But I wonder why your app has no user, running on a user machine.但我想知道为什么您的应用程序没有用户,在用户机器上运行。 Because ideally you have a client (without secret) where the user logs in and let the client contact the api ( delegation ).
因为理想情况下,您有一个客户端(没有秘密),用户登录并让客户端联系 api( 委托)。
So there are two things: do you need to identify the client?所以有两件事:你需要识别客户吗? If not you could suffice with an ApiKey, like eg Sendgrid.
如果没有,您可以使用 ApiKey,例如 Sendgrid。 And you can never trust a client.
你永远不能相信客户。 Security has to be server side.
安全必须是服务器端。
So basically it doesn't really matter, there is nothing you can do to make it much safer client side.所以基本上这并不重要,你无法做任何事情来让它更安全的客户端。 The only thing you can do is add the requirement of user interaction.
您唯一可以做的就是添加用户交互的要求。 So perhaps now you don't need it, but it will increase security and allows you to delegate api access to the client.
所以也许现在您不需要它,但它会增加安全性并允许您将 api 访问权限委托给客户端。
To add to Ruard's very good answer and point you to some links:要添加到 Ruard 的非常好的答案并指向一些链接:
For your WPF desktop applications the standard technique is to open the system browser for logins and then receive the response in your app.对于您的 WPF 桌面应用程序,标准技术是打开系统浏览器进行登录,然后在您的应用程序中接收响应。 This is a little tricky but the below IdentityModel code samples show how:
这有点棘手,但下面的 IdentityModel 代码示例显示了如何:
RESOURCES OF MINE我的资源
The user experience is a little tricky though, so to understand the behaviour you may want to have a look at my visual blog posts.不过,用户体验有点棘手,所以要了解这种行为,您可能需要查看我的可视化博客文章。
The blog posts are accompanied by a couple of code samples you can easily run from your local PC.博客文章附有几个代码示例,您可以在本地 PC 上轻松运行。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.