对于上下文,我使用的是Okta SSO平台。
对于机器对机器的认证,我使用的是客户端凭证流。在收到并验证了一个访问令牌后,我需要知道我应该如何对请求进行授权。
似乎我可以选择根据访问控制列表检查客户端ID(在 "子 "声明中)。
否则,这些选项似乎更复杂,而且可能不安全,例如验证添加到访问令牌中的自定义作用域的存在。
根据我可以从访问令牌中获得的数据来授权请求的正确方法是什么?
必须是 当您绝对相信目标客户对您的受保护资源或服务是100%可信的实体时,就可以采用。因为您的授权服务器将直接发出一个由您的授权服务器发出的授权。access token
的注册客户,即使没有 authorization code
提供。这就是美丽的 client credential flow
.
最好的方法是,正如你所提到的,在为客户发出访问令牌之前,检查客户的id。Sub
在真正的客户端凭证流中,值将是空的,因为没有终端用户参与其中。只是在注册客户端和授权服务器之间。
下面是在 RFC 6749. 我想你已经知道这些东西了,但只是想确认一下你认为的方法到底对不对。
+---------+ +---------------+ | | | | | |>--(A)- Client Authentication --->| Authorization | | Client | | Server | | |<--(B)---- Access Token ---------<| | | | | | +---------+ +---------------+ Figure 6: Client Credentials Flow
如果你能绝对信任你的客户,那就没什么好鉴定的了。否则选择 client credential flow
可能是一个错误的选择,可能会导致危害你的保护资源。
OAuth客户端id是一个值,如 0ajiowefr789 并只做了一件事,那就是确定呼叫者在 技术术语. 在接收端,你需要将这个对象映射到它在 商业条款.
下面举几个例子。
0ajiowefr789代表了一个调用的应用程序, 你需要在你的应用程序的数据中查找该外部应用程序的权限.
0ajiowefr789代表的是一个呼叫的外部公司,你需要在你的app的数据中查询该公司的权利。
不管是哪种情况,我都会将特权表示为一个Claims Principal对象--它可以包含诸如角色、对特定资源的读写访问权,或者其他任何你喜欢的东西。
class ApiClaims {
clientId: string;
callerName: string;
callerType: string;
readOnly: boolean;
role: string;
}
然后,每个API操作都可以使用上述数据来强制访问资源,如果调用者尝试一些他们无权访问的资源,则返回403 forbidden。当然,你的API只允许调用者拥有有限的权限是有意义的--只需足够做他们需要的事情。