我正在努力学习使用net core的微服务方法
-
我创建了两个api项目:Company和Package。端口5002和5010
-
我需要一个入口,奥切洛就是那个。我有这样的配置:
{
"Routes": [
// Company Api
{
"DownstreamPathTemplate": "/api/company/{everything}",
"DownstreamScheme": "http",
"DownstreamHostAndPorts": [
{
"Host": "localhost",
"Port": 5002
}
],
"UpstreamPathTemplate": "/api/company/{everything}",
"UpstreamHttpMethod": [
"GET"
],
"AuthenticationOptions": {
"AuthenticationProviderKey": "TestKey",
"AllowedScopes": []
},
"AddHeadersToRequest": {
"CustomerId": "Claims[sub] > value"
}
},
// Anonymous Company Api
{
"DownstreamPathTemplate": "/api/company/getHomeSections",
"DownstreamScheme": "http",
"DownstreamHostAndPorts": [
{
"Host": "localhost",
"Port": 5002
}
],
"UpstreamPathTemplate": "/api/anonymous/company/getHomeSections",
"UpstreamHttpMethod": [
"GET"
]
},
// Package Api
{
"DownstreamPathTemplate": "/api/package/{everything}",
"DownstreamScheme": "http",
"DownstreamHostAndPorts": [
{
"Host": "localhost",
"Port": 5010
}
],
"UpstreamPathTemplate": "/api/package/{everything}",
"UpstreamHttpMethod": [
"GET"
],
"AuthenticationOptions": {
"AuthenticationProviderKey": "TestKey",
"AllowedScopes": []
}
}
],
"GlobalConfiguration": {
"BaseUrl": "http://localhost:5000"
},
"AllowedHosts": "*"
}
- 我有一个配置了标识和mongoDB的identityServer4。工作起来很有魅力
我已经在angular 10中配置了一个客户端。我可以登录,我得到令牌,一切都按预期进行。
现在我的大问题是,如何在API/角色的基础上授予用户访问权限?假设角色A可以访问公司/读取,角色B可以访问公司或读取和公司/写入?
如何真正做到这一点?
非常感谢。
如何在API/角色的基础上授予用户访问权限?
有两种方法:
在客户端
这个方法根本不涉及网关,只涉及IdentityServer。
如果你只想在用户体验中基于角色的行为——允许/禁止某些调用或隐藏/显示某些屏幕/组件,你可以做以下操作:
- 将您的角色建模为Identity Server中的用户声明
- 让用户体验询问JWT在登录时返回的持有者,并打开索赔集合
- 基于发现的角色应用基于角色的用户体验逻辑
在网关/后端
这更为复杂,但如果您希望在后端具有基于角色的行为,则需要在服务中为此进行编码。例如,实现这一点的一种方法是让每个服务接受一组角色作为头参数。然后你可以:
- 将您的角色建模为Identity Server中的用户声明
- 在Ocelot中,公开不带任何角色头参数的上游服务路径
- 当UX发出请求时;角色";声明为下游http标头(与当前处理customerId的方式相同(
- 然后,您可以让每个服务根据角色决定是否允许请求
然而,这感觉很笨拙。考虑到服务级别的访问控制,角色感觉有点过于粗糙。
也许还有第三种方式
所以,基于角色的行为在前端很有效,但后端呢?
由于您已经在利用将CustomerId用户声明注入下游服务的能力,我们应该考虑另一种解决方案。
与其在后端使用基于角色的行为,为什么不使用资源标识符来控制访问呢?例如,可以使用customerId作为路径的一部分来定义与客户有关的私有http操作:
GET /customers/{customerId}
在Ocelot中,上游路径可以暴露为
GET /customers
当在网关上接收到请求时,customerId声明被注入到下游路径中(注意:Ocelot不支持开箱即用的路径参数注入。您需要创建一个从DelegatingHandler派生的类,并将其与Ocelot.json中的DelegatingHandlers[]
集合一起使用(。
类似地,您可以通过创建从GET /company
到GET /company/{companyId}
的Ocelot路由来保护您的公司API,其中companyId是用户声明。
与前端基于角色的行为相结合,这种方法在网关/后端上为您提供了比基于角色行为更细粒度的访问控制。你两全其美。